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