blob: 0b5889ec28c0df99e6bf2f61025475d540491461 [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,
Janis Danisevskis04b02832020-10-26 09:21:40 -070022 KeyParameter::KeyParameter as KmParam, KeyPurpose::KeyPurpose, SecurityLevel::SecurityLevel,
23 Tag::Tag,
Janis Danisevskis1af91262020-08-10 14:58:08 -070024};
25use android_system_keystore2::aidl::android::system::keystore2::{
26 AuthenticatorSpec::AuthenticatorSpec, AuthenticatorType::AuthenticatorType,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070027 CreateOperationResponse::CreateOperationResponse, Domain::Domain,
Janis Danisevskis1af91262020-08-10 14:58:08 -070028 IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
29 IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070030 KeyMetadata::KeyMetadata, KeyParameter::KeyParameter, KeyParameters::KeyParameters,
Janis Danisevskis04b02832020-10-26 09:21:40 -070031 SecurityLevel::SecurityLevel as KsSecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -070032};
33
Janis Danisevskis1af91262020-08-10 14:58:08 -070034use 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};
Janis Danisevskis04b02832020-10-26 09:21:40 -070042use crate::{
43 error::{self, map_km_error, map_or_log_err, Error, ErrorCode},
44 utils::key_characteristics_to_internal,
45};
Janis Danisevskis1af91262020-08-10 14:58:08 -070046use anyhow::{anyhow, Context, Result};
47use binder::{IBinder, Interface, ThreadState};
48
49/// Implementation of the IKeystoreSecurityLevel Interface.
50pub struct KeystoreSecurityLevel {
51 security_level: SecurityLevel,
52 keymint: Asp,
53 operation_db: OperationDb,
54}
55
56static KEYMINT_SERVICE_NAME: &str = "android.hardware.keymint.IKeyMintDevice";
57
58// Blob of 32 zeroes used as empty masking key.
59static ZERO_BLOB_32: &[u8] = &[0; 32];
60
61impl KeystoreSecurityLevel {
62 /// Creates a new security level instance wrapped in a
63 /// BnKeystoreSecurityLevel proxy object. It also
64 /// calls `IBinder::set_requesting_sid` on the new interface, because
65 /// we need it for checking keystore permissions.
66 pub fn new_native_binder(
67 security_level: SecurityLevel,
68 ) -> Result<impl IKeystoreSecurityLevel + Send> {
69 let service_name = format!("{}/default", KEYMINT_SERVICE_NAME);
70 let keymint: Box<dyn IKeyMintDevice> =
71 binder::get_interface(&service_name).map_err(|e| {
72 anyhow!(format!(
73 "Could not get KeyMint instance: {} failed with error code {:?}",
74 service_name, e
75 ))
76 })?;
77
78 let result = BnKeystoreSecurityLevel::new_binder(Self {
79 security_level,
80 keymint: Asp::new(keymint.as_binder()),
81 operation_db: OperationDb::new(),
82 });
83 result.as_binder().set_requesting_sid(true);
84 Ok(result)
85 }
86
87 fn store_new_key(
88 &self,
89 key: KeyDescriptor,
Janis Danisevskis04b02832020-10-26 09:21:40 -070090 key_characteristics: KeyCharacteristics,
Janis Danisevskis1af91262020-08-10 14:58:08 -070091 km_cert_chain: Option<Vec<KmCertificate>>,
Janis Danisevskis85d47932020-10-23 16:12:59 -070092 blob: ByteArray,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070093 ) -> Result<KeyMetadata> {
94 let (cert, cert_chain): (Option<Vec<u8>>, Option<Vec<u8>>) = match km_cert_chain {
Janis Danisevskis1af91262020-08-10 14:58:08 -070095 Some(mut chain) => (
96 match chain.len() {
97 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070098 _ => Some(chain.remove(0).encodedCertificate),
Janis Danisevskis1af91262020-08-10 14:58:08 -070099 },
100 match chain.len() {
101 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700102 _ => Some(
103 chain
Janis Danisevskis1af91262020-08-10 14:58:08 -0700104 .iter()
105 .map(|c| c.encodedCertificate.iter())
106 .flatten()
107 .copied()
108 .collect(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700109 ),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700110 },
111 ),
112 None => (None, None),
113 };
114
Janis Danisevskis04b02832020-10-26 09:21:40 -0700115 let key_parameters =
116 key_characteristics_to_internal(key_characteristics, self.security_level);
117
Janis Danisevskis1af91262020-08-10 14:58:08 -0700118 let key = match key.domain {
119 Domain::BLOB => {
Janis Danisevskis85d47932020-10-23 16:12:59 -0700120 KeyDescriptor { domain: Domain::BLOB, blob: Some(blob.data), ..Default::default() }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700121 }
122 _ => DB
123 .with(|db| {
124 let mut db = db.borrow_mut();
125 let key_id = db
126 .create_key_entry(key.domain, key.nspace)
127 .context("Trying to create a key entry.")?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700128 db.insert_blob(
129 key_id,
130 SubComponentType::KM_BLOB,
131 &blob.data,
132 self.security_level,
133 )
134 .context("Trying to insert km blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700135 if let Some(c) = &cert {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700136 db.insert_blob(key_id, SubComponentType::CERT, c, self.security_level)
137 .context("Trying to insert cert blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700138 }
139 if let Some(c) = &cert_chain {
140 db.insert_blob(
141 key_id,
142 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700143 c,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700144 self.security_level,
145 )
146 .context("Trying to insert cert chain blob.")?;
147 }
Janis Danisevskis04b02832020-10-26 09:21:40 -0700148 db.insert_keyparameter(key_id, &key_parameters)
149 .context("Trying to insert key parameters.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700150 match &key.alias {
151 Some(alias) => db
152 .rebind_alias(key_id, alias, key.domain, key.nspace)
153 .context("Failed to rebind alias.")?,
154 None => {
155 return Err(error::Error::sys()).context(
156 "Alias must be specified. (This should have been checked earlier.)",
157 )
158 }
159 }
160 Ok(KeyDescriptor {
161 domain: Domain::KEY_ID,
162 nspace: key_id,
163 ..Default::default()
164 })
165 })
166 .context("In store_new_key.")?,
167 };
168
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700169 Ok(KeyMetadata {
170 key,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700171 keySecurityLevel: KsSecurityLevel(self.security_level.0),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700172 certificate: cert,
173 certificateChain: cert_chain,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700174 authorizations: crate::utils::key_parameters_to_authorizations(key_parameters),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700175 ..Default::default()
176 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700177 }
178
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700179 fn create_operation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700180 &self,
181 key: &KeyDescriptor,
182 operation_parameters: &[KeyParameter],
183 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700184 ) -> Result<CreateOperationResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700185 let caller_uid = ThreadState::get_calling_uid();
186 // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
187 // so that we can use it by reference like the blob provided by the key descriptor.
188 // Otherwise, we would have to clone the blob from the key descriptor.
189 let scoping_blob: Vec<u8>;
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700190 let (km_blob, key_id) = match key.domain {
191 Domain::BLOB => {
192 check_key_permission(KeyPerm::use_(), key, &None)
193 .context("In create_operation: checking use permission for Domain::BLOB.")?;
194 (
195 match &key.blob {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700196 Some(blob) => blob,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700197 None => {
198 return Err(Error::sys()).context(concat!(
199 "In create_operation: Key blob must be specified when",
200 " using Domain::BLOB."
201 ))
202 }
203 },
204 None,
205 )
206 }
207 _ => {
208 let mut key_entry = DB
209 .with::<_, Result<KeyEntry>>(|db| {
210 db.borrow_mut().load_key_entry(
211 key.clone(),
212 KeyEntryLoadBits::KM,
213 caller_uid,
214 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
215 )
216 })
217 .context("In create_operation: Failed to load key blob.")?;
218 scoping_blob = match key_entry.take_km_blob() {
219 Some(blob) => blob,
220 None => {
221 return Err(Error::sys()).context(concat!(
222 "In create_operation: Successfully loaded key entry,",
223 " but KM blob was missing."
224 ))
225 }
226 };
227 (&scoping_blob, Some(key_entry.id()))
228 }
229 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700230
231 // TODO Authorize begin operation.
232 // Check if we need an authorization token.
233 // Lookup authorization token and request VerificationToken if required.
234
235 let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE.0).map_or(
236 Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700237 .context("In create_operation: No operation purpose specified."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700238 |kp| Ok(KeyPurpose(kp.integer)),
239 )?;
240
241 let km_params =
242 operation_parameters.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>();
243
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700244 let km_dev: Box<dyn IKeyMintDevice> = self
245 .keymint
246 .get_interface()
247 .context("In create_operation: Failed to get KeyMint device")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700248
249 let (begin_result, upgraded_blob) = loop {
250 match map_km_error(km_dev.begin(purpose, &km_blob, &km_params, &Default::default())) {
251 Ok(result) => break (result, None),
252 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700253 self.operation_db
254 .prune(caller_uid)
255 .context("In create_operation: Outer loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700256 continue;
257 }
258 Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
259 let upgraded_blob = map_km_error(km_dev.upgradeKey(&km_blob, &km_params))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700260 .context("In create_operation: Upgrade failed.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700261 break loop {
262 match map_km_error(km_dev.begin(
263 purpose,
264 &upgraded_blob,
265 &km_params,
266 &Default::default(),
267 )) {
268 Ok(result) => break (result, Some(upgraded_blob)),
269 // If Keystore 2.0 is multi threaded another request may have
270 // snatched up our previously pruned operation slot. So we might
271 // need to prune again.
272 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
273 self.operation_db
274 .prune(caller_uid)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700275 .context("In create_operation: Inner loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700276 continue;
277 }
278 Err(e) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700279 return Err(e).context(
280 "In create_operation: Begin operation failed after upgrade.",
281 )
Janis Danisevskis1af91262020-08-10 14:58:08 -0700282 }
283 }
284 };
285 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700286 Err(e) => return Err(e).context("In create_operation: Begin operation failed."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700287 };
288 };
289
290 if let Some(upgraded_blob) = upgraded_blob {
291 if let Some(key_id) = key_id {
292 DB.with(|db| {
293 db.borrow_mut().insert_blob(
294 key_id,
295 SubComponentType::KM_BLOB,
296 &upgraded_blob,
297 self.security_level,
298 )
299 })
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700300 .context(
301 "In create_operation: Failed to insert upgraded blob into the database.",
302 )?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700303 }
304 }
305
306 let operation = match begin_result.operation {
307 Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700308 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 -0700309 };
310
311 let op_binder: Box<dyn IKeystoreOperation> =
312 KeystoreOperation::new_native_binder(operation)
313 .as_binder()
314 .into_interface()
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700315 .context("In create_operation: Failed to create IKeystoreOperation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700316
317 // TODO we need to the enforcement module to determine if we need to return the challenge.
318 // We return None for now because we don't support auth bound keys yet.
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700319 Ok(CreateOperationResponse {
320 iOperation: Some(op_binder),
321 operationChallenge: None,
322 parameters: match begin_result.params.len() {
323 0 => None,
324 _ => Some(KeyParameters {
325 keyParameter: begin_result
326 .params
327 .iter()
328 .map(|p| keyparam_km_to_ks(p))
329 .collect(),
330 }),
331 },
332 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700333 }
334
335 fn generate_key(
336 &self,
337 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700338 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700339 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700340 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700341 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700342 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700343 if key.domain != Domain::BLOB && key.alias.is_none() {
344 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
345 .context("In generate_key: Alias must be specified");
346 }
347
348 let key = match key.domain {
349 Domain::APP => KeyDescriptor {
350 domain: key.domain,
351 nspace: ThreadState::get_calling_uid() as i64,
352 alias: key.alias.clone(),
353 blob: None,
354 },
355 _ => key.clone(),
356 };
357
358 // generate_key requires the rebind permission.
359 check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
360
361 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
362 map_km_error(km_dev.addRngEntropy(entropy))?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700363 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700364 let mut key_characteristics: KeyCharacteristics = Default::default();
365 let mut certificate_chain: Vec<KmCertificate> = Default::default();
366 map_km_error(km_dev.generateKey(
367 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
368 &mut blob,
369 &mut key_characteristics,
370 &mut certificate_chain,
371 ))?;
372
Janis Danisevskis04b02832020-10-26 09:21:40 -0700373 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
374 .context("In generate_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700375 }
376
377 fn import_key(
378 &self,
379 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700380 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700381 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700382 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700383 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700384 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700385 if key.domain != Domain::BLOB && key.alias.is_none() {
386 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
387 .context("In import_key: Alias must be specified");
388 }
389
390 let key = match key.domain {
391 Domain::APP => KeyDescriptor {
392 domain: key.domain,
393 nspace: ThreadState::get_calling_uid() as i64,
394 alias: key.alias.clone(),
395 blob: None,
396 },
397 _ => key.clone(),
398 };
399
400 // import_key requires the rebind permission.
401 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
402
Janis Danisevskis85d47932020-10-23 16:12:59 -0700403 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700404 let mut key_characteristics: KeyCharacteristics = Default::default();
405 let mut certificate_chain: Vec<KmCertificate> = Default::default();
406
407 let format = params
408 .iter()
409 .find(|p| p.tag == Tag::ALGORITHM.0)
410 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
411 .context("No KeyParameter 'Algorithm'.")
412 .and_then(|p| match Algorithm(p.integer) {
413 Algorithm::AES | Algorithm::HMAC | Algorithm::TRIPLE_DES => Ok(KeyFormat::RAW),
414 Algorithm::RSA | Algorithm::EC => Ok(KeyFormat::PKCS8),
415 algorithm => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
416 .context(format!("Unknown Algorithm {:?}.", algorithm)),
417 })
418 .context("In import_key.")?;
419
420 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
421 map_km_error(km_dev.importKey(
422 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
423 format,
424 key_data,
425 &mut blob,
426 &mut key_characteristics,
427 &mut certificate_chain,
428 ))?;
429
Janis Danisevskis04b02832020-10-26 09:21:40 -0700430 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
431 .context("In import_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700432 }
433
434 fn import_wrapped_key(
435 &self,
436 key: &KeyDescriptor,
437 wrapping_key: &KeyDescriptor,
438 masking_key: Option<&[u8]>,
439 params: &[KeyParameter],
440 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700441 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700442 if key.domain != Domain::BLOB && key.alias.is_none() {
443 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
444 .context("In import_wrapped_key: Alias must be specified.");
445 }
446
447 let wrapped_data = match &key.blob {
448 Some(d) => d,
449 None => {
450 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
451 "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
452 )
453 }
454 };
455
456 let key = match key.domain {
457 Domain::APP => KeyDescriptor {
458 domain: key.domain,
459 nspace: ThreadState::get_calling_uid() as i64,
460 alias: key.alias.clone(),
461 blob: None,
462 },
463 _ => key.clone(),
464 };
465
466 // import_wrapped_key requires the rebind permission for the new key.
467 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
468
469 let wrapping_key_entry = DB
470 .with(|db| {
471 db.borrow_mut().load_key_entry(
472 wrapping_key.clone(),
473 KeyEntryLoadBits::KM,
474 ThreadState::get_calling_uid(),
475 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
476 )
477 })
478 .context("Failed to load wrapping key.")?;
479 let wrapping_key_blob = match wrapping_key_entry.km_blob() {
480 Some(blob) => blob,
481 None => {
482 return Err(error::Error::sys()).context(concat!(
483 "No km_blob after successfully loading key.",
484 " This should never happen."
485 ))
486 }
487 };
488
Janis Danisevskis85d47932020-10-23 16:12:59 -0700489 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700490 let mut key_characteristics: KeyCharacteristics = Default::default();
491 // km_dev.importWrappedKey does not return a certificate chain.
492 // TODO Do we assume that all wrapped keys are symmetric?
493 // let certificate_chain: Vec<KmCertificate> = Default::default();
494
495 let pw_sid = authenticators
496 .iter()
497 .find_map(|a| match a.authenticatorType {
498 AuthenticatorType::PASSWORD => Some(a.authenticatorId),
499 _ => None,
500 })
501 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
502 .context("A password authenticator SID must be specified.")?;
503
504 let fp_sid = authenticators
505 .iter()
506 .find_map(|a| match a.authenticatorType {
507 AuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
508 _ => None,
509 })
510 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
511 .context("A fingerprint authenticator SID must be specified.")?;
512
513 let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
514
515 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
516 map_km_error(km_dev.importWrappedKey(
517 wrapped_data,
518 wrapping_key_blob,
519 masking_key,
520 &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
521 pw_sid,
522 fp_sid,
523 &mut blob,
524 &mut key_characteristics,
525 ))?;
526
Janis Danisevskis04b02832020-10-26 09:21:40 -0700527 self.store_new_key(key, key_characteristics, None, blob).context("In import_wrapped_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700528 }
529}
530
531impl binder::Interface for KeystoreSecurityLevel {}
532
533impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700534 fn createOperation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700535 &self,
536 key: &KeyDescriptor,
537 operation_parameters: &[KeyParameter],
538 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700539 ) -> binder::public_api::Result<CreateOperationResponse> {
540 map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700541 }
542 fn generateKey(
543 &self,
544 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700545 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700546 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700547 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700548 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700549 ) -> binder::public_api::Result<KeyMetadata> {
550 map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700551 }
552 fn importKey(
553 &self,
554 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700555 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700556 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700557 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700558 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700559 ) -> binder::public_api::Result<KeyMetadata> {
560 map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700561 }
562 fn importWrappedKey(
563 &self,
564 key: &KeyDescriptor,
565 wrapping_key: &KeyDescriptor,
566 masking_key: Option<&[u8]>,
567 params: &[KeyParameter],
568 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700569 ) -> binder::public_api::Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700570 map_or_log_err(
571 self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700572 Ok,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700573 )
574 }
575}