blob: 09f20bd0496b5577d5838ff0ef013d02d030acd0 [file] [log] [blame]
Janis Danisevskis1af91262020-08-10 14:58:08 -07001// Copyright 2020, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![allow(unused_variables)]
16
17//! This crate implements the IKeystoreSecurityLevel interface.
18
19use android_hardware_keymint::aidl::android::hardware::keymint::{
Janis Danisevskis85d47932020-10-23 16:12:59 -070020 Algorithm::Algorithm, ByteArray::ByteArray, Certificate::Certificate as KmCertificate,
Janis Danisevskis1af91262020-08-10 14:58:08 -070021 IKeyMintDevice::IKeyMintDevice, KeyCharacteristics::KeyCharacteristics, KeyFormat::KeyFormat,
22 KeyParameter::KeyParameter as KmParam, KeyPurpose::KeyPurpose, Tag::Tag,
23};
24use android_system_keystore2::aidl::android::system::keystore2::{
25 AuthenticatorSpec::AuthenticatorSpec, AuthenticatorType::AuthenticatorType,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070026 CreateOperationResponse::CreateOperationResponse, Domain::Domain,
Janis Danisevskis1af91262020-08-10 14:58:08 -070027 IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
28 IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070029 KeyMetadata::KeyMetadata, KeyParameter::KeyParameter, KeyParameters::KeyParameters,
Janis Danisevskis1af91262020-08-10 14:58:08 -070030 SecurityLevel::SecurityLevel,
31};
32
33use crate::error::{self, map_km_error, map_or_log_err, Error, ErrorCode};
34use crate::globals::DB;
35use crate::permission::KeyPerm;
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070036use crate::utils::{check_key_permission, keyparam_km_to_ks, keyparam_ks_to_km, Asp};
Janis Danisevskis1af91262020-08-10 14:58:08 -070037use crate::{
38 database::{KeyEntry, KeyEntryLoadBits, SubComponentType},
39 operation::KeystoreOperation,
40 operation::OperationDb,
41};
42use anyhow::{anyhow, Context, Result};
43use binder::{IBinder, Interface, ThreadState};
44
45/// Implementation of the IKeystoreSecurityLevel Interface.
46pub struct KeystoreSecurityLevel {
47 security_level: SecurityLevel,
48 keymint: Asp,
49 operation_db: OperationDb,
50}
51
52static KEYMINT_SERVICE_NAME: &str = "android.hardware.keymint.IKeyMintDevice";
53
54// Blob of 32 zeroes used as empty masking key.
55static ZERO_BLOB_32: &[u8] = &[0; 32];
56
57impl KeystoreSecurityLevel {
58 /// Creates a new security level instance wrapped in a
59 /// BnKeystoreSecurityLevel proxy object. It also
60 /// calls `IBinder::set_requesting_sid` on the new interface, because
61 /// we need it for checking keystore permissions.
62 pub fn new_native_binder(
63 security_level: SecurityLevel,
64 ) -> Result<impl IKeystoreSecurityLevel + Send> {
65 let service_name = format!("{}/default", KEYMINT_SERVICE_NAME);
66 let keymint: Box<dyn IKeyMintDevice> =
67 binder::get_interface(&service_name).map_err(|e| {
68 anyhow!(format!(
69 "Could not get KeyMint instance: {} failed with error code {:?}",
70 service_name, e
71 ))
72 })?;
73
74 let result = BnKeystoreSecurityLevel::new_binder(Self {
75 security_level,
76 keymint: Asp::new(keymint.as_binder()),
77 operation_db: OperationDb::new(),
78 });
79 result.as_binder().set_requesting_sid(true);
80 Ok(result)
81 }
82
83 fn store_new_key(
84 &self,
85 key: KeyDescriptor,
86 km_cert_chain: Option<Vec<KmCertificate>>,
Janis Danisevskis85d47932020-10-23 16:12:59 -070087 blob: ByteArray,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070088 ) -> Result<KeyMetadata> {
89 let (cert, cert_chain): (Option<Vec<u8>>, Option<Vec<u8>>) = match km_cert_chain {
Janis Danisevskis1af91262020-08-10 14:58:08 -070090 Some(mut chain) => (
91 match chain.len() {
92 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070093 _ => Some(chain.remove(0).encodedCertificate),
Janis Danisevskis1af91262020-08-10 14:58:08 -070094 },
95 match chain.len() {
96 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070097 _ => Some(
98 chain
Janis Danisevskis1af91262020-08-10 14:58:08 -070099 .iter()
100 .map(|c| c.encodedCertificate.iter())
101 .flatten()
102 .copied()
103 .collect(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700104 ),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700105 },
106 ),
107 None => (None, None),
108 };
109
110 let key = match key.domain {
111 Domain::BLOB => {
Janis Danisevskis85d47932020-10-23 16:12:59 -0700112 KeyDescriptor { domain: Domain::BLOB, blob: Some(blob.data), ..Default::default() }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700113 }
114 _ => DB
115 .with(|db| {
116 let mut db = db.borrow_mut();
117 let key_id = db
118 .create_key_entry(key.domain, key.nspace)
119 .context("Trying to create a key entry.")?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700120 db.insert_blob(
121 key_id,
122 SubComponentType::KM_BLOB,
123 &blob.data,
124 self.security_level,
125 )
126 .context("Trying to insert km blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700127 if let Some(c) = &cert {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700128 db.insert_blob(key_id, SubComponentType::CERT, c, self.security_level)
129 .context("Trying to insert cert blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700130 }
131 if let Some(c) = &cert_chain {
132 db.insert_blob(
133 key_id,
134 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700135 c,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700136 self.security_level,
137 )
138 .context("Trying to insert cert chain blob.")?;
139 }
140 match &key.alias {
141 Some(alias) => db
142 .rebind_alias(key_id, alias, key.domain, key.nspace)
143 .context("Failed to rebind alias.")?,
144 None => {
145 return Err(error::Error::sys()).context(
146 "Alias must be specified. (This should have been checked earlier.)",
147 )
148 }
149 }
150 Ok(KeyDescriptor {
151 domain: Domain::KEY_ID,
152 nspace: key_id,
153 ..Default::default()
154 })
155 })
156 .context("In store_new_key.")?,
157 };
158
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700159 Ok(KeyMetadata {
160 key,
161 keySecurityLevel: self.security_level,
162 certificate: cert,
163 certificateChain: cert_chain,
164 // TODO initialize the authorizations.
165 ..Default::default()
166 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700167 }
168
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700169 fn create_operation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700170 &self,
171 key: &KeyDescriptor,
172 operation_parameters: &[KeyParameter],
173 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700174 ) -> Result<CreateOperationResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700175 let caller_uid = ThreadState::get_calling_uid();
176 // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
177 // so that we can use it by reference like the blob provided by the key descriptor.
178 // Otherwise, we would have to clone the blob from the key descriptor.
179 let scoping_blob: Vec<u8>;
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700180 let (km_blob, key_id) = match key.domain {
181 Domain::BLOB => {
182 check_key_permission(KeyPerm::use_(), key, &None)
183 .context("In create_operation: checking use permission for Domain::BLOB.")?;
184 (
185 match &key.blob {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700186 Some(blob) => blob,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700187 None => {
188 return Err(Error::sys()).context(concat!(
189 "In create_operation: Key blob must be specified when",
190 " using Domain::BLOB."
191 ))
192 }
193 },
194 None,
195 )
196 }
197 _ => {
198 let mut key_entry = DB
199 .with::<_, Result<KeyEntry>>(|db| {
200 db.borrow_mut().load_key_entry(
201 key.clone(),
202 KeyEntryLoadBits::KM,
203 caller_uid,
204 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
205 )
206 })
207 .context("In create_operation: Failed to load key blob.")?;
208 scoping_blob = match key_entry.take_km_blob() {
209 Some(blob) => blob,
210 None => {
211 return Err(Error::sys()).context(concat!(
212 "In create_operation: Successfully loaded key entry,",
213 " but KM blob was missing."
214 ))
215 }
216 };
217 (&scoping_blob, Some(key_entry.id()))
218 }
219 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700220
221 // TODO Authorize begin operation.
222 // Check if we need an authorization token.
223 // Lookup authorization token and request VerificationToken if required.
224
225 let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE.0).map_or(
226 Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700227 .context("In create_operation: No operation purpose specified."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700228 |kp| Ok(KeyPurpose(kp.integer)),
229 )?;
230
231 let km_params =
232 operation_parameters.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>();
233
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700234 let km_dev: Box<dyn IKeyMintDevice> = self
235 .keymint
236 .get_interface()
237 .context("In create_operation: Failed to get KeyMint device")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700238
239 let (begin_result, upgraded_blob) = loop {
240 match map_km_error(km_dev.begin(purpose, &km_blob, &km_params, &Default::default())) {
241 Ok(result) => break (result, None),
242 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700243 self.operation_db
244 .prune(caller_uid)
245 .context("In create_operation: Outer loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700246 continue;
247 }
248 Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
249 let upgraded_blob = map_km_error(km_dev.upgradeKey(&km_blob, &km_params))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700250 .context("In create_operation: Upgrade failed.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700251 break loop {
252 match map_km_error(km_dev.begin(
253 purpose,
254 &upgraded_blob,
255 &km_params,
256 &Default::default(),
257 )) {
258 Ok(result) => break (result, Some(upgraded_blob)),
259 // If Keystore 2.0 is multi threaded another request may have
260 // snatched up our previously pruned operation slot. So we might
261 // need to prune again.
262 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
263 self.operation_db
264 .prune(caller_uid)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700265 .context("In create_operation: Inner loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700266 continue;
267 }
268 Err(e) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700269 return Err(e).context(
270 "In create_operation: Begin operation failed after upgrade.",
271 )
Janis Danisevskis1af91262020-08-10 14:58:08 -0700272 }
273 }
274 };
275 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700276 Err(e) => return Err(e).context("In create_operation: Begin operation failed."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700277 };
278 };
279
280 if let Some(upgraded_blob) = upgraded_blob {
281 if let Some(key_id) = key_id {
282 DB.with(|db| {
283 db.borrow_mut().insert_blob(
284 key_id,
285 SubComponentType::KM_BLOB,
286 &upgraded_blob,
287 self.security_level,
288 )
289 })
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700290 .context(
291 "In create_operation: Failed to insert upgraded blob into the database.",
292 )?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700293 }
294 }
295
296 let operation = match begin_result.operation {
297 Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700298 None => return Err(Error::sys()).context("In create_operation: Begin operation returned successfully, but did not return a valid operation."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700299 };
300
301 let op_binder: Box<dyn IKeystoreOperation> =
302 KeystoreOperation::new_native_binder(operation)
303 .as_binder()
304 .into_interface()
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700305 .context("In create_operation: Failed to create IKeystoreOperation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700306
307 // TODO we need to the enforcement module to determine if we need to return the challenge.
308 // We return None for now because we don't support auth bound keys yet.
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700309 Ok(CreateOperationResponse {
310 iOperation: Some(op_binder),
311 operationChallenge: None,
312 parameters: match begin_result.params.len() {
313 0 => None,
314 _ => Some(KeyParameters {
315 keyParameter: begin_result
316 .params
317 .iter()
318 .map(|p| keyparam_km_to_ks(p))
319 .collect(),
320 }),
321 },
322 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700323 }
324
325 fn generate_key(
326 &self,
327 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700328 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700329 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700330 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700331 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700332 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700333 if key.domain != Domain::BLOB && key.alias.is_none() {
334 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
335 .context("In generate_key: Alias must be specified");
336 }
337
338 let key = match key.domain {
339 Domain::APP => KeyDescriptor {
340 domain: key.domain,
341 nspace: ThreadState::get_calling_uid() as i64,
342 alias: key.alias.clone(),
343 blob: None,
344 },
345 _ => key.clone(),
346 };
347
348 // generate_key requires the rebind permission.
349 check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
350
351 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
352 map_km_error(km_dev.addRngEntropy(entropy))?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700353 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700354 let mut key_characteristics: KeyCharacteristics = Default::default();
355 let mut certificate_chain: Vec<KmCertificate> = Default::default();
356 map_km_error(km_dev.generateKey(
357 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
358 &mut blob,
359 &mut key_characteristics,
360 &mut certificate_chain,
361 ))?;
362
363 self.store_new_key(key, Some(certificate_chain), blob).context("In generate_key.")
364 }
365
366 fn import_key(
367 &self,
368 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700369 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700370 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700371 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700372 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700373 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700374 if key.domain != Domain::BLOB && key.alias.is_none() {
375 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
376 .context("In import_key: Alias must be specified");
377 }
378
379 let key = match key.domain {
380 Domain::APP => KeyDescriptor {
381 domain: key.domain,
382 nspace: ThreadState::get_calling_uid() as i64,
383 alias: key.alias.clone(),
384 blob: None,
385 },
386 _ => key.clone(),
387 };
388
389 // import_key requires the rebind permission.
390 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
391
Janis Danisevskis85d47932020-10-23 16:12:59 -0700392 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700393 let mut key_characteristics: KeyCharacteristics = Default::default();
394 let mut certificate_chain: Vec<KmCertificate> = Default::default();
395
396 let format = params
397 .iter()
398 .find(|p| p.tag == Tag::ALGORITHM.0)
399 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
400 .context("No KeyParameter 'Algorithm'.")
401 .and_then(|p| match Algorithm(p.integer) {
402 Algorithm::AES | Algorithm::HMAC | Algorithm::TRIPLE_DES => Ok(KeyFormat::RAW),
403 Algorithm::RSA | Algorithm::EC => Ok(KeyFormat::PKCS8),
404 algorithm => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
405 .context(format!("Unknown Algorithm {:?}.", algorithm)),
406 })
407 .context("In import_key.")?;
408
409 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
410 map_km_error(km_dev.importKey(
411 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
412 format,
413 key_data,
414 &mut blob,
415 &mut key_characteristics,
416 &mut certificate_chain,
417 ))?;
418
419 self.store_new_key(key, Some(certificate_chain), blob).context("In import_key.")
420 }
421
422 fn import_wrapped_key(
423 &self,
424 key: &KeyDescriptor,
425 wrapping_key: &KeyDescriptor,
426 masking_key: Option<&[u8]>,
427 params: &[KeyParameter],
428 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700429 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700430 if key.domain != Domain::BLOB && key.alias.is_none() {
431 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
432 .context("In import_wrapped_key: Alias must be specified.");
433 }
434
435 let wrapped_data = match &key.blob {
436 Some(d) => d,
437 None => {
438 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
439 "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
440 )
441 }
442 };
443
444 let key = match key.domain {
445 Domain::APP => KeyDescriptor {
446 domain: key.domain,
447 nspace: ThreadState::get_calling_uid() as i64,
448 alias: key.alias.clone(),
449 blob: None,
450 },
451 _ => key.clone(),
452 };
453
454 // import_wrapped_key requires the rebind permission for the new key.
455 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
456
457 let wrapping_key_entry = DB
458 .with(|db| {
459 db.borrow_mut().load_key_entry(
460 wrapping_key.clone(),
461 KeyEntryLoadBits::KM,
462 ThreadState::get_calling_uid(),
463 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
464 )
465 })
466 .context("Failed to load wrapping key.")?;
467 let wrapping_key_blob = match wrapping_key_entry.km_blob() {
468 Some(blob) => blob,
469 None => {
470 return Err(error::Error::sys()).context(concat!(
471 "No km_blob after successfully loading key.",
472 " This should never happen."
473 ))
474 }
475 };
476
Janis Danisevskis85d47932020-10-23 16:12:59 -0700477 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700478 let mut key_characteristics: KeyCharacteristics = Default::default();
479 // km_dev.importWrappedKey does not return a certificate chain.
480 // TODO Do we assume that all wrapped keys are symmetric?
481 // let certificate_chain: Vec<KmCertificate> = Default::default();
482
483 let pw_sid = authenticators
484 .iter()
485 .find_map(|a| match a.authenticatorType {
486 AuthenticatorType::PASSWORD => Some(a.authenticatorId),
487 _ => None,
488 })
489 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
490 .context("A password authenticator SID must be specified.")?;
491
492 let fp_sid = authenticators
493 .iter()
494 .find_map(|a| match a.authenticatorType {
495 AuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
496 _ => None,
497 })
498 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
499 .context("A fingerprint authenticator SID must be specified.")?;
500
501 let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
502
503 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
504 map_km_error(km_dev.importWrappedKey(
505 wrapped_data,
506 wrapping_key_blob,
507 masking_key,
508 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
509 pw_sid,
510 fp_sid,
511 &mut blob,
512 &mut key_characteristics,
513 ))?;
514
515 self.store_new_key(key, None, blob).context("In import_wrapped_key.")
516 }
517}
518
519impl binder::Interface for KeystoreSecurityLevel {}
520
521impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700522 fn createOperation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700523 &self,
524 key: &KeyDescriptor,
525 operation_parameters: &[KeyParameter],
526 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700527 ) -> binder::public_api::Result<CreateOperationResponse> {
528 map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700529 }
530 fn generateKey(
531 &self,
532 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700533 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700534 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700535 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700536 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700537 ) -> binder::public_api::Result<KeyMetadata> {
538 map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700539 }
540 fn importKey(
541 &self,
542 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700543 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700544 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700545 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700546 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700547 ) -> binder::public_api::Result<KeyMetadata> {
548 map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700549 }
550 fn importWrappedKey(
551 &self,
552 key: &KeyDescriptor,
553 wrapping_key: &KeyDescriptor,
554 masking_key: Option<&[u8]>,
555 params: &[KeyParameter],
556 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700557 ) -> binder::public_api::Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700558 map_or_log_err(
559 self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700560 Ok,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700561 )
562 }
563}