blob: 24b665e6139e97d3adfaaaec69435a7844ddfd5f [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 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::globals::DB;
34use crate::permission::KeyPerm;
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -070035use crate::utils::{check_key_permission, Asp};
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(
128 key_id,
129 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 Danisevskis2c7f9622020-09-30 16:30:31 -0700135 db.insert_blob(key_id, SubComponentType::CERT, c, self.security_level)
136 .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(
140 key_id,
141 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 Danisevskis04b02832020-10-26 09:21:40 -0700147 db.insert_keyparameter(key_id, &key_parameters)
148 .context("Trying to insert key parameters.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700149 match &key.alias {
150 Some(alias) => db
151 .rebind_alias(key_id, alias, key.domain, key.nspace)
152 .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,
161 nspace: key_id,
162 ..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 Danisevskis2c7f9622020-09-30 16:30:31 -0700189 let (km_blob, key_id) = match key.domain {
190 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 _ => {
207 let mut key_entry = DB
208 .with::<_, Result<KeyEntry>>(|db| {
209 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 };
226 (&scoping_blob, Some(key_entry.id()))
227 }
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
245 let (begin_result, upgraded_blob) = loop {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700246 match map_km_error(km_dev.begin(
247 purpose,
248 &km_blob,
249 &operation_parameters,
250 &Default::default(),
251 )) {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700252 Ok(result) => break (result, None),
253 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700254 self.operation_db
255 .prune(caller_uid)
256 .context("In create_operation: Outer loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700257 continue;
258 }
259 Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700260 let upgraded_blob =
261 map_km_error(km_dev.upgradeKey(&km_blob, &operation_parameters))
262 .context("In create_operation: Upgrade failed.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700263 break loop {
264 match map_km_error(km_dev.begin(
265 purpose,
266 &upgraded_blob,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700267 &operation_parameters,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700268 &Default::default(),
269 )) {
270 Ok(result) => break (result, Some(upgraded_blob)),
271 // If Keystore 2.0 is multi threaded another request may have
272 // snatched up our previously pruned operation slot. So we might
273 // need to prune again.
274 Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
275 self.operation_db
276 .prune(caller_uid)
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700277 .context("In create_operation: Inner loop.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700278 continue;
279 }
280 Err(e) => {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700281 return Err(e).context(
282 "In create_operation: Begin operation failed after upgrade.",
283 )
Janis Danisevskis1af91262020-08-10 14:58:08 -0700284 }
285 }
286 };
287 }
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700288 Err(e) => return Err(e).context("In create_operation: Begin operation failed."),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700289 };
290 };
291
292 if let Some(upgraded_blob) = upgraded_blob {
293 if let Some(key_id) = key_id {
294 DB.with(|db| {
295 db.borrow_mut().insert_blob(
296 key_id,
297 SubComponentType::KM_BLOB,
298 &upgraded_blob,
299 self.security_level,
300 )
301 })
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700302 .context(
303 "In create_operation: Failed to insert upgraded blob into the database.",
304 )?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700305 }
306 }
307
308 let operation = match begin_result.operation {
309 Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700310 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 -0700311 };
312
313 let op_binder: Box<dyn IKeystoreOperation> =
314 KeystoreOperation::new_native_binder(operation)
315 .as_binder()
316 .into_interface()
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700317 .context("In create_operation: Failed to create IKeystoreOperation.")?;
Janis Danisevskis1af91262020-08-10 14:58:08 -0700318
319 // TODO we need to the enforcement module to determine if we need to return the challenge.
320 // We return None for now because we don't support auth bound keys yet.
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700321 Ok(CreateOperationResponse {
322 iOperation: Some(op_binder),
323 operationChallenge: None,
324 parameters: match begin_result.params.len() {
325 0 => None,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700326 _ => Some(KeyParameters { keyParameter: begin_result.params }),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700327 },
328 })
Janis Danisevskis1af91262020-08-10 14:58:08 -0700329 }
330
331 fn generate_key(
332 &self,
333 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700334 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700335 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700336 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700337 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700338 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700339 if key.domain != Domain::BLOB && key.alias.is_none() {
340 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
341 .context("In generate_key: Alias must be specified");
342 }
343
344 let key = match key.domain {
345 Domain::APP => KeyDescriptor {
346 domain: key.domain,
347 nspace: ThreadState::get_calling_uid() as i64,
348 alias: key.alias.clone(),
349 blob: None,
350 },
351 _ => key.clone(),
352 };
353
354 // generate_key requires the rebind permission.
355 check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
356
357 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
358 map_km_error(km_dev.addRngEntropy(entropy))?;
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 map_km_error(km_dev.generateKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700363 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700364 &mut blob,
365 &mut key_characteristics,
366 &mut certificate_chain,
367 ))?;
368
Janis Danisevskis04b02832020-10-26 09:21:40 -0700369 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
370 .context("In generate_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700371 }
372
373 fn import_key(
374 &self,
375 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700376 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700377 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700378 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700379 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700380 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700381 if key.domain != Domain::BLOB && key.alias.is_none() {
382 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
383 .context("In import_key: Alias must be specified");
384 }
385
386 let key = match key.domain {
387 Domain::APP => KeyDescriptor {
388 domain: key.domain,
389 nspace: ThreadState::get_calling_uid() as i64,
390 alias: key.alias.clone(),
391 blob: None,
392 },
393 _ => key.clone(),
394 };
395
396 // import_key requires the rebind permission.
397 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
398
Janis Danisevskis85d47932020-10-23 16:12:59 -0700399 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700400 let mut key_characteristics: KeyCharacteristics = Default::default();
401 let mut certificate_chain: Vec<KmCertificate> = Default::default();
402
403 let format = params
404 .iter()
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700405 .find(|p| p.tag == Tag::ALGORITHM)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700406 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
407 .context("No KeyParameter 'Algorithm'.")
408 .and_then(|p| match Algorithm(p.integer) {
409 Algorithm::AES | Algorithm::HMAC | Algorithm::TRIPLE_DES => Ok(KeyFormat::RAW),
410 Algorithm::RSA | Algorithm::EC => Ok(KeyFormat::PKCS8),
411 algorithm => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
412 .context(format!("Unknown Algorithm {:?}.", algorithm)),
413 })
414 .context("In import_key.")?;
415
416 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
417 map_km_error(km_dev.importKey(
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700418 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700419 format,
420 key_data,
421 &mut blob,
422 &mut key_characteristics,
423 &mut certificate_chain,
424 ))?;
425
Janis Danisevskis04b02832020-10-26 09:21:40 -0700426 self.store_new_key(key, key_characteristics, Some(certificate_chain), blob)
427 .context("In import_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700428 }
429
430 fn import_wrapped_key(
431 &self,
432 key: &KeyDescriptor,
433 wrapping_key: &KeyDescriptor,
434 masking_key: Option<&[u8]>,
435 params: &[KeyParameter],
436 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700437 ) -> Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700438 if key.domain != Domain::BLOB && key.alias.is_none() {
439 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
440 .context("In import_wrapped_key: Alias must be specified.");
441 }
442
443 let wrapped_data = match &key.blob {
444 Some(d) => d,
445 None => {
446 return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
447 "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
448 )
449 }
450 };
451
452 let key = match key.domain {
453 Domain::APP => KeyDescriptor {
454 domain: key.domain,
455 nspace: ThreadState::get_calling_uid() as i64,
456 alias: key.alias.clone(),
457 blob: None,
458 },
459 _ => key.clone(),
460 };
461
462 // import_wrapped_key requires the rebind permission for the new key.
463 check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
464
465 let wrapping_key_entry = DB
466 .with(|db| {
467 db.borrow_mut().load_key_entry(
468 wrapping_key.clone(),
469 KeyEntryLoadBits::KM,
470 ThreadState::get_calling_uid(),
471 |k, av| check_key_permission(KeyPerm::use_(), k, &av),
472 )
473 })
474 .context("Failed to load wrapping key.")?;
475 let wrapping_key_blob = match wrapping_key_entry.km_blob() {
476 Some(blob) => blob,
477 None => {
478 return Err(error::Error::sys()).context(concat!(
479 "No km_blob after successfully loading key.",
480 " This should never happen."
481 ))
482 }
483 };
484
Janis Danisevskis85d47932020-10-23 16:12:59 -0700485 let mut blob: ByteArray = Default::default();
Janis Danisevskis1af91262020-08-10 14:58:08 -0700486 let mut key_characteristics: KeyCharacteristics = Default::default();
487 // km_dev.importWrappedKey does not return a certificate chain.
488 // TODO Do we assume that all wrapped keys are symmetric?
489 // let certificate_chain: Vec<KmCertificate> = Default::default();
490
491 let pw_sid = authenticators
492 .iter()
493 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700494 HardwareAuthenticatorType::PASSWORD => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700495 _ => None,
496 })
497 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
498 .context("A password authenticator SID must be specified.")?;
499
500 let fp_sid = authenticators
501 .iter()
502 .find_map(|a| match a.authenticatorType {
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700503 HardwareAuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
Janis Danisevskis1af91262020-08-10 14:58:08 -0700504 _ => None,
505 })
506 .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
507 .context("A fingerprint authenticator SID must be specified.")?;
508
509 let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
510
511 let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
512 map_km_error(km_dev.importWrappedKey(
513 wrapped_data,
514 wrapping_key_blob,
515 masking_key,
Janis Danisevskisa53c9cf2020-10-26 11:52:33 -0700516 &params,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700517 pw_sid,
518 fp_sid,
519 &mut blob,
520 &mut key_characteristics,
521 ))?;
522
Janis Danisevskis04b02832020-10-26 09:21:40 -0700523 self.store_new_key(key, key_characteristics, None, blob).context("In import_wrapped_key.")
Janis Danisevskis1af91262020-08-10 14:58:08 -0700524 }
525}
526
527impl binder::Interface for KeystoreSecurityLevel {}
528
529impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700530 fn createOperation(
Janis Danisevskis1af91262020-08-10 14:58:08 -0700531 &self,
532 key: &KeyDescriptor,
533 operation_parameters: &[KeyParameter],
534 forced: bool,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700535 ) -> binder::public_api::Result<CreateOperationResponse> {
536 map_or_log_err(self.create_operation(key, operation_parameters, forced), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700537 }
538 fn generateKey(
539 &self,
540 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700541 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700542 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700543 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700544 entropy: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700545 ) -> binder::public_api::Result<KeyMetadata> {
546 map_or_log_err(self.generate_key(key, attestation_key, params, flags, entropy), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700547 }
548 fn importKey(
549 &self,
550 key: &KeyDescriptor,
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700551 attestation_key: Option<&KeyDescriptor>,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700552 params: &[KeyParameter],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700553 flags: i32,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700554 key_data: &[u8],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700555 ) -> binder::public_api::Result<KeyMetadata> {
556 map_or_log_err(self.import_key(key, attestation_key, params, flags, key_data), Ok)
Janis Danisevskis1af91262020-08-10 14:58:08 -0700557 }
558 fn importWrappedKey(
559 &self,
560 key: &KeyDescriptor,
561 wrapping_key: &KeyDescriptor,
562 masking_key: Option<&[u8]>,
563 params: &[KeyParameter],
564 authenticators: &[AuthenticatorSpec],
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700565 ) -> binder::public_api::Result<KeyMetadata> {
Janis Danisevskis1af91262020-08-10 14:58:08 -0700566 map_or_log_err(
567 self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
Janis Danisevskis2c7f9622020-09-30 16:30:31 -0700568 Ok,
Janis Danisevskis1af91262020-08-10 14:58:08 -0700569 )
570 }
571}