blob: 30c9a86c318a5bcb7cf1044368b39f01d524480d [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::{
20 Algorithm::Algorithm, Certificate::Certificate as KmCertificate,
21 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>>,
87 blob: Vec<u8>,
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 => {
112 KeyDescriptor { domain: Domain::BLOB, blob: Some(blob), ..Default::default() }
113 }
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.")?;
120 db.insert_blob(key_id, SubComponentType::KM_BLOB, &blob, self.security_level)
121 .context("Trying to insert km blob.")?;
122 if let Some(c) = &cert {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700123 db.insert_blob(key_id, SubComponentType::CERT, c, self.security_level)
124 .context("Trying to insert cert blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700125 }
126 if let Some(c) = &cert_chain {
127 db.insert_blob(
128 key_id,
129 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700130 c,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700131 self.security_level,
132 )
133 .context("Trying to insert cert chain blob.")?;
134 }
135 match &key.alias {
136 Some(alias) => db
137 .rebind_alias(key_id, alias, key.domain, key.nspace)
138 .context("Failed to rebind alias.")?,
139 None => {
140 return Err(error::Error::sys()).context(
141 "Alias must be specified. (This should have been checked earlier.)",
142 )
143 }
144 }
145 Ok(KeyDescriptor {
146 domain: Domain::KEY_ID,
147 nspace: key_id,
148 ..Default::default()
149 })
150 })
151 .context("In store_new_key.")?,
152 };
153
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700154 Ok(KeyMetadata {
155 key,
156 keySecurityLevel: self.security_level,
157 certificate: cert,
158 certificateChain: cert_chain,
159 // TODO initialize the authorizations.
160 ..Default::default()
161 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700162 }
163
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700164 fn create_operation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700165 &self,
166 key: &KeyDescriptor,
167 operation_parameters: &[KeyParameter],
168 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700169 ) -> Result<CreateOperationResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700170 let caller_uid = ThreadState::get_calling_uid();
171 // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
172 // so that we can use it by reference like the blob provided by the key descriptor.
173 // Otherwise, we would have to clone the blob from the key descriptor.
174 let scoping_blob: Vec<u8>;
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700175 let (km_blob, key_id) = match key.domain {
176 Domain::BLOB => {
177 check_key_permission(KeyPerm::use_(), key, &None)
178 .context("In create_operation: checking use permission for Domain::BLOB.")?;
179 (
180 match &key.blob {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700181 Some(blob) => blob,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700182 None => {
183 return Err(Error::sys()).context(concat!(
184 "In create_operation: Key blob must be specified when",
185 " using Domain::BLOB."
186 ))
187 }
188 },
189 None,
190 )
191 }
192 _ => {
193 let mut key_entry = DB
194 .with::<_, Result<KeyEntry>>(|db| {
195 db.borrow_mut().load_key_entry(
196 key.clone(),
197 KeyEntryLoadBits::KM,
198 caller_uid,
199 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
200 )
201 })
202 .context("In create_operation: Failed to load key blob.")?;
203 scoping_blob = match key_entry.take_km_blob() {
204 Some(blob) => blob,
205 None => {
206 return Err(Error::sys()).context(concat!(
207 "In create_operation: Successfully loaded key entry,",
208 " but KM blob was missing."
209 ))
210 }
211 };
212 (&scoping_blob, Some(key_entry.id()))
213 }
214 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700215
216 // TODO Authorize begin operation.
217 // Check if we need an authorization token.
218 // Lookup authorization token and request VerificationToken if required.
219
220 let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE.0).map_or(
221 Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700222 .context("In create_operation: No operation purpose specified."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700223 |kp| Ok(KeyPurpose(kp.integer)),
224 )?;
225
226 let km_params =
227 operation_parameters.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>();
228
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700229 let km_dev: Box<dyn IKeyMintDevice> = self
230 .keymint
231 .get_interface()
232 .context("In create_operation: Failed to get KeyMint device")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700233
234 let (begin_result, upgraded_blob) = loop {
235 match map_km_error(km_dev.begin(purpose, &km_blob, &km_params, &Default::default())) {
236 Ok(result) => break (result, None),
237 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700238 self.operation_db
239 .prune(caller_uid)
240 .context("In create_operation: Outer loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700241 continue;
242 }
243 Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
244 let upgraded_blob = map_km_error(km_dev.upgradeKey(&km_blob, &km_params))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700245 .context("In create_operation: Upgrade failed.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700246 break loop {
247 match map_km_error(km_dev.begin(
248 purpose,
249 &upgraded_blob,
250 &km_params,
251 &Default::default(),
252 )) {
253 Ok(result) => break (result, Some(upgraded_blob)),
254 // If Keystore 2.0 is multi threaded another request may have
255 // snatched up our previously pruned operation slot. So we might
256 // need to prune again.
257 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
258 self.operation_db
259 .prune(caller_uid)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700260 .context("In create_operation: Inner loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700261 continue;
262 }
263 Err(e) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700264 return Err(e).context(
265 "In create_operation: Begin operation failed after upgrade.",
266 )
Janis Danisevskis1af91262020-08-10 14:58:08 -0700267 }
268 }
269 };
270 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700271 Err(e) => return Err(e).context("In create_operation: Begin operation failed."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700272 };
273 };
274
275 if let Some(upgraded_blob) = upgraded_blob {
276 if let Some(key_id) = key_id {
277 DB.with(|db| {
278 db.borrow_mut().insert_blob(
279 key_id,
280 SubComponentType::KM_BLOB,
281 &upgraded_blob,
282 self.security_level,
283 )
284 })
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700285 .context(
286 "In create_operation: Failed to insert upgraded blob into the database.",
287 )?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700288 }
289 }
290
291 let operation = match begin_result.operation {
292 Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700293 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 -0700294 };
295
296 let op_binder: Box<dyn IKeystoreOperation> =
297 KeystoreOperation::new_native_binder(operation)
298 .as_binder()
299 .into_interface()
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700300 .context("In create_operation: Failed to create IKeystoreOperation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700301
302 // TODO we need to the enforcement module to determine if we need to return the challenge.
303 // We return None for now because we don't support auth bound keys yet.
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700304 Ok(CreateOperationResponse {
305 iOperation: Some(op_binder),
306 operationChallenge: None,
307 parameters: match begin_result.params.len() {
308 0 => None,
309 _ => Some(KeyParameters {
310 keyParameter: begin_result
311 .params
312 .iter()
313 .map(|p| keyparam_km_to_ks(p))
314 .collect(),
315 }),
316 },
317 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700318 }
319
320 fn generate_key(
321 &self,
322 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700323 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700324 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700325 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700326 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700327 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700328 if key.domain != Domain::BLOB && key.alias.is_none() {
329 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
330 .context("In generate_key: Alias must be specified");
331 }
332
333 let key = match key.domain {
334 Domain::APP => KeyDescriptor {
335 domain: key.domain,
336 nspace: ThreadState::get_calling_uid() as i64,
337 alias: key.alias.clone(),
338 blob: None,
339 },
340 _ => key.clone(),
341 };
342
343 // generate_key requires the rebind permission.
344 check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
345
346 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
347 map_km_error(km_dev.addRngEntropy(entropy))?;
348 let mut blob: Vec<u8> = Default::default();
349 let mut key_characteristics: KeyCharacteristics = Default::default();
350 let mut certificate_chain: Vec<KmCertificate> = Default::default();
351 map_km_error(km_dev.generateKey(
352 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
353 &mut blob,
354 &mut key_characteristics,
355 &mut certificate_chain,
356 ))?;
357
358 self.store_new_key(key, Some(certificate_chain), blob).context("In generate_key.")
359 }
360
361 fn import_key(
362 &self,
363 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700364 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700365 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700366 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700367 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700368 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700369 if key.domain != Domain::BLOB && key.alias.is_none() {
370 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
371 .context("In import_key: Alias must be specified");
372 }
373
374 let key = match key.domain {
375 Domain::APP => KeyDescriptor {
376 domain: key.domain,
377 nspace: ThreadState::get_calling_uid() as i64,
378 alias: key.alias.clone(),
379 blob: None,
380 },
381 _ => key.clone(),
382 };
383
384 // import_key requires the rebind permission.
385 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
386
387 let mut blob: Vec<u8> = Default::default();
388 let mut key_characteristics: KeyCharacteristics = Default::default();
389 let mut certificate_chain: Vec<KmCertificate> = Default::default();
390
391 let format = params
392 .iter()
393 .find(|p| p.tag == Tag::ALGORITHM.0)
394 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
395 .context("No KeyParameter 'Algorithm'.")
396 .and_then(|p| match Algorithm(p.integer) {
397 Algorithm::AES | Algorithm::HMAC | Algorithm::TRIPLE_DES => Ok(KeyFormat::RAW),
398 Algorithm::RSA | Algorithm::EC => Ok(KeyFormat::PKCS8),
399 algorithm => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
400 .context(format!("Unknown Algorithm {:?}.", algorithm)),
401 })
402 .context("In import_key.")?;
403
404 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
405 map_km_error(km_dev.importKey(
406 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
407 format,
408 key_data,
409 &mut blob,
410 &mut key_characteristics,
411 &mut certificate_chain,
412 ))?;
413
414 self.store_new_key(key, Some(certificate_chain), blob).context("In import_key.")
415 }
416
417 fn import_wrapped_key(
418 &self,
419 key: &KeyDescriptor,
420 wrapping_key: &KeyDescriptor,
421 masking_key: Option<&[u8]>,
422 params: &[KeyParameter],
423 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700424 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700425 if key.domain != Domain::BLOB && key.alias.is_none() {
426 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
427 .context("In import_wrapped_key: Alias must be specified.");
428 }
429
430 let wrapped_data = match &key.blob {
431 Some(d) => d,
432 None => {
433 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
434 "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
435 )
436 }
437 };
438
439 let key = match key.domain {
440 Domain::APP => KeyDescriptor {
441 domain: key.domain,
442 nspace: ThreadState::get_calling_uid() as i64,
443 alias: key.alias.clone(),
444 blob: None,
445 },
446 _ => key.clone(),
447 };
448
449 // import_wrapped_key requires the rebind permission for the new key.
450 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
451
452 let wrapping_key_entry = DB
453 .with(|db| {
454 db.borrow_mut().load_key_entry(
455 wrapping_key.clone(),
456 KeyEntryLoadBits::KM,
457 ThreadState::get_calling_uid(),
458 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
459 )
460 })
461 .context("Failed to load wrapping key.")?;
462 let wrapping_key_blob = match wrapping_key_entry.km_blob() {
463 Some(blob) => blob,
464 None => {
465 return Err(error::Error::sys()).context(concat!(
466 "No km_blob after successfully loading key.",
467 " This should never happen."
468 ))
469 }
470 };
471
472 let mut blob: Vec<u8> = Default::default();
473 let mut key_characteristics: KeyCharacteristics = Default::default();
474 // km_dev.importWrappedKey does not return a certificate chain.
475 // TODO Do we assume that all wrapped keys are symmetric?
476 // let certificate_chain: Vec<KmCertificate> = Default::default();
477
478 let pw_sid = authenticators
479 .iter()
480 .find_map(|a| match a.authenticatorType {
481 AuthenticatorType::PASSWORD => Some(a.authenticatorId),
482 _ => None,
483 })
484 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
485 .context("A password authenticator SID must be specified.")?;
486
487 let fp_sid = authenticators
488 .iter()
489 .find_map(|a| match a.authenticatorType {
490 AuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
491 _ => None,
492 })
493 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
494 .context("A fingerprint authenticator SID must be specified.")?;
495
496 let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
497
498 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
499 map_km_error(km_dev.importWrappedKey(
500 wrapped_data,
501 wrapping_key_blob,
502 masking_key,
503 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
504 pw_sid,
505 fp_sid,
506 &mut blob,
507 &mut key_characteristics,
508 ))?;
509
510 self.store_new_key(key, None, blob).context("In import_wrapped_key.")
511 }
512}
513
514impl binder::Interface for KeystoreSecurityLevel {}
515
516impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700517 fn createOperation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700518 &self,
519 key: &KeyDescriptor,
520 operation_parameters: &[KeyParameter],
521 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700522 ) -> binder::public_api::Result<CreateOperationResponse> {
523 map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700524 }
525 fn generateKey(
526 &self,
527 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700528 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700529 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700530 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700531 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700532 ) -> binder::public_api::Result<KeyMetadata> {
533 map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700534 }
535 fn importKey(
536 &self,
537 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700538 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700539 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700540 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700541 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700542 ) -> binder::public_api::Result<KeyMetadata> {
543 map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700544 }
545 fn importWrappedKey(
546 &self,
547 key: &KeyDescriptor,
548 wrapping_key: &KeyDescriptor,
549 masking_key: Option<&[u8]>,
550 params: &[KeyParameter],
551 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700552 ) -> binder::public_api::Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700553 map_or_log_err(
554 self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700555 Ok,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700556 )
557 }
558}