blob: 29bb9b2c4399ae5133b0ea25a8632d316d1fdeae [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,
Janis Danisevskis398e6be2020-12-17 09:29:25 -080023 KeyParameterValue::KeyParameterValue, 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 Danisevskisa53c9cf2020-10-26 11:52:33 -070033use crate::utils::{check_key_permission, Asp};
Janis Danisevskisaec14592020-11-12 09:41:49 -080034use crate::{database::KeyIdGuard, globals::DB};
Janis Danisevskis1af91262020-08-10 14:58:08 -070035use crate::{
Janis Danisevskisb42fc182020-12-15 08:41:27 -080036 database::{DateTime, KeyMetaData, KeyMetaEntry, KeyType},
37 permission::KeyPerm,
38};
39use crate::{
Janis Danisevskis1af91262020-08-10 14:58:08 -070040 database::{KeyEntry, KeyEntryLoadBits, SubComponentType},
41 operation::KeystoreOperation,
42 operation::OperationDb,
43};
Janis Danisevskis04b02832020-10-26 09:21:40 -070044use crate::{
45 error::{self, map_km_error, map_or_log_err, Error, ErrorCode},
46 utils::key_characteristics_to_internal,
47};
Janis Danisevskisba998992020-12-29 16:08:40 -080048use anyhow::{Context, Result};
Janis Danisevskis1af91262020-08-10 14:58:08 -070049use binder::{IBinder, Interface, ThreadState};
50
51/// Implementation of the IKeystoreSecurityLevel Interface.
52pub struct KeystoreSecurityLevel {
53 security_level: SecurityLevel,
54 keymint: Asp,
55 operation_db: OperationDb,
56}
57
Janis Danisevskis1af91262020-08-10 14:58:08 -070058// 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> {
Janis Danisevskis1af91262020-08-10 14:58:08 -070069 let result = BnKeystoreSecurityLevel::new_binder(Self {
70 security_level,
Janis Danisevskisba998992020-12-29 16:08:40 -080071 keymint: crate::globals::get_keymint_device(security_level)
72 .context("In KeystoreSecurityLevel::new_native_binder.")?,
Janis Danisevskis1af91262020-08-10 14:58:08 -070073 operation_db: OperationDb::new(),
74 });
75 result.as_binder().set_requesting_sid(true);
76 Ok(result)
77 }
78
79 fn store_new_key(
80 &self,
81 key: KeyDescriptor,
Janis Danisevskis04b02832020-10-26 09:21:40 -070082 key_characteristics: KeyCharacteristics,
Janis Danisevskis1af91262020-08-10 14:58:08 -070083 km_cert_chain: Option<Vec<KmCertificate>>,
Janis Danisevskis85d47932020-10-23 16:12:59 -070084 blob: ByteArray,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070085 ) -> Result<KeyMetadata> {
86 let (cert, cert_chain): (Option<Vec<u8>>, Option<Vec<u8>>) = match km_cert_chain {
Janis Danisevskis1af91262020-08-10 14:58:08 -070087 Some(mut chain) => (
88 match chain.len() {
89 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070090 _ => Some(chain.remove(0).encodedCertificate),
Janis Danisevskis1af91262020-08-10 14:58:08 -070091 },
92 match chain.len() {
93 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070094 _ => Some(
95 chain
Janis Danisevskis1af91262020-08-10 14:58:08 -070096 .iter()
97 .map(|c| c.encodedCertificate.iter())
98 .flatten()
99 .copied()
100 .collect(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700101 ),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700102 },
103 ),
104 None => (None, None),
105 };
106
Janis Danisevskis04b02832020-10-26 09:21:40 -0700107 let key_parameters =
108 key_characteristics_to_internal(key_characteristics, self.security_level);
109
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800110 let creation_date = DateTime::now().context("Trying to make creation time.")?;
111
Janis Danisevskis1af91262020-08-10 14:58:08 -0700112 let key = match key.domain {
113 Domain::BLOB => {
Janis Danisevskis85d47932020-10-23 16:12:59 -0700114 KeyDescriptor { domain: Domain::BLOB, blob: Some(blob.data), ..Default::default() }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700115 }
116 _ => DB
117 .with(|db| {
118 let mut db = db.borrow_mut();
119 let key_id = db
120 .create_key_entry(key.domain, key.nspace)
121 .context("Trying to create a key entry.")?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700122 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800123 &key_id,
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800124 SubComponentType::KEY_BLOB,
Janis Danisevskis85d47932020-10-23 16:12:59 -0700125 &blob.data,
126 self.security_level,
127 )
128 .context("Trying to insert km blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700129 if let Some(c) = &cert {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800130 db.insert_blob(&key_id, SubComponentType::CERT, c, self.security_level)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700131 .context("Trying to insert cert blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700132 }
133 if let Some(c) = &cert_chain {
134 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800135 &key_id,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700136 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700137 c,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700138 self.security_level,
139 )
140 .context("Trying to insert cert chain blob.")?;
141 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800142 db.insert_keyparameter(&key_id, &key_parameters)
Janis Danisevskis04b02832020-10-26 09:21:40 -0700143 .context("Trying to insert key parameters.")?;
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800144 let mut metadata = KeyMetaData::new();
145 metadata.add(KeyMetaEntry::CreationDate(creation_date));
146 db.insert_key_metadata(&key_id, &metadata)
147 .context("Trying to insert key metadata.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700148 match &key.alias {
149 Some(alias) => db
Janis Danisevskisaec14592020-11-12 09:41:49 -0800150 .rebind_alias(&key_id, alias, key.domain, key.nspace)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700151 .context("Failed to rebind alias.")?,
152 None => {
153 return Err(error::Error::sys()).context(
154 "Alias must be specified. (This should have been checked earlier.)",
155 )
156 }
157 }
158 Ok(KeyDescriptor {
159 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800160 nspace: key_id.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700161 ..Default::default()
162 })
163 })
164 .context("In store_new_key.")?,
165 };
166
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700167 Ok(KeyMetadata {
168 key,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700169 keySecurityLevel: self.security_level,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700170 certificate: cert,
171 certificateChain: cert_chain,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700172 authorizations: crate::utils::key_parameters_to_authorizations(key_parameters),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800173 modificationTimeMs: creation_date.to_millis_epoch(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700174 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700175 }
176
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700177 fn create_operation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700178 &self,
179 key: &KeyDescriptor,
180 operation_parameters: &[KeyParameter],
181 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700182 ) -> Result<CreateOperationResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700183 let caller_uid = ThreadState::get_calling_uid();
184 // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
185 // so that we can use it by reference like the blob provided by the key descriptor.
186 // Otherwise, we would have to clone the blob from the key descriptor.
187 let scoping_blob: Vec<u8>;
Janis Danisevskisaec14592020-11-12 09:41:49 -0800188 let (km_blob, key_id_guard) = match key.domain {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700189 Domain::BLOB => {
190 check_key_permission(KeyPerm::use_(), key, &None)
191 .context("In create_operation: checking use permission for Domain::BLOB.")?;
192 (
193 match &key.blob {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700194 Some(blob) => blob,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700195 None => {
196 return Err(Error::sys()).context(concat!(
197 "In create_operation: Key blob must be specified when",
198 " using Domain::BLOB."
199 ))
200 }
201 },
202 None,
203 )
204 }
205 _ => {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800206 let (key_id_guard, mut key_entry) = DB
207 .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700208 db.borrow_mut().load_key_entry(
209 key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800210 KeyType::Client,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700211 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 Danisevskis398e6be2020-12-17 09:29:25 -0800237 |kp| match kp.value {
238 KeyParameterValue::KeyPurpose(p) => Ok(p),
239 _ => Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
240 .context("In create_operation: Malformed KeyParameter."),
241 },
Janis Danisevskis1af91262020-08-10 14:58:08 -0700242 )?;
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
Janis Danisevskisaec14592020-11-12 09:41:49 -0800249 let (begin_result, upgraded_blob) = self
250 .upgrade_keyblob_if_required_with(
251 &*km_dev,
252 key_id_guard,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700253 &km_blob,
254 &operation_parameters,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800255 |blob| loop {
256 match map_km_error(km_dev.begin(
257 purpose,
258 blob,
259 &operation_parameters,
260 &Default::default(),
261 )) {
262 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
263 self.operation_db.prune(caller_uid)?;
264 continue;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700265 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800266 v => return v,
267 }
268 },
269 )
270 .context("In create_operation: Failed to begin operation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700271
272 let operation = match begin_result.operation {
273 Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700274 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 -0700275 };
276
277 let op_binder: Box<dyn IKeystoreOperation> =
278 KeystoreOperation::new_native_binder(operation)
279 .as_binder()
280 .into_interface()
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700281 .context("In create_operation: Failed to create IKeystoreOperation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700282
283 // TODO we need to the enforcement module to determine if we need to return the challenge.
284 // We return None for now because we don't support auth bound keys yet.
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700285 Ok(CreateOperationResponse {
286 iOperation: Some(op_binder),
287 operationChallenge: None,
288 parameters: match begin_result.params.len() {
289 0 => None,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700290 _ => Some(KeyParameters { keyParameter: begin_result.params }),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700291 },
292 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700293 }
294
295 fn generate_key(
296 &self,
297 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700298 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700299 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700300 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700301 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700302 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700303 if key.domain != Domain::BLOB && key.alias.is_none() {
304 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
305 .context("In generate_key: Alias must be specified");
306 }
307
308 let key = match key.domain {
309 Domain::APP => KeyDescriptor {
310 domain: key.domain,
311 nspace: ThreadState::get_calling_uid() as i64,
312 alias: key.alias.clone(),
313 blob: None,
314 },
315 _ => key.clone(),
316 };
317
318 // generate_key requires the rebind permission.
319 check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
320
321 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
322 map_km_error(km_dev.addRngEntropy(entropy))?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700323 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700324 let mut key_characteristics: KeyCharacteristics = Default::default();
325 let mut certificate_chain: Vec<KmCertificate> = Default::default();
326 map_km_error(km_dev.generateKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700327 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700328 &mut blob,
329 &mut key_characteristics,
330 &mut certificate_chain,
331 ))?;
332
Janis Danisevskis04b02832020-10-26 09:21:40 -0700333 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
334 .context("In generate_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700335 }
336
337 fn import_key(
338 &self,
339 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700340 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700341 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700342 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700343 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700344 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700345 if key.domain != Domain::BLOB && key.alias.is_none() {
346 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
347 .context("In import_key: Alias must be specified");
348 }
349
350 let key = match key.domain {
351 Domain::APP => KeyDescriptor {
352 domain: key.domain,
353 nspace: ThreadState::get_calling_uid() as i64,
354 alias: key.alias.clone(),
355 blob: None,
356 },
357 _ => key.clone(),
358 };
359
360 // import_key requires the rebind permission.
361 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
362
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
367 let format = params
368 .iter()
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700369 .find(|p| p.tag == Tag::ALGORITHM)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700370 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
371 .context("No KeyParameter 'Algorithm'.")
Janis Danisevskis398e6be2020-12-17 09:29:25 -0800372 .and_then(|p| match &p.value {
373 KeyParameterValue::Algorithm(Algorithm::AES)
374 | KeyParameterValue::Algorithm(Algorithm::HMAC)
375 | KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES) => Ok(KeyFormat::RAW),
376 KeyParameterValue::Algorithm(Algorithm::RSA)
377 | KeyParameterValue::Algorithm(Algorithm::EC) => Ok(KeyFormat::PKCS8),
378 v => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
379 .context(format!("Unknown Algorithm {:?}.", v)),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700380 })
381 .context("In import_key.")?;
382
383 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
384 map_km_error(km_dev.importKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700385 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700386 format,
387 key_data,
388 &mut blob,
389 &mut key_characteristics,
390 &mut certificate_chain,
391 ))?;
392
Janis Danisevskis04b02832020-10-26 09:21:40 -0700393 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
394 .context("In import_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700395 }
396
397 fn import_wrapped_key(
398 &self,
399 key: &KeyDescriptor,
400 wrapping_key: &KeyDescriptor,
401 masking_key: Option<&[u8]>,
402 params: &[KeyParameter],
403 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700404 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700405 if key.domain != Domain::BLOB && key.alias.is_none() {
406 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
407 .context("In import_wrapped_key: Alias must be specified.");
408 }
409
Janis Danisevskisaec14592020-11-12 09:41:49 -0800410 if wrapping_key.domain == Domain::BLOB {
411 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
412 "In import_wrapped_key: Import wrapped key not supported for self managed blobs.",
413 );
414 }
415
Janis Danisevskis1af91262020-08-10 14:58:08 -0700416 let wrapped_data = match &key.blob {
417 Some(d) => d,
418 None => {
419 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
420 "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
421 )
422 }
423 };
424
425 let key = match key.domain {
426 Domain::APP => KeyDescriptor {
427 domain: key.domain,
428 nspace: ThreadState::get_calling_uid() as i64,
429 alias: key.alias.clone(),
430 blob: None,
431 },
432 _ => key.clone(),
433 };
434
435 // import_wrapped_key requires the rebind permission for the new key.
436 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
437
Janis Danisevskisaec14592020-11-12 09:41:49 -0800438 let (wrapping_key_id_guard, wrapping_key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700439 .with(|db| {
440 db.borrow_mut().load_key_entry(
441 wrapping_key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800442 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700443 KeyEntryLoadBits::KM,
444 ThreadState::get_calling_uid(),
445 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
446 )
447 })
448 .context("Failed to load wrapping key.")?;
449 let wrapping_key_blob = match wrapping_key_entry.km_blob() {
450 Some(blob) => blob,
451 None => {
452 return Err(error::Error::sys()).context(concat!(
453 "No km_blob after successfully loading key.",
454 " This should never happen."
455 ))
456 }
457 };
458
Janis Danisevskis1af91262020-08-10 14:58:08 -0700459 // km_dev.importWrappedKey does not return a certificate chain.
460 // TODO Do we assume that all wrapped keys are symmetric?
461 // let certificate_chain: Vec<KmCertificate> = Default::default();
462
463 let pw_sid = authenticators
464 .iter()
465 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700466 HardwareAuthenticatorType::PASSWORD => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700467 _ => None,
468 })
469 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
470 .context("A password authenticator SID must be specified.")?;
471
472 let fp_sid = authenticators
473 .iter()
474 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700475 HardwareAuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700476 _ => None,
477 })
478 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
479 .context("A fingerprint authenticator SID must be specified.")?;
480
481 let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
482
483 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
Janis Danisevskisaec14592020-11-12 09:41:49 -0800484 let ((blob, key_characteristics), _) = self.upgrade_keyblob_if_required_with(
485 &*km_dev,
486 Some(wrapping_key_id_guard),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700487 wrapping_key_blob,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800488 &[],
489 |wrapping_blob| {
490 let mut blob: ByteArray = Default::default();
491 let mut key_characteristics: KeyCharacteristics = Default::default();
492 map_km_error(km_dev.importWrappedKey(
493 wrapped_data,
494 wrapping_key_blob,
495 masking_key,
496 &params,
497 pw_sid,
498 fp_sid,
499 &mut blob,
500 &mut key_characteristics,
501 ))?;
502 Ok((blob, key_characteristics))
503 },
504 )?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700505
Janis Danisevskis04b02832020-10-26 09:21:40 -0700506 self.store_new_key(key, key_characteristics, None, blob).context("In import_wrapped_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700507 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800508
509 fn upgrade_keyblob_if_required_with<T, F>(
510 &self,
511 km_dev: &dyn IKeyMintDevice,
512 key_id_guard: Option<KeyIdGuard>,
513 blob: &[u8],
514 params: &[KeyParameter],
515 f: F,
516 ) -> Result<(T, Option<Vec<u8>>)>
517 where
518 F: Fn(&[u8]) -> Result<T, Error>,
519 {
520 match f(blob) {
521 Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
522 let upgraded_blob = map_km_error(km_dev.upgradeKey(blob, params))
523 .context("In upgrade_keyblob_if_required_with: Upgrade failed.")?;
524 key_id_guard.map_or(Ok(()), |key_id_guard| {
525 DB.with(|db| {
526 db.borrow_mut().insert_blob(
527 &key_id_guard,
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800528 SubComponentType::KEY_BLOB,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800529 &upgraded_blob,
530 self.security_level,
531 )
532 })
533 .context(concat!(
534 "In upgrade_keyblob_if_required_with: ",
535 "Failed to insert upgraded blob into the database.",
536 ))
537 })?;
538 match f(&upgraded_blob) {
539 Ok(v) => Ok((v, Some(upgraded_blob))),
540 Err(e) => Err(e).context(concat!(
541 "In upgrade_keyblob_if_required_with: ",
542 "Failed to perform operation on second try."
543 )),
544 }
545 }
546 Err(e) => {
547 Err(e).context("In upgrade_keyblob_if_required_with: Failed perform operation.")
548 }
549 Ok(v) => Ok((v, None)),
550 }
551 }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700552}
553
554impl binder::Interface for KeystoreSecurityLevel {}
555
556impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700557 fn createOperation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700558 &self,
559 key: &KeyDescriptor,
560 operation_parameters: &[KeyParameter],
561 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700562 ) -> binder::public_api::Result<CreateOperationResponse> {
563 map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700564 }
565 fn generateKey(
566 &self,
567 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700568 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700569 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700570 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700571 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700572 ) -> binder::public_api::Result<KeyMetadata> {
573 map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700574 }
575 fn importKey(
576 &self,
577 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700578 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700579 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700580 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700581 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700582 ) -> binder::public_api::Result<KeyMetadata> {
583 map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700584 }
585 fn importWrappedKey(
586 &self,
587 key: &KeyDescriptor,
588 wrapping_key: &KeyDescriptor,
589 masking_key: Option<&[u8]>,
590 params: &[KeyParameter],
591 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700592 ) -> binder::public_api::Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700593 map_or_log_err(
594 self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700595 Ok,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700596 )
597 }
598}