blob: e7d07e315e8609a7d03741e52b37811f66e35236 [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
Shawn Willden708744a2020-12-11 13:05:27 +000019use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Janis Danisevskis85d47932020-10-23 16:12:59 -070020 Algorithm::Algorithm, ByteArray::ByteArray, Certificate::Certificate as KmCertificate,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -070021 HardwareAuthenticatorType::HardwareAuthenticatorType, IKeyMintDevice::IKeyMintDevice,
22 KeyCharacteristics::KeyCharacteristics, KeyFormat::KeyFormat, KeyParameter::KeyParameter,
23 KeyPurpose::KeyPurpose, SecurityLevel::SecurityLevel, Tag::Tag,
Janis Danisevskis1af91262020-08-10 14:58:08 -070024};
25use android_system_keystore2::aidl::android::system::keystore2::{
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -070026 AuthenticatorSpec::AuthenticatorSpec, CreateOperationResponse::CreateOperationResponse,
27 Domain::Domain, IKeystoreOperation::IKeystoreOperation,
28 IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
Janis Danisevskis1af91262020-08-10 14:58:08 -070029 IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -070030 KeyMetadata::KeyMetadata, KeyParameters::KeyParameters,
Janis Danisevskis1af91262020-08-10 14:58:08 -070031};
32
Janis Danisevskis1af91262020-08-10 14:58:08 -070033use crate::permission::KeyPerm;
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -070034use crate::utils::{check_key_permission, Asp};
Janis Danisevskisaec14592020-11-12 09:41:49 -080035use crate::{database::KeyIdGuard, globals::DB};
Janis Danisevskis1af91262020-08-10 14:58:08 -070036use crate::{
37 database::{KeyEntry, KeyEntryLoadBits, SubComponentType},
38 operation::KeystoreOperation,
39 operation::OperationDb,
40};
Janis Danisevskis04b02832020-10-26 09:21:40 -070041use crate::{
42 error::{self, map_km_error, map_or_log_err, Error, ErrorCode},
43 utils::key_characteristics_to_internal,
44};
Janis Danisevskis1af91262020-08-10 14:58:08 -070045use anyhow::{anyhow, Context, Result};
46use binder::{IBinder, Interface, ThreadState};
47
48/// Implementation of the IKeystoreSecurityLevel Interface.
49pub struct KeystoreSecurityLevel {
50 security_level: SecurityLevel,
51 keymint: Asp,
52 operation_db: OperationDb,
53}
54
55static KEYMINT_SERVICE_NAME: &str = "android.hardware.keymint.IKeyMintDevice";
56
57// Blob of 32 zeroes used as empty masking key.
58static ZERO_BLOB_32: &[u8] = &[0; 32];
59
60impl KeystoreSecurityLevel {
61 /// Creates a new security level instance wrapped in a
62 /// BnKeystoreSecurityLevel proxy object. It also
63 /// calls `IBinder::set_requesting_sid` on the new interface, because
64 /// we need it for checking keystore permissions.
65 pub fn new_native_binder(
66 security_level: SecurityLevel,
67 ) -> Result<impl IKeystoreSecurityLevel + Send> {
68 let service_name = format!("{}/default", KEYMINT_SERVICE_NAME);
69 let keymint: Box<dyn IKeyMintDevice> =
70 binder::get_interface(&service_name).map_err(|e| {
71 anyhow!(format!(
72 "Could not get KeyMint instance: {} failed with error code {:?}",
73 service_name, e
74 ))
75 })?;
76
77 let result = BnKeystoreSecurityLevel::new_binder(Self {
78 security_level,
79 keymint: Asp::new(keymint.as_binder()),
80 operation_db: OperationDb::new(),
81 });
82 result.as_binder().set_requesting_sid(true);
83 Ok(result)
84 }
85
86 fn store_new_key(
87 &self,
88 key: KeyDescriptor,
Janis Danisevskis04b02832020-10-26 09:21:40 -070089 key_characteristics: KeyCharacteristics,
Janis Danisevskis1af91262020-08-10 14:58:08 -070090 km_cert_chain: Option<Vec<KmCertificate>>,
Janis Danisevskis85d47932020-10-23 16:12:59 -070091 blob: ByteArray,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070092 ) -> Result<KeyMetadata> {
93 let (cert, cert_chain): (Option<Vec<u8>>, Option<Vec<u8>>) = match km_cert_chain {
Janis Danisevskis1af91262020-08-10 14:58:08 -070094 Some(mut chain) => (
95 match chain.len() {
96 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070097 _ => Some(chain.remove(0).encodedCertificate),
Janis Danisevskis1af91262020-08-10 14:58:08 -070098 },
99 match chain.len() {
100 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700101 _ => Some(
102 chain
Janis Danisevskis1af91262020-08-10 14:58:08 -0700103 .iter()
104 .map(|c| c.encodedCertificate.iter())
105 .flatten()
106 .copied()
107 .collect(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700108 ),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700109 },
110 ),
111 None => (None, None),
112 };
113
Janis Danisevskis04b02832020-10-26 09:21:40 -0700114 let key_parameters =
115 key_characteristics_to_internal(key_characteristics, self.security_level);
116
Janis Danisevskis1af91262020-08-10 14:58:08 -0700117 let key = match key.domain {
118 Domain::BLOB => {
Janis Danisevskis85d47932020-10-23 16:12:59 -0700119 KeyDescriptor { domain: Domain::BLOB, blob: Some(blob.data), ..Default::default() }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700120 }
121 _ => DB
122 .with(|db| {
123 let mut db = db.borrow_mut();
124 let key_id = db
125 .create_key_entry(key.domain, key.nspace)
126 .context("Trying to create a key entry.")?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700127 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800128 &key_id,
Janis Danisevskis85d47932020-10-23 16:12:59 -0700129 SubComponentType::KM_BLOB,
130 &blob.data,
131 self.security_level,
132 )
133 .context("Trying to insert km blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700134 if let Some(c) = &cert {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800135 db.insert_blob(&key_id, SubComponentType::CERT, c, self.security_level)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700136 .context("Trying to insert cert blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700137 }
138 if let Some(c) = &cert_chain {
139 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800140 &key_id,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700141 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700142 c,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700143 self.security_level,
144 )
145 .context("Trying to insert cert chain blob.")?;
146 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800147 db.insert_keyparameter(&key_id, &key_parameters)
Janis Danisevskis04b02832020-10-26 09:21:40 -0700148 .context("Trying to insert key parameters.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700149 match &key.alias {
150 Some(alias) => db
Janis Danisevskisaec14592020-11-12 09:41:49 -0800151 .rebind_alias(&key_id, alias, key.domain, key.nspace)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700152 .context("Failed to rebind alias.")?,
153 None => {
154 return Err(error::Error::sys()).context(
155 "Alias must be specified. (This should have been checked earlier.)",
156 )
157 }
158 }
159 Ok(KeyDescriptor {
160 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800161 nspace: key_id.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700162 ..Default::default()
163 })
164 })
165 .context("In store_new_key.")?,
166 };
167
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700168 Ok(KeyMetadata {
169 key,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700170 keySecurityLevel: self.security_level,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700171 certificate: cert,
172 certificateChain: cert_chain,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700173 authorizations: crate::utils::key_parameters_to_authorizations(key_parameters),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700174 ..Default::default()
175 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700176 }
177
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700178 fn create_operation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700179 &self,
180 key: &KeyDescriptor,
181 operation_parameters: &[KeyParameter],
182 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700183 ) -> Result<CreateOperationResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700184 let caller_uid = ThreadState::get_calling_uid();
185 // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
186 // so that we can use it by reference like the blob provided by the key descriptor.
187 // Otherwise, we would have to clone the blob from the key descriptor.
188 let scoping_blob: Vec<u8>;
Janis Danisevskisaec14592020-11-12 09:41:49 -0800189 let (km_blob, key_id_guard) = match key.domain {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700190 Domain::BLOB => {
191 check_key_permission(KeyPerm::use_(), key, &None)
192 .context("In create_operation: checking use permission for Domain::BLOB.")?;
193 (
194 match &key.blob {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700195 Some(blob) => blob,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700196 None => {
197 return Err(Error::sys()).context(concat!(
198 "In create_operation: Key blob must be specified when",
199 " using Domain::BLOB."
200 ))
201 }
202 },
203 None,
204 )
205 }
206 _ => {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800207 let (key_id_guard, mut key_entry) = DB
208 .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700209 db.borrow_mut().load_key_entry(
210 key.clone(),
211 KeyEntryLoadBits::KM,
212 caller_uid,
213 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
214 )
215 })
216 .context("In create_operation: Failed to load key blob.")?;
217 scoping_blob = match key_entry.take_km_blob() {
218 Some(blob) => blob,
219 None => {
220 return Err(Error::sys()).context(concat!(
221 "In create_operation: Successfully loaded key entry,",
222 " but KM blob was missing."
223 ))
224 }
225 };
Janis Danisevskisaec14592020-11-12 09:41:49 -0800226 (&scoping_blob, Some(key_id_guard))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700227 }
228 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700229
230 // TODO Authorize begin operation.
231 // Check if we need an authorization token.
232 // Lookup authorization token and request VerificationToken if required.
233
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700234 let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE).map_or(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700235 Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700236 .context("In create_operation: No operation purpose specified."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700237 |kp| Ok(KeyPurpose(kp.integer)),
238 )?;
239
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700240 let km_dev: Box<dyn IKeyMintDevice> = self
241 .keymint
242 .get_interface()
243 .context("In create_operation: Failed to get KeyMint device")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700244
Janis Danisevskisaec14592020-11-12 09:41:49 -0800245 let (begin_result, upgraded_blob) = self
246 .upgrade_keyblob_if_required_with(
247 &*km_dev,
248 key_id_guard,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700249 &km_blob,
250 &operation_parameters,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800251 |blob| loop {
252 match map_km_error(km_dev.begin(
253 purpose,
254 blob,
255 &operation_parameters,
256 &Default::default(),
257 )) {
258 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
259 self.operation_db.prune(caller_uid)?;
260 continue;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700261 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800262 v => return v,
263 }
264 },
265 )
266 .context("In create_operation: Failed to begin operation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700267
268 let operation = match begin_result.operation {
269 Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700270 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 -0700271 };
272
273 let op_binder: Box<dyn IKeystoreOperation> =
274 KeystoreOperation::new_native_binder(operation)
275 .as_binder()
276 .into_interface()
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700277 .context("In create_operation: Failed to create IKeystoreOperation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700278
279 // TODO we need to the enforcement module to determine if we need to return the challenge.
280 // We return None for now because we don't support auth bound keys yet.
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700281 Ok(CreateOperationResponse {
282 iOperation: Some(op_binder),
283 operationChallenge: None,
284 parameters: match begin_result.params.len() {
285 0 => None,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700286 _ => Some(KeyParameters { keyParameter: begin_result.params }),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700287 },
288 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700289 }
290
291 fn generate_key(
292 &self,
293 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700294 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700295 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700296 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700297 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700298 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700299 if key.domain != Domain::BLOB && key.alias.is_none() {
300 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
301 .context("In generate_key: Alias must be specified");
302 }
303
304 let key = match key.domain {
305 Domain::APP => KeyDescriptor {
306 domain: key.domain,
307 nspace: ThreadState::get_calling_uid() as i64,
308 alias: key.alias.clone(),
309 blob: None,
310 },
311 _ => key.clone(),
312 };
313
314 // generate_key requires the rebind permission.
315 check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
316
317 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
318 map_km_error(km_dev.addRngEntropy(entropy))?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700319 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700320 let mut key_characteristics: KeyCharacteristics = Default::default();
321 let mut certificate_chain: Vec<KmCertificate> = Default::default();
322 map_km_error(km_dev.generateKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700323 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700324 &mut blob,
325 &mut key_characteristics,
326 &mut certificate_chain,
327 ))?;
328
Janis Danisevskis04b02832020-10-26 09:21:40 -0700329 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
330 .context("In generate_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700331 }
332
333 fn import_key(
334 &self,
335 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700336 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700337 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700338 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700339 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700340 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700341 if key.domain != Domain::BLOB && key.alias.is_none() {
342 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
343 .context("In import_key: Alias must be specified");
344 }
345
346 let key = match key.domain {
347 Domain::APP => KeyDescriptor {
348 domain: key.domain,
349 nspace: ThreadState::get_calling_uid() as i64,
350 alias: key.alias.clone(),
351 blob: None,
352 },
353 _ => key.clone(),
354 };
355
356 // import_key requires the rebind permission.
357 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
358
Janis Danisevskis85d47932020-10-23 16:12:59 -0700359 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700360 let mut key_characteristics: KeyCharacteristics = Default::default();
361 let mut certificate_chain: Vec<KmCertificate> = Default::default();
362
363 let format = params
364 .iter()
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700365 .find(|p| p.tag == Tag::ALGORITHM)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700366 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
367 .context("No KeyParameter 'Algorithm'.")
368 .and_then(|p| match Algorithm(p.integer) {
369 Algorithm::AES | Algorithm::HMAC | Algorithm::TRIPLE_DES => Ok(KeyFormat::RAW),
370 Algorithm::RSA | Algorithm::EC => Ok(KeyFormat::PKCS8),
371 algorithm => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
372 .context(format!("Unknown Algorithm {:?}.", algorithm)),
373 })
374 .context("In import_key.")?;
375
376 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
377 map_km_error(km_dev.importKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700378 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700379 format,
380 key_data,
381 &mut blob,
382 &mut key_characteristics,
383 &mut certificate_chain,
384 ))?;
385
Janis Danisevskis04b02832020-10-26 09:21:40 -0700386 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
387 .context("In import_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700388 }
389
390 fn import_wrapped_key(
391 &self,
392 key: &KeyDescriptor,
393 wrapping_key: &KeyDescriptor,
394 masking_key: Option<&[u8]>,
395 params: &[KeyParameter],
396 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700397 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700398 if key.domain != Domain::BLOB && key.alias.is_none() {
399 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
400 .context("In import_wrapped_key: Alias must be specified.");
401 }
402
Janis Danisevskisaec14592020-11-12 09:41:49 -0800403 if wrapping_key.domain == Domain::BLOB {
404 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
405 "In import_wrapped_key: Import wrapped key not supported for self managed blobs.",
406 );
407 }
408
Janis Danisevskis1af91262020-08-10 14:58:08 -0700409 let wrapped_data = match &key.blob {
410 Some(d) => d,
411 None => {
412 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
413 "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
414 )
415 }
416 };
417
418 let key = match key.domain {
419 Domain::APP => KeyDescriptor {
420 domain: key.domain,
421 nspace: ThreadState::get_calling_uid() as i64,
422 alias: key.alias.clone(),
423 blob: None,
424 },
425 _ => key.clone(),
426 };
427
428 // import_wrapped_key requires the rebind permission for the new key.
429 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
430
Janis Danisevskisaec14592020-11-12 09:41:49 -0800431 let (wrapping_key_id_guard, wrapping_key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700432 .with(|db| {
433 db.borrow_mut().load_key_entry(
434 wrapping_key.clone(),
435 KeyEntryLoadBits::KM,
436 ThreadState::get_calling_uid(),
437 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
438 )
439 })
440 .context("Failed to load wrapping key.")?;
441 let wrapping_key_blob = match wrapping_key_entry.km_blob() {
442 Some(blob) => blob,
443 None => {
444 return Err(error::Error::sys()).context(concat!(
445 "No km_blob after successfully loading key.",
446 " This should never happen."
447 ))
448 }
449 };
450
Janis Danisevskis1af91262020-08-10 14:58:08 -0700451 // km_dev.importWrappedKey does not return a certificate chain.
452 // TODO Do we assume that all wrapped keys are symmetric?
453 // let certificate_chain: Vec<KmCertificate> = Default::default();
454
455 let pw_sid = authenticators
456 .iter()
457 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700458 HardwareAuthenticatorType::PASSWORD => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700459 _ => None,
460 })
461 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
462 .context("A password authenticator SID must be specified.")?;
463
464 let fp_sid = authenticators
465 .iter()
466 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700467 HardwareAuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700468 _ => None,
469 })
470 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
471 .context("A fingerprint authenticator SID must be specified.")?;
472
473 let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
474
475 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
Janis Danisevskisaec14592020-11-12 09:41:49 -0800476 let ((blob, key_characteristics), _) = self.upgrade_keyblob_if_required_with(
477 &*km_dev,
478 Some(wrapping_key_id_guard),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700479 wrapping_key_blob,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800480 &[],
481 |wrapping_blob| {
482 let mut blob: ByteArray = Default::default();
483 let mut key_characteristics: KeyCharacteristics = Default::default();
484 map_km_error(km_dev.importWrappedKey(
485 wrapped_data,
486 wrapping_key_blob,
487 masking_key,
488 &params,
489 pw_sid,
490 fp_sid,
491 &mut blob,
492 &mut key_characteristics,
493 ))?;
494 Ok((blob, key_characteristics))
495 },
496 )?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700497
Janis Danisevskis04b02832020-10-26 09:21:40 -0700498 self.store_new_key(key, key_characteristics, None, blob).context("In import_wrapped_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700499 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800500
501 fn upgrade_keyblob_if_required_with<T, F>(
502 &self,
503 km_dev: &dyn IKeyMintDevice,
504 key_id_guard: Option<KeyIdGuard>,
505 blob: &[u8],
506 params: &[KeyParameter],
507 f: F,
508 ) -> Result<(T, Option<Vec<u8>>)>
509 where
510 F: Fn(&[u8]) -> Result<T, Error>,
511 {
512 match f(blob) {
513 Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
514 let upgraded_blob = map_km_error(km_dev.upgradeKey(blob, params))
515 .context("In upgrade_keyblob_if_required_with: Upgrade failed.")?;
516 key_id_guard.map_or(Ok(()), |key_id_guard| {
517 DB.with(|db| {
518 db.borrow_mut().insert_blob(
519 &key_id_guard,
520 SubComponentType::KM_BLOB,
521 &upgraded_blob,
522 self.security_level,
523 )
524 })
525 .context(concat!(
526 "In upgrade_keyblob_if_required_with: ",
527 "Failed to insert upgraded blob into the database.",
528 ))
529 })?;
530 match f(&upgraded_blob) {
531 Ok(v) => Ok((v, Some(upgraded_blob))),
532 Err(e) => Err(e).context(concat!(
533 "In upgrade_keyblob_if_required_with: ",
534 "Failed to perform operation on second try."
535 )),
536 }
537 }
538 Err(e) => {
539 Err(e).context("In upgrade_keyblob_if_required_with: Failed perform operation.")
540 }
541 Ok(v) => Ok((v, None)),
542 }
543 }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700544}
545
546impl binder::Interface for KeystoreSecurityLevel {}
547
548impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700549 fn createOperation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700550 &self,
551 key: &KeyDescriptor,
552 operation_parameters: &[KeyParameter],
553 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700554 ) -> binder::public_api::Result<CreateOperationResponse> {
555 map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700556 }
557 fn generateKey(
558 &self,
559 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700560 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700561 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700562 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700563 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700564 ) -> binder::public_api::Result<KeyMetadata> {
565 map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700566 }
567 fn importKey(
568 &self,
569 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700570 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700571 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700572 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700573 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700574 ) -> binder::public_api::Result<KeyMetadata> {
575 map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700576 }
577 fn importWrappedKey(
578 &self,
579 key: &KeyDescriptor,
580 wrapping_key: &KeyDescriptor,
581 masking_key: Option<&[u8]>,
582 params: &[KeyParameter],
583 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700584 ) -> binder::public_api::Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700585 map_or_log_err(
586 self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700587 Ok,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700588 )
589 }
590}