• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! TA functionality related to key generation/import/upgrade.
2 
3 use crate::{cert, device, AttestationChainInfo};
4 use alloc::collections::btree_map::Entry;
5 use alloc::vec::Vec;
6 use core::{borrow::Borrow, cmp::Ordering, convert::TryFrom};
7 use der::{Decode, Sequence};
8 use kmr_common::{
9     crypto::{self, aes, rsa, KeyMaterial, OpaqueOr},
10     get_bool_tag_value, get_opt_tag_value, get_tag_value, keyblob, km_err, tag, try_to_vec,
11     vec_try_with_capacity, Error, FallibleAllocExt,
12 };
13 use kmr_wire::{
14     keymint::{
15         AttestationKey, Digest, EcCurve, ErrorCode, HardwareAuthenticatorType, KeyCharacteristics,
16         KeyCreationResult, KeyFormat, KeyOrigin, KeyParam, KeyPurpose, SecurityLevel,
17     },
18     *,
19 };
20 use log::{error, warn};
21 use spki::SubjectPublicKeyInfo;
22 use x509_cert::ext::pkix::KeyUsages;
23 
24 /// Maximum size of an attestation challenge value.
25 const MAX_ATTESTATION_CHALLENGE_LEN: usize = 128;
26 
27 /// Contents of wrapping key data
28 ///
29 /// ```asn1
30 /// SecureKeyWrapper ::= SEQUENCE {
31 ///     version                   INTEGER, # Value 0
32 ///     encryptedTransportKey     OCTET_STRING,
33 ///     initializationVector      OCTET_STRING,
34 ///     keyDescription            KeyDescription, # See below
35 ///     encryptedKey              OCTET_STRING,
36 ///     tag                       OCTET_STRING,
37 /// }
38 /// ```
39 #[derive(Debug, Clone, Sequence)]
40 pub struct SecureKeyWrapper<'a> {
41     pub version: i32,
42     #[asn1(type = "OCTET STRING")]
43     pub encrypted_transport_key: &'a [u8],
44     #[asn1(type = "OCTET STRING")]
45     pub initialization_vector: &'a [u8],
46     pub key_description: KeyDescription<'a>,
47     #[asn1(type = "OCTET STRING")]
48     pub encrypted_key: &'a [u8],
49     #[asn1(type = "OCTET STRING")]
50     pub tag: &'a [u8],
51 }
52 
53 const SECURE_KEY_WRAPPER_VERSION: i32 = 0;
54 
55 /// Contents of key description.
56 ///
57 /// ``asn1
58 /// KeyDescription ::= SEQUENCE {
59 ///     keyFormat    INTEGER, # Values from KeyFormat enum
60 ///     keyParams    AuthorizationList, # See cert.rs
61 /// }
62 /// ```
63 #[derive(Debug, Clone, Sequence)]
64 pub struct KeyDescription<'a> {
65     pub key_format: i32,
66     pub key_params: cert::AuthorizationList<'a>,
67 }
68 
69 /// Indication of whether key import has a secure wrapper.
70 #[derive(Debug, Clone, Copy)]
71 pub(crate) enum KeyImport {
72     Wrapped,
73     NonWrapped,
74 }
75 
76 /// Combined information needed for signing a fresh public key.
77 #[derive(Clone)]
78 pub(crate) struct SigningInfo<'a> {
79     pub attestation_info: Option<(&'a [u8], &'a [u8])>, // (challenge, app_id)
80     pub signing_key: KeyMaterial,
81     /// ASN.1 DER encoding of subject field from first cert.
82     pub issuer_subject: Vec<u8>,
83     /// Cert chain starting with public key for `signing_key`.
84     pub chain: Vec<keymint::Certificate>,
85 }
86 
87 impl<'a> crate::KeyMintTa<'a> {
88     /// Retrieve the signing information.
get_signing_info( &self, key_type: device::SigningKeyType, ) -> Result<SigningInfo<'a>, Error>89     pub(crate) fn get_signing_info(
90         &self,
91         key_type: device::SigningKeyType,
92     ) -> Result<SigningInfo<'a>, Error> {
93         // Retrieve the chain and issuer information, which is cached after first retrieval.
94         let mut attestation_chain_info = self.attestation_chain_info.borrow_mut();
95         let chain_info = match attestation_chain_info.entry(key_type) {
96             Entry::Occupied(e) => e.into_mut(),
97             Entry::Vacant(e) => {
98                 // Retrieve and store the cert chain information (as this is public).
99                 let chain = self.dev.sign_info.cert_chain(key_type)?;
100                 let issuer = cert::extract_subject(
101                     chain.get(0).ok_or_else(|| km_err!(UnknownError, "empty attestation chain"))?,
102                 )?;
103                 e.insert(AttestationChainInfo { chain, issuer })
104             }
105         };
106 
107         // Retrieve the signing key information (which will be dropped when signing is done).
108         let signing_key = self.dev.sign_info.signing_key(key_type)?;
109         Ok(SigningInfo {
110             attestation_info: None,
111             signing_key,
112             issuer_subject: chain_info.issuer.clone(),
113             chain: chain_info.chain.clone(),
114         })
115     }
116 
117     /// Generate an X.509 leaf certificate.
generate_cert( &self, info: Option<SigningInfo>, spki: SubjectPublicKeyInfo, params: &[KeyParam], chars: &[KeyCharacteristics], ) -> Result<keymint::Certificate, Error>118     pub(crate) fn generate_cert(
119         &self,
120         info: Option<SigningInfo>,
121         spki: SubjectPublicKeyInfo,
122         params: &[KeyParam],
123         chars: &[KeyCharacteristics],
124     ) -> Result<keymint::Certificate, Error> {
125         // Build and encode key usage extension value
126         let key_usage_ext_bits = cert::key_usage_extension_bits(params);
127         let key_usage_ext_val = cert::asn1_der_encode(&key_usage_ext_bits)?;
128 
129         // Build and encode basic constraints extension value, based on the key usage extension
130         // value
131         let basic_constraints_ext_val =
132             if (key_usage_ext_bits.0 & KeyUsages::KeyCertSign).bits().count_ones() != 0 {
133                 let basic_constraints = cert::basic_constraints_ext_value(true);
134                 Some(cert::asn1_der_encode(&basic_constraints)?)
135             } else {
136                 None
137             };
138 
139         // Build and encode attestation extension if present
140         let id_info = self.get_attestation_ids();
141         let attest_ext_val =
142             if let Some(SigningInfo { attestation_info: Some((challenge, app_id)), .. }) = &info {
143                 let unique_id = self.calculate_unique_id(app_id, params)?;
144                 let attest_ext = cert::attestation_extension(
145                     challenge,
146                     app_id,
147                     self.hw_info.security_level,
148                     id_info.as_ref().map(|v| v.borrow()),
149                     params,
150                     chars,
151                     &unique_id,
152                     self.boot_info.as_ref().ok_or_else(|| {
153                         km_err!(HardwareNotYetAvailable, "root of trust info not found")
154                     })?,
155                 )?;
156                 Some(cert::asn1_der_encode(&attest_ext)?)
157             } else {
158                 None
159             };
160 
161         let tbs_cert = cert::tbs_certificate(
162             &info,
163             spki,
164             &key_usage_ext_val,
165             basic_constraints_ext_val.as_deref(),
166             attest_ext_val.as_deref(),
167             tag::characteristics_at(chars, self.hw_info.security_level)?,
168             params,
169         )?;
170         let tbs_data = cert::asn1_der_encode(&tbs_cert)?;
171         // If key does not have ATTEST_KEY or SIGN purpose, the certificate has empty signature
172         let sig_data = match info.as_ref() {
173             Some(info) => self.sign_cert_data(info.signing_key.clone(), tbs_data.as_slice())?,
174             None => Vec::new(),
175         };
176 
177         let cert = cert::certificate(tbs_cert, &sig_data)?;
178         let cert_data = cert::asn1_der_encode(&cert)?;
179         Ok(keymint::Certificate { encoded_certificate: cert_data })
180     }
181 
182     /// Perform a complete signing operation using default modes.
sign_cert_data(&self, signing_key: KeyMaterial, tbs_data: &[u8]) -> Result<Vec<u8>, Error>183     fn sign_cert_data(&self, signing_key: KeyMaterial, tbs_data: &[u8]) -> Result<Vec<u8>, Error> {
184         match signing_key {
185             KeyMaterial::Rsa(key) => {
186                 let mut op = self
187                     .imp
188                     .rsa
189                     .begin_sign(key, rsa::SignMode::Pkcs1_1_5Padding(Digest::Sha256))?;
190                 op.update(tbs_data)?;
191                 op.finish()
192             }
193             KeyMaterial::Ec(curve, _, key) => {
194                 let digest = if curve == EcCurve::Curve25519 {
195                     // Ed25519 includes an internal digest and so does not use an external digest.
196                     Digest::None
197                 } else {
198                     Digest::Sha256
199                 };
200                 let mut op = self.imp.ec.begin_sign(key, digest)?;
201                 op.update(tbs_data)?;
202                 op.finish()
203             }
204             _ => Err(km_err!(UnknownError, "unexpected cert signing key type")),
205         }
206     }
207 
208     /// Calculate the `UNIQUE_ID` value for the parameters, if needed.
calculate_unique_id(&self, app_id: &[u8], params: &[KeyParam]) -> Result<Vec<u8>, Error>209     fn calculate_unique_id(&self, app_id: &[u8], params: &[KeyParam]) -> Result<Vec<u8>, Error> {
210         if !get_bool_tag_value!(params, IncludeUniqueId)? {
211             return Ok(Vec::new());
212         }
213         let creation_datetime =
214             get_tag_value!(params, CreationDatetime, ErrorCode::InvalidArgument)?;
215         let rounded_datetime = creation_datetime.ms_since_epoch / 2_592_000_000i64;
216         let datetime_data = rounded_datetime.to_ne_bytes();
217 
218         let mut combined_input = vec_try_with_capacity!(datetime_data.len() + app_id.len() + 1)?;
219         combined_input.extend_from_slice(&datetime_data[..]);
220         combined_input.extend_from_slice(app_id);
221         combined_input.push(u8::from(get_bool_tag_value!(params, ResetSinceIdRotation)?));
222 
223         let hbk = self.dev.keys.unique_id_hbk(self.imp.ckdf)?;
224 
225         let mut hmac_op = self.imp.hmac.begin(hbk.into(), Digest::Sha256)?;
226         hmac_op.update(&combined_input)?;
227         let tag = hmac_op.finish()?;
228         try_to_vec(&tag[..16])
229     }
230 
generate_key( &mut self, params: &[KeyParam], attestation_key: Option<AttestationKey>, ) -> Result<KeyCreationResult, Error>231     pub(crate) fn generate_key(
232         &mut self,
233         params: &[KeyParam],
234         attestation_key: Option<AttestationKey>,
235     ) -> Result<KeyCreationResult, Error> {
236         let (key_material, chars) = self.generate_key_material(params)?;
237         self.finish_keyblob_creation(
238             params,
239             attestation_key,
240             chars,
241             key_material,
242             keyblob::SlotPurpose::KeyGeneration,
243         )
244     }
245 
generate_key_material( &mut self, params: &[KeyParam], ) -> Result<(KeyMaterial, Vec<KeyCharacteristics>), Error>246     pub(crate) fn generate_key_material(
247         &mut self,
248         params: &[KeyParam],
249     ) -> Result<(KeyMaterial, Vec<KeyCharacteristics>), Error> {
250         let (mut chars, keygen_info) = tag::extract_key_gen_characteristics(
251             self.secure_storage_available(),
252             params,
253             self.hw_info.security_level,
254         )?;
255         self.add_keymint_tags(&mut chars, KeyOrigin::Generated)?;
256         let key_material = match keygen_info {
257             crypto::KeyGenInfo::Aes(variant) => {
258                 self.imp.aes.generate_key(&mut *self.imp.rng, variant, params)?
259             }
260             crypto::KeyGenInfo::TripleDes => {
261                 self.imp.des.generate_key(&mut *self.imp.rng, params)?
262             }
263             crypto::KeyGenInfo::Hmac(key_size) => {
264                 self.imp.hmac.generate_key(&mut *self.imp.rng, key_size, params)?
265             }
266             crypto::KeyGenInfo::Rsa(key_size, pub_exponent) => {
267                 self.imp.rsa.generate_key(&mut *self.imp.rng, key_size, pub_exponent, params)?
268             }
269             crypto::KeyGenInfo::NistEc(curve) => {
270                 self.imp.ec.generate_nist_key(&mut *self.imp.rng, curve, params)?
271             }
272             crypto::KeyGenInfo::Ed25519 => {
273                 self.imp.ec.generate_ed25519_key(&mut *self.imp.rng, params)?
274             }
275             crypto::KeyGenInfo::X25519 => {
276                 self.imp.ec.generate_x25519_key(&mut *self.imp.rng, params)?
277             }
278         };
279         Ok((key_material, chars))
280     }
281 
import_key( &mut self, params: &[KeyParam], key_format: KeyFormat, key_data: &[u8], attestation_key: Option<AttestationKey>, import_type: KeyImport, ) -> Result<KeyCreationResult, Error>282     pub(crate) fn import_key(
283         &mut self,
284         params: &[KeyParam],
285         key_format: KeyFormat,
286         key_data: &[u8],
287         attestation_key: Option<AttestationKey>,
288         import_type: KeyImport,
289     ) -> Result<KeyCreationResult, Error> {
290         if !self.in_early_boot && get_bool_tag_value!(params, EarlyBootOnly)? {
291             return Err(km_err!(EarlyBootEnded, "attempt to use EARLY_BOOT key after early boot"));
292         }
293 
294         let (mut chars, key_material) = tag::extract_key_import_characteristics(
295             &self.imp,
296             self.secure_storage_available(),
297             params,
298             self.hw_info.security_level,
299             key_format,
300             key_data,
301         )?;
302         match import_type {
303             KeyImport::NonWrapped => {
304                 self.add_keymint_tags(&mut chars, KeyOrigin::Imported)?;
305             }
306             KeyImport::Wrapped => {
307                 self.add_keymint_tags(&mut chars, KeyOrigin::SecurelyImported)?;
308             }
309         }
310 
311         self.finish_keyblob_creation(
312             params,
313             attestation_key,
314             chars,
315             key_material,
316             keyblob::SlotPurpose::KeyImport,
317         )
318     }
319 
320     /// Perform common processing for keyblob creation (for both generation and import).
finish_keyblob_creation( &mut self, params: &[KeyParam], attestation_key: Option<AttestationKey>, chars: Vec<KeyCharacteristics>, key_material: KeyMaterial, purpose: keyblob::SlotPurpose, ) -> Result<KeyCreationResult, Error>321     pub fn finish_keyblob_creation(
322         &mut self,
323         params: &[KeyParam],
324         attestation_key: Option<AttestationKey>,
325         chars: Vec<KeyCharacteristics>,
326         key_material: KeyMaterial,
327         purpose: keyblob::SlotPurpose,
328     ) -> Result<KeyCreationResult, Error> {
329         let keyblob = keyblob::PlaintextKeyBlob {
330             // Don't include any `SecurityLevel::Keystore` characteristics in the set that is bound
331             // to the key.
332             characteristics: chars
333                 .iter()
334                 .filter(|c| c.security_level != SecurityLevel::Keystore)
335                 .cloned()
336                 .collect(),
337             key_material: key_material.clone(),
338         };
339         let attest_keyblob;
340         let mut certificate_chain = Vec::new();
341         if let Some(spki) = keyblob.key_material.subject_public_key_info(
342             &mut Vec::<u8>::new(),
343             self.imp.ec,
344             self.imp.rsa,
345         )? {
346             // Asymmetric keys return the public key inside an X.509 certificate.
347             // Need to determine:
348             // - a key to sign the cert with (may be absent), together with any associated
349             //   cert chain to append
350             // - whether to include an attestation extension
351             let attest_challenge = get_opt_tag_value!(params, AttestationChallenge)?;
352 
353             let signing_info = if let Some(attest_challenge) = attest_challenge {
354                 // Attestation requested.
355                 if attest_challenge.len() > MAX_ATTESTATION_CHALLENGE_LEN {
356                     return Err(km_err!(
357                         InvalidInputLength,
358                         "attestation challenge too large: {} bytes",
359                         attest_challenge.len()
360                     ));
361                 }
362                 let attest_app_id = get_opt_tag_value!(params, AttestationApplicationId)?
363                     .ok_or_else(|| {
364                         km_err!(AttestationApplicationIdMissing, "attestation requested")
365                     })?;
366                 let attestation_info: Option<(&[u8], &[u8])> =
367                     Some((attest_challenge, attest_app_id));
368 
369                 if let Some(attest_keyinfo) = attestation_key.as_ref() {
370                     // User-specified attestation key provided.
371                     (attest_keyblob, _) = self.keyblob_parse_decrypt(
372                         &attest_keyinfo.key_blob,
373                         &attest_keyinfo.attest_key_params,
374                     )?;
375                     attest_keyblob
376                         .suitable_for(KeyPurpose::AttestKey, self.hw_info.security_level)?;
377                     if attest_keyinfo.issuer_subject_name.is_empty() {
378                         return Err(km_err!(InvalidArgument, "empty subject name"));
379                     }
380                     Some(SigningInfo {
381                         attestation_info,
382                         signing_key: attest_keyblob.key_material,
383                         issuer_subject: attest_keyinfo.issuer_subject_name.clone(),
384                         chain: Vec::new(),
385                     })
386                 } else {
387                     // Need to use a device key for attestation. Look up the relevant device key and
388                     // chain.
389                     let which_key = match (
390                         get_bool_tag_value!(params, DeviceUniqueAttestation)?,
391                         self.is_strongbox(),
392                     ) {
393                         (false, _) => device::SigningKey::Batch,
394                         (true, true) => device::SigningKey::DeviceUnique,
395                         (true, false) => {
396                             return Err(km_err!(
397                                 InvalidArgument,
398                                 "device unique attestation supported only by Strongbox TA"
399                             ))
400                         }
401                     };
402                     // Provide an indication of what's going to be signed, to allow the
403                     // implementation to switch between EC and RSA signing keys if it so chooses.
404                     let algo_hint = match &keyblob.key_material {
405                         crypto::KeyMaterial::Rsa(_) => device::SigningAlgorithm::Rsa,
406                         crypto::KeyMaterial::Ec(_, _, _) => device::SigningAlgorithm::Ec,
407                         _ => return Err(km_err!(InvalidArgument, "unexpected key type!")),
408                     };
409 
410                     let mut info = self
411                         .get_signing_info(device::SigningKeyType { which: which_key, algo_hint })?;
412                     info.attestation_info = attestation_info;
413                     Some(info)
414                 }
415             } else {
416                 // No attestation challenge, so no attestation.
417                 if attestation_key.is_some() {
418                     return Err(km_err!(
419                         AttestationChallengeMissing,
420                         "got attestation key but no challenge"
421                     ));
422                 }
423 
424                 // See if the generated key can self-sign.
425                 let is_signing_key = params.iter().any(|param| {
426                     matches!(
427                         param,
428                         KeyParam::Purpose(KeyPurpose::Sign)
429                             | KeyParam::Purpose(KeyPurpose::AttestKey)
430                     )
431                 });
432                 if is_signing_key {
433                     Some(SigningInfo {
434                         attestation_info: None,
435                         signing_key: key_material,
436                         issuer_subject: try_to_vec(tag::get_cert_subject(params)?)?,
437                         chain: Vec::new(),
438                     })
439                 } else {
440                     None
441                 }
442             };
443 
444             // Build the X.509 leaf certificate.
445             let leaf_cert = self.generate_cert(signing_info.clone(), spki, params, &chars)?;
446             certificate_chain.try_push(leaf_cert)?;
447 
448             // Append the rest of the chain.
449             if let Some(info) = signing_info {
450                 for cert in info.chain {
451                     certificate_chain.try_push(cert)?;
452                 }
453             }
454         }
455 
456         // Now build the keyblob.
457         let kek_context = self.dev.keys.kek_context()?;
458         let root_kek = self.root_kek(&kek_context)?;
459         let hidden = tag::hidden(params, self.root_of_trust()?)?;
460         let encrypted_keyblob = keyblob::encrypt(
461             self.hw_info.security_level,
462             match &mut self.dev.sdd_mgr {
463                 None => None,
464                 Some(mr) => Some(*mr),
465             },
466             self.imp.aes,
467             self.imp.hkdf,
468             &mut *self.imp.rng,
469             &root_kek,
470             &kek_context,
471             keyblob,
472             hidden,
473             purpose,
474         )?;
475         let serialized_keyblob = encrypted_keyblob.into_vec()?;
476 
477         Ok(KeyCreationResult {
478             key_blob: serialized_keyblob,
479             key_characteristics: chars,
480             certificate_chain,
481         })
482     }
483 
import_wrapped_key( &mut self, wrapped_key_data: &[u8], wrapping_key_blob: &[u8], masking_key: &[u8], unwrapping_params: &[KeyParam], password_sid: i64, biometric_sid: i64, ) -> Result<KeyCreationResult, Error>484     pub(crate) fn import_wrapped_key(
485         &mut self,
486         wrapped_key_data: &[u8],
487         wrapping_key_blob: &[u8],
488         masking_key: &[u8],
489         unwrapping_params: &[KeyParam],
490         password_sid: i64,
491         biometric_sid: i64,
492     ) -> Result<KeyCreationResult, Error> {
493         // Decrypt the wrapping key blob
494         let (wrapping_key, _) = self.keyblob_parse_decrypt(wrapping_key_blob, unwrapping_params)?;
495         let keyblob::PlaintextKeyBlob { characteristics, key_material } = wrapping_key;
496 
497         // Decode the ASN.1 DER encoded `SecureKeyWrapper`.
498         let mut secure_key_wrapper = SecureKeyWrapper::from_der(wrapped_key_data)?;
499 
500         if secure_key_wrapper.version != SECURE_KEY_WRAPPER_VERSION {
501             return Err(km_err!(InvalidArgument, "invalid version in Secure Key Wrapper."));
502         }
503 
504         // Decrypt the masked transport key.
505         let masked_transport_key = match key_material {
506             KeyMaterial::Rsa(key) => {
507                 // Check the requirements on the wrapping key characterisitcs
508                 let decrypt_mode = tag::check_rsa_wrapping_key_params(
509                     tag::characteristics_at(&characteristics, self.hw_info.security_level)?,
510                     unwrapping_params,
511                 )?;
512 
513                 // Decrypt the masked and encrypted transport key
514                 let mut crypto_op = self.imp.rsa.begin_decrypt(key, decrypt_mode)?;
515                 crypto_op.as_mut().update(secure_key_wrapper.encrypted_transport_key)?;
516                 crypto_op.finish()?
517             }
518             // TODO: For now, we consider wrapping keys to be RSA keys only.
519             _ => {
520                 return Err(km_err!(InvalidArgument, "invalid key algorithm for transport key"));
521             }
522         };
523 
524         if masked_transport_key.len() != masking_key.len() {
525             return Err(km_err!(
526                 InvalidArgument,
527                 "masked transport key is {} bytes, but masking key is {} bytes",
528                 masked_transport_key.len(),
529                 masking_key.len()
530             ));
531         }
532 
533         let unmasked_transport_key: Vec<u8> =
534             masked_transport_key.iter().zip(masking_key).map(|(x, y)| x ^ y).collect();
535 
536         let aes_transport_key =
537             aes::Key::Aes256(unmasked_transport_key.try_into().map_err(|_e| {
538                 km_err!(
539                     InvalidArgument,
540                     "transport key len {} not correct for AES-256 key",
541                     masked_transport_key.len()
542                 )
543             })?);
544 
545         // Validate the size of the IV and match the `aes::GcmMode` based on the tag size.
546         let iv_len = secure_key_wrapper.initialization_vector.len();
547         if iv_len != aes::GCM_NONCE_SIZE {
548             return Err(km_err!(
549                 InvalidArgument,
550                 "IV length is of {} bytes, which should be of {} bytes",
551                 iv_len,
552                 aes::GCM_NONCE_SIZE
553             ));
554         }
555         let tag_len = secure_key_wrapper.tag.len();
556         let gcm_mode = match tag_len {
557             12 => crypto::aes::GcmMode::GcmTag12 {
558                 nonce: secure_key_wrapper.initialization_vector.try_into()
559                 .unwrap(/* safe: len checked */),
560             },
561             13 => crypto::aes::GcmMode::GcmTag13 {
562                 nonce: secure_key_wrapper.initialization_vector.try_into()
563                 .unwrap(/* safe: len checked */),
564             },
565             14 => crypto::aes::GcmMode::GcmTag14 {
566                 nonce: secure_key_wrapper.initialization_vector.try_into()
567                 .unwrap(/* safe: len checked */),
568             },
569             15 => crypto::aes::GcmMode::GcmTag15 {
570                 nonce: secure_key_wrapper.initialization_vector.try_into()
571                 .unwrap(/* safe: len checked */),
572             },
573             16 => crypto::aes::GcmMode::GcmTag16 {
574                 nonce: secure_key_wrapper.initialization_vector.try_into()
575                 .unwrap(/* safe: len checked */),
576             },
577             v => {
578                 return Err(km_err!(
579                     InvalidMacLength,
580                     "want 12-16 byte tag for AES-GCM not {} bytes",
581                     v
582                 ))
583             }
584         };
585 
586         // Decrypt the encrypted key to be imported, using the ASN.1 DER (re-)encoding of the key
587         // description as the AAD.
588         let mut op = self.imp.aes.begin_aead(
589             OpaqueOr::Explicit(aes_transport_key),
590             gcm_mode,
591             crypto::SymmetricOperation::Decrypt,
592         )?;
593         op.update_aad(&cert::asn1_der_encode(&secure_key_wrapper.key_description)?)?;
594 
595         let mut imported_key_data = op.update(secure_key_wrapper.encrypted_key)?;
596         imported_key_data.try_extend_from_slice(&op.update(secure_key_wrapper.tag)?)?;
597         imported_key_data.try_extend_from_slice(&op.finish()?)?;
598 
599         // The `Cow::to_mut()` call will not clone, because `from_der()` invokes
600         // `AuthorizationList::decode_value()` which creates the owned variant.
601         let imported_key_params: &mut Vec<KeyParam> =
602             secure_key_wrapper.key_description.key_params.auths.to_mut();
603         if let Some(secure_id) = get_opt_tag_value!(&*imported_key_params, UserSecureId)? {
604             let secure_id = *secure_id;
605             // If both the Password and Fingerprint bits are set in UserSecureId, the password SID
606             // should be used, because biometric auth tokens contain both password and fingerprint
607             // SIDs, but password auth tokens only contain the password SID.
608             if (secure_id & (HardwareAuthenticatorType::Password as u64)
609                 == (HardwareAuthenticatorType::Password as u64))
610                 && (secure_id & (HardwareAuthenticatorType::Fingerprint as u64)
611                     == (HardwareAuthenticatorType::Fingerprint as u64))
612             {
613                 imported_key_params
614                     .retain(|key_param| !matches!(key_param, KeyParam::UserSecureId(_)));
615                 imported_key_params.try_push(KeyParam::UserSecureId(password_sid as u64))?;
616             } else if secure_id & (HardwareAuthenticatorType::Password as u64)
617                 == (HardwareAuthenticatorType::Password as u64)
618             {
619                 imported_key_params
620                     .retain(|key_param| !matches!(key_param, KeyParam::UserSecureId(_)));
621                 imported_key_params.try_push(KeyParam::UserSecureId(password_sid as u64))?;
622             } else if secure_id & (HardwareAuthenticatorType::Fingerprint as u64)
623                 == (HardwareAuthenticatorType::Fingerprint as u64)
624             {
625                 imported_key_params
626                     .retain(|key_param| !matches!(key_param, KeyParam::UserSecureId(_)));
627                 imported_key_params.try_push(KeyParam::UserSecureId(biometric_sid as u64))?;
628             }
629         };
630         self.import_key(
631             imported_key_params,
632             KeyFormat::try_from(secure_key_wrapper.key_description.key_format).map_err(|_e| {
633                 km_err!(
634                     UnsupportedKeyFormat,
635                     "could not convert the provided keyformat {}",
636                     secure_key_wrapper.key_description.key_format
637                 )
638             })?,
639             &imported_key_data,
640             None,
641             KeyImport::Wrapped,
642         )
643     }
644 
upgrade_key( &mut self, keyblob_to_upgrade: &[u8], upgrade_params: Vec<KeyParam>, ) -> Result<Vec<u8>, Error>645     pub(crate) fn upgrade_key(
646         &mut self,
647         keyblob_to_upgrade: &[u8],
648         upgrade_params: Vec<KeyParam>,
649     ) -> Result<Vec<u8>, Error> {
650         let (mut keyblob, mut modified) =
651             match self.keyblob_parse_decrypt_backlevel(keyblob_to_upgrade, &upgrade_params) {
652                 Ok(v) => (v.0, false),
653                 Err(Error::Hal(ErrorCode::KeyRequiresUpgrade, _)) => {
654                     // Because `keyblob_parse_decrypt_backlevel` explicitly allows back-level
655                     // versioned keys, a `KeyRequiresUpgrade` error indicates that the keyblob looks
656                     // to be in legacy format.  Try to convert it.
657                     let legacy_handler = self
658                         .dev
659                         .legacy_key
660                         .as_mut()
661                         .ok_or_else(|| km_err!(UnknownError, "no legacy key handler"))?;
662                     (
663                         legacy_handler.convert_legacy_key(
664                             keyblob_to_upgrade,
665                             &upgrade_params,
666                             self.boot_info
667                                 .as_ref()
668                                 .ok_or_else(|| km_err!(HardwareNotYetAvailable, "no boot info"))?,
669                             self.hw_info.security_level,
670                         )?,
671                         // Force the emission of a new keyblob even if versions are the same.
672                         true,
673                     )
674                 }
675                 Err(e) => return Err(e),
676             };
677 
678         fn upgrade(v: &mut u32, curr: u32, name: &str) -> Result<bool, Error> {
679             match (*v).cmp(&curr) {
680                 Ordering::Less => {
681                     *v = curr;
682                     Ok(true)
683                 }
684                 Ordering::Equal => Ok(false),
685                 Ordering::Greater => {
686                     error!("refusing to downgrade {} from {} to {}", name, v, curr);
687                     Err(km_err!(
688                         InvalidArgument,
689                         "keyblob with future {} {} (current {})",
690                         name,
691                         v,
692                         curr
693                     ))
694                 }
695             }
696         }
697 
698         for chars in &mut keyblob.characteristics {
699             if chars.security_level != self.hw_info.security_level {
700                 continue;
701             }
702             for param in &mut chars.authorizations {
703                 match param {
704                     KeyParam::OsVersion(v) => {
705                         if let Some(hal_info) = &self.hal_info {
706                             if hal_info.os_version == 0 {
707                                 // Special case: upgrades to OS version zero are always allowed.
708                                 warn!("forcing upgrade to OS version 0");
709                                 modified |= *v != 0;
710                                 *v = 0;
711                             } else {
712                                 modified |= upgrade(v, hal_info.os_version, "OS version")?;
713                             }
714                         } else {
715                             error!("OS version not available, can't upgrade from {}", v);
716                         }
717                     }
718                     KeyParam::OsPatchlevel(v) => {
719                         if let Some(hal_info) = &self.hal_info {
720                             modified |= upgrade(v, hal_info.os_patchlevel, "OS patchlevel")?;
721                         } else {
722                             error!("OS patchlevel not available, can't upgrade from {}", v);
723                         }
724                     }
725                     KeyParam::VendorPatchlevel(v) => {
726                         if let Some(hal_info) = &self.hal_info {
727                             modified |=
728                                 upgrade(v, hal_info.vendor_patchlevel, "vendor patchlevel")?;
729                         } else {
730                             error!("vendor patchlevel not available, can't upgrade from {}", v);
731                         }
732                     }
733                     KeyParam::BootPatchlevel(v) => {
734                         if let Some(boot_info) = &self.boot_info {
735                             modified |= upgrade(v, boot_info.boot_patchlevel, "boot patchlevel")?;
736                         } else {
737                             error!("boot patchlevel not available, can't upgrade from {}", v);
738                         }
739                     }
740                     _ => {}
741                 }
742             }
743         }
744 
745         if !modified {
746             // No upgrade needed, return empty data to indicate existing keyblob can still be used.
747             return Ok(Vec::new());
748         }
749 
750         // Now re-build the keyblob. Use a potentially fresh key encryption key, and potentially a
751         // new secure deletion secret slot. (The old slot will be released when Keystore performs
752         // the corresponding `deleteKey` operation on the old keyblob.
753         let kek_context = self.dev.keys.kek_context()?;
754         let root_kek = self.root_kek(&kek_context)?;
755         let hidden = tag::hidden(&upgrade_params, self.root_of_trust()?)?;
756         let encrypted_keyblob = keyblob::encrypt(
757             self.hw_info.security_level,
758             match &mut self.dev.sdd_mgr {
759                 None => None,
760                 Some(mr) => Some(*mr),
761             },
762             self.imp.aes,
763             self.imp.hkdf,
764             &mut *self.imp.rng,
765             &root_kek,
766             &kek_context,
767             keyblob,
768             hidden,
769             keyblob::SlotPurpose::KeyUpgrade,
770         )?;
771         Ok(encrypted_keyblob.into_vec()?)
772     }
773 }
774