blob: a89f309e902224dc38d7a506ecc7ffac219762e5 [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 Danisevskis1af91262020-08-10 14:58:08 -070048use anyhow::{anyhow, Context, Result};
49use 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 Danisevskise04f7a72020-12-15 14:53:21 -080058static KEYMINT_SERVICE_NAME: &str = "android.hardware.security.keymint.IKeyMintDevice";
Janis Danisevskis1af91262020-08-10 14:58:08 -070059
60// Blob of 32 zeroes used as empty masking key.
61static ZERO_BLOB_32: &[u8] = &[0; 32];
62
63impl KeystoreSecurityLevel {
64 /// Creates a new security level instance wrapped in a
65 /// BnKeystoreSecurityLevel proxy object. It also
66 /// calls `IBinder::set_requesting_sid` on the new interface, because
67 /// we need it for checking keystore permissions.
68 pub fn new_native_binder(
69 security_level: SecurityLevel,
70 ) -> Result<impl IKeystoreSecurityLevel + Send> {
71 let service_name = format!("{}/default", KEYMINT_SERVICE_NAME);
72 let keymint: Box<dyn IKeyMintDevice> =
73 binder::get_interface(&service_name).map_err(|e| {
74 anyhow!(format!(
75 "Could not get KeyMint instance: {} failed with error code {:?}",
76 service_name, e
77 ))
78 })?;
79
80 let result = BnKeystoreSecurityLevel::new_binder(Self {
81 security_level,
82 keymint: Asp::new(keymint.as_binder()),
83 operation_db: OperationDb::new(),
84 });
85 result.as_binder().set_requesting_sid(true);
86 Ok(result)
87 }
88
89 fn store_new_key(
90 &self,
91 key: KeyDescriptor,
Janis Danisevskis04b02832020-10-26 09:21:40 -070092 key_characteristics: KeyCharacteristics,
Janis Danisevskis1af91262020-08-10 14:58:08 -070093 km_cert_chain: Option<Vec<KmCertificate>>,
Janis Danisevskis85d47932020-10-23 16:12:59 -070094 blob: ByteArray,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -070095 ) -> Result<KeyMetadata> {
96 let (cert, cert_chain): (Option<Vec<u8>>, Option<Vec<u8>>) = match km_cert_chain {
Janis Danisevskis1af91262020-08-10 14:58:08 -070097 Some(mut chain) => (
98 match chain.len() {
99 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700100 _ => Some(chain.remove(0).encodedCertificate),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700101 },
102 match chain.len() {
103 0 => None,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700104 _ => Some(
105 chain
Janis Danisevskis1af91262020-08-10 14:58:08 -0700106 .iter()
107 .map(|c| c.encodedCertificate.iter())
108 .flatten()
109 .copied()
110 .collect(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700111 ),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700112 },
113 ),
114 None => (None, None),
115 };
116
Janis Danisevskis04b02832020-10-26 09:21:40 -0700117 let key_parameters =
118 key_characteristics_to_internal(key_characteristics, self.security_level);
119
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800120 let creation_date = DateTime::now().context("Trying to make creation time.")?;
121
Janis Danisevskis1af91262020-08-10 14:58:08 -0700122 let key = match key.domain {
123 Domain::BLOB => {
Janis Danisevskis85d47932020-10-23 16:12:59 -0700124 KeyDescriptor { domain: Domain::BLOB, blob: Some(blob.data), ..Default::default() }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700125 }
126 _ => DB
127 .with(|db| {
128 let mut db = db.borrow_mut();
129 let key_id = db
130 .create_key_entry(key.domain, key.nspace)
131 .context("Trying to create a key entry.")?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700132 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800133 &key_id,
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800134 SubComponentType::KEY_BLOB,
Janis Danisevskis85d47932020-10-23 16:12:59 -0700135 &blob.data,
136 self.security_level,
137 )
138 .context("Trying to insert km blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700139 if let Some(c) = &cert {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800140 db.insert_blob(&key_id, SubComponentType::CERT, c, self.security_level)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700141 .context("Trying to insert cert blob.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700142 }
143 if let Some(c) = &cert_chain {
144 db.insert_blob(
Janis Danisevskisaec14592020-11-12 09:41:49 -0800145 &key_id,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700146 SubComponentType::CERT_CHAIN,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700147 c,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700148 self.security_level,
149 )
150 .context("Trying to insert cert chain blob.")?;
151 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800152 db.insert_keyparameter(&key_id, &key_parameters)
Janis Danisevskis04b02832020-10-26 09:21:40 -0700153 .context("Trying to insert key parameters.")?;
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800154 let mut metadata = KeyMetaData::new();
155 metadata.add(KeyMetaEntry::CreationDate(creation_date));
156 db.insert_key_metadata(&key_id, &metadata)
157 .context("Trying to insert key metadata.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700158 match &key.alias {
159 Some(alias) => db
Janis Danisevskisaec14592020-11-12 09:41:49 -0800160 .rebind_alias(&key_id, alias, key.domain, key.nspace)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700161 .context("Failed to rebind alias.")?,
162 None => {
163 return Err(error::Error::sys()).context(
164 "Alias must be specified. (This should have been checked earlier.)",
165 )
166 }
167 }
168 Ok(KeyDescriptor {
169 domain: Domain::KEY_ID,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800170 nspace: key_id.id(),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700171 ..Default::default()
172 })
173 })
174 .context("In store_new_key.")?,
175 };
176
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700177 Ok(KeyMetadata {
178 key,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700179 keySecurityLevel: self.security_level,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700180 certificate: cert,
181 certificateChain: cert_chain,
Janis Danisevskis04b02832020-10-26 09:21:40 -0700182 authorizations: crate::utils::key_parameters_to_authorizations(key_parameters),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800183 modificationTimeMs: creation_date.to_millis_epoch(),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700184 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700185 }
186
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700187 fn create_operation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700188 &self,
189 key: &KeyDescriptor,
190 operation_parameters: &[KeyParameter],
191 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700192 ) -> Result<CreateOperationResponse> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700193 let caller_uid = ThreadState::get_calling_uid();
194 // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
195 // so that we can use it by reference like the blob provided by the key descriptor.
196 // Otherwise, we would have to clone the blob from the key descriptor.
197 let scoping_blob: Vec<u8>;
Janis Danisevskisaec14592020-11-12 09:41:49 -0800198 let (km_blob, key_id_guard) = match key.domain {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700199 Domain::BLOB => {
200 check_key_permission(KeyPerm::use_(), key, &None)
201 .context("In create_operation: checking use permission for Domain::BLOB.")?;
202 (
203 match &key.blob {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700204 Some(blob) => blob,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700205 None => {
206 return Err(Error::sys()).context(concat!(
207 "In create_operation: Key blob must be specified when",
208 " using Domain::BLOB."
209 ))
210 }
211 },
212 None,
213 )
214 }
215 _ => {
Janis Danisevskisaec14592020-11-12 09:41:49 -0800216 let (key_id_guard, mut key_entry) = DB
217 .with::<_, Result<(KeyIdGuard, KeyEntry)>>(|db| {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700218 db.borrow_mut().load_key_entry(
219 key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800220 KeyType::Client,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700221 KeyEntryLoadBits::KM,
222 caller_uid,
223 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
224 )
225 })
226 .context("In create_operation: Failed to load key blob.")?;
227 scoping_blob = match key_entry.take_km_blob() {
228 Some(blob) => blob,
229 None => {
230 return Err(Error::sys()).context(concat!(
231 "In create_operation: Successfully loaded key entry,",
232 " but KM blob was missing."
233 ))
234 }
235 };
Janis Danisevskisaec14592020-11-12 09:41:49 -0800236 (&scoping_blob, Some(key_id_guard))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700237 }
238 };
Janis Danisevskis1af91262020-08-10 14:58:08 -0700239
240 // TODO Authorize begin operation.
241 // Check if we need an authorization token.
242 // Lookup authorization token and request VerificationToken if required.
243
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700244 let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE).map_or(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700245 Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700246 .context("In create_operation: No operation purpose specified."),
Janis Danisevskis398e6be2020-12-17 09:29:25 -0800247 |kp| match kp.value {
248 KeyParameterValue::KeyPurpose(p) => Ok(p),
249 _ => Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
250 .context("In create_operation: Malformed KeyParameter."),
251 },
Janis Danisevskis1af91262020-08-10 14:58:08 -0700252 )?;
253
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700254 let km_dev: Box<dyn IKeyMintDevice> = self
255 .keymint
256 .get_interface()
257 .context("In create_operation: Failed to get KeyMint device")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700258
Janis Danisevskisaec14592020-11-12 09:41:49 -0800259 let (begin_result, upgraded_blob) = self
260 .upgrade_keyblob_if_required_with(
261 &*km_dev,
262 key_id_guard,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700263 &km_blob,
264 &operation_parameters,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800265 |blob| loop {
266 match map_km_error(km_dev.begin(
267 purpose,
268 blob,
269 &operation_parameters,
270 &Default::default(),
271 )) {
272 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
273 self.operation_db.prune(caller_uid)?;
274 continue;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700275 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800276 v => return v,
277 }
278 },
279 )
280 .context("In create_operation: Failed to begin operation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700281
282 let operation = match begin_result.operation {
283 Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700284 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 -0700285 };
286
287 let op_binder: Box<dyn IKeystoreOperation> =
288 KeystoreOperation::new_native_binder(operation)
289 .as_binder()
290 .into_interface()
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700291 .context("In create_operation: Failed to create IKeystoreOperation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700292
293 // TODO we need to the enforcement module to determine if we need to return the challenge.
294 // We return None for now because we don't support auth bound keys yet.
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700295 Ok(CreateOperationResponse {
296 iOperation: Some(op_binder),
297 operationChallenge: None,
298 parameters: match begin_result.params.len() {
299 0 => None,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700300 _ => Some(KeyParameters { keyParameter: begin_result.params }),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700301 },
302 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700303 }
304
305 fn generate_key(
306 &self,
307 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700308 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700309 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700310 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700311 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700312 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700313 if key.domain != Domain::BLOB && key.alias.is_none() {
314 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
315 .context("In generate_key: Alias must be specified");
316 }
317
318 let key = match key.domain {
319 Domain::APP => KeyDescriptor {
320 domain: key.domain,
321 nspace: ThreadState::get_calling_uid() as i64,
322 alias: key.alias.clone(),
323 blob: None,
324 },
325 _ => key.clone(),
326 };
327
328 // generate_key requires the rebind permission.
329 check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
330
331 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
332 map_km_error(km_dev.addRngEntropy(entropy))?;
Janis Danisevskis85d47932020-10-23 16:12:59 -0700333 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700334 let mut key_characteristics: KeyCharacteristics = Default::default();
335 let mut certificate_chain: Vec<KmCertificate> = Default::default();
336 map_km_error(km_dev.generateKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700337 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700338 &mut blob,
339 &mut key_characteristics,
340 &mut certificate_chain,
341 ))?;
342
Janis Danisevskis04b02832020-10-26 09:21:40 -0700343 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
344 .context("In generate_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700345 }
346
347 fn import_key(
348 &self,
349 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700350 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700351 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700352 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700353 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700354 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700355 if key.domain != Domain::BLOB && key.alias.is_none() {
356 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
357 .context("In import_key: Alias must be specified");
358 }
359
360 let key = match key.domain {
361 Domain::APP => KeyDescriptor {
362 domain: key.domain,
363 nspace: ThreadState::get_calling_uid() as i64,
364 alias: key.alias.clone(),
365 blob: None,
366 },
367 _ => key.clone(),
368 };
369
370 // import_key requires the rebind permission.
371 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
372
Janis Danisevskis85d47932020-10-23 16:12:59 -0700373 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700374 let mut key_characteristics: KeyCharacteristics = Default::default();
375 let mut certificate_chain: Vec<KmCertificate> = Default::default();
376
377 let format = params
378 .iter()
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700379 .find(|p| p.tag == Tag::ALGORITHM)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700380 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
381 .context("No KeyParameter 'Algorithm'.")
Janis Danisevskis398e6be2020-12-17 09:29:25 -0800382 .and_then(|p| match &p.value {
383 KeyParameterValue::Algorithm(Algorithm::AES)
384 | KeyParameterValue::Algorithm(Algorithm::HMAC)
385 | KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES) => Ok(KeyFormat::RAW),
386 KeyParameterValue::Algorithm(Algorithm::RSA)
387 | KeyParameterValue::Algorithm(Algorithm::EC) => Ok(KeyFormat::PKCS8),
388 v => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
389 .context(format!("Unknown Algorithm {:?}.", v)),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700390 })
391 .context("In import_key.")?;
392
393 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
394 map_km_error(km_dev.importKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700395 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700396 format,
397 key_data,
398 &mut blob,
399 &mut key_characteristics,
400 &mut certificate_chain,
401 ))?;
402
Janis Danisevskis04b02832020-10-26 09:21:40 -0700403 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
404 .context("In import_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700405 }
406
407 fn import_wrapped_key(
408 &self,
409 key: &KeyDescriptor,
410 wrapping_key: &KeyDescriptor,
411 masking_key: Option<&[u8]>,
412 params: &[KeyParameter],
413 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700414 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700415 if key.domain != Domain::BLOB && key.alias.is_none() {
416 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
417 .context("In import_wrapped_key: Alias must be specified.");
418 }
419
Janis Danisevskisaec14592020-11-12 09:41:49 -0800420 if wrapping_key.domain == Domain::BLOB {
421 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
422 "In import_wrapped_key: Import wrapped key not supported for self managed blobs.",
423 );
424 }
425
Janis Danisevskis1af91262020-08-10 14:58:08 -0700426 let wrapped_data = match &key.blob {
427 Some(d) => d,
428 None => {
429 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
430 "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
431 )
432 }
433 };
434
435 let key = match key.domain {
436 Domain::APP => KeyDescriptor {
437 domain: key.domain,
438 nspace: ThreadState::get_calling_uid() as i64,
439 alias: key.alias.clone(),
440 blob: None,
441 },
442 _ => key.clone(),
443 };
444
445 // import_wrapped_key requires the rebind permission for the new key.
446 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
447
Janis Danisevskisaec14592020-11-12 09:41:49 -0800448 let (wrapping_key_id_guard, wrapping_key_entry) = DB
Janis Danisevskis1af91262020-08-10 14:58:08 -0700449 .with(|db| {
450 db.borrow_mut().load_key_entry(
451 wrapping_key.clone(),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800452 KeyType::Client,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700453 KeyEntryLoadBits::KM,
454 ThreadState::get_calling_uid(),
455 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
456 )
457 })
458 .context("Failed to load wrapping key.")?;
459 let wrapping_key_blob = match wrapping_key_entry.km_blob() {
460 Some(blob) => blob,
461 None => {
462 return Err(error::Error::sys()).context(concat!(
463 "No km_blob after successfully loading key.",
464 " This should never happen."
465 ))
466 }
467 };
468
Janis Danisevskis1af91262020-08-10 14:58:08 -0700469 // km_dev.importWrappedKey does not return a certificate chain.
470 // TODO Do we assume that all wrapped keys are symmetric?
471 // let certificate_chain: Vec<KmCertificate> = Default::default();
472
473 let pw_sid = authenticators
474 .iter()
475 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700476 HardwareAuthenticatorType::PASSWORD => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700477 _ => None,
478 })
479 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
480 .context("A password authenticator SID must be specified.")?;
481
482 let fp_sid = authenticators
483 .iter()
484 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700485 HardwareAuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700486 _ => None,
487 })
488 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
489 .context("A fingerprint authenticator SID must be specified.")?;
490
491 let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
492
493 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
Janis Danisevskisaec14592020-11-12 09:41:49 -0800494 let ((blob, key_characteristics), _) = self.upgrade_keyblob_if_required_with(
495 &*km_dev,
496 Some(wrapping_key_id_guard),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700497 wrapping_key_blob,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800498 &[],
499 |wrapping_blob| {
500 let mut blob: ByteArray = Default::default();
501 let mut key_characteristics: KeyCharacteristics = Default::default();
502 map_km_error(km_dev.importWrappedKey(
503 wrapped_data,
504 wrapping_key_blob,
505 masking_key,
506 &params,
507 pw_sid,
508 fp_sid,
509 &mut blob,
510 &mut key_characteristics,
511 ))?;
512 Ok((blob, key_characteristics))
513 },
514 )?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700515
Janis Danisevskis04b02832020-10-26 09:21:40 -0700516 self.store_new_key(key, key_characteristics, None, blob).context("In import_wrapped_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700517 }
Janis Danisevskisaec14592020-11-12 09:41:49 -0800518
519 fn upgrade_keyblob_if_required_with<T, F>(
520 &self,
521 km_dev: &dyn IKeyMintDevice,
522 key_id_guard: Option<KeyIdGuard>,
523 blob: &[u8],
524 params: &[KeyParameter],
525 f: F,
526 ) -> Result<(T, Option<Vec<u8>>)>
527 where
528 F: Fn(&[u8]) -> Result<T, Error>,
529 {
530 match f(blob) {
531 Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
532 let upgraded_blob = map_km_error(km_dev.upgradeKey(blob, params))
533 .context("In upgrade_keyblob_if_required_with: Upgrade failed.")?;
534 key_id_guard.map_or(Ok(()), |key_id_guard| {
535 DB.with(|db| {
536 db.borrow_mut().insert_blob(
537 &key_id_guard,
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800538 SubComponentType::KEY_BLOB,
Janis Danisevskisaec14592020-11-12 09:41:49 -0800539 &upgraded_blob,
540 self.security_level,
541 )
542 })
543 .context(concat!(
544 "In upgrade_keyblob_if_required_with: ",
545 "Failed to insert upgraded blob into the database.",
546 ))
547 })?;
548 match f(&upgraded_blob) {
549 Ok(v) => Ok((v, Some(upgraded_blob))),
550 Err(e) => Err(e).context(concat!(
551 "In upgrade_keyblob_if_required_with: ",
552 "Failed to perform operation on second try."
553 )),
554 }
555 }
556 Err(e) => {
557 Err(e).context("In upgrade_keyblob_if_required_with: Failed perform operation.")
558 }
559 Ok(v) => Ok((v, None)),
560 }
561 }
Janis Danisevskis1af91262020-08-10 14:58:08 -0700562}
563
564impl binder::Interface for KeystoreSecurityLevel {}
565
566impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700567 fn createOperation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700568 &self,
569 key: &KeyDescriptor,
570 operation_parameters: &[KeyParameter],
571 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700572 ) -> binder::public_api::Result<CreateOperationResponse> {
573 map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700574 }
575 fn generateKey(
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 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700582 ) -> binder::public_api::Result<KeyMetadata> {
583 map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700584 }
585 fn importKey(
586 &self,
587 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700588 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700589 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700590 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700591 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700592 ) -> binder::public_api::Result<KeyMetadata> {
593 map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700594 }
595 fn importWrappedKey(
596 &self,
597 key: &KeyDescriptor,
598 wrapping_key: &KeyDescriptor,
599 masking_key: Option<&[u8]>,
600 params: &[KeyParameter],
601 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700602 ) -> binder::public_api::Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700603 map_or_log_err(
604 self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700605 Ok,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700606 )
607 }
608}