• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Helper functionality for working with tags.
2 
3 use crate::{
4     crypto,
5     crypto::{rsa::DecryptionMode, *},
6     km_err, try_to_vec, vec_try_with_capacity, Error, FallibleAllocExt,
7 };
8 use alloc::vec::Vec;
9 use kmr_wire::{
10     keymint::{
11         Algorithm, BlockMode, Digest, EcCurve, ErrorCode, KeyCharacteristics, KeyFormat, KeyParam,
12         KeyPurpose, PaddingMode, SecurityLevel, Tag, DEFAULT_CERT_SERIAL, DEFAULT_CERT_SUBJECT,
13     },
14     KeySizeInBits,
15 };
16 use log::{info, warn};
17 
18 mod info;
19 pub use info::*;
20 pub mod legacy;
21 #[cfg(test)]
22 mod tests;
23 
24 /// The set of tags that are directly copied from key generation/import parameters to
25 /// key characteristics without being checked.
26 pub const UNPOLICED_COPYABLE_TAGS: &[Tag] = &[
27     Tag::RollbackResistance,
28     Tag::EarlyBootOnly,
29     Tag::MaxUsesPerBoot,
30     Tag::UserSecureId, // repeatable
31     Tag::NoAuthRequired,
32     Tag::UserAuthType,
33     Tag::AuthTimeout,
34     Tag::TrustedUserPresenceRequired,
35     Tag::TrustedConfirmationRequired,
36     Tag::UnlockedDeviceRequired,
37     Tag::StorageKey,
38 ];
39 
40 /// Indication of whether secure storage is available.
41 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
42 pub enum SecureStorage {
43     Available,
44     Unavailable,
45 }
46 
47 /// Macro to retrieve a copy of the (single) value of a tag in a collection of `KeyParam`s.  There
48 /// can be only one.  Only works for variants whose data type implements `Copy`.
49 #[macro_export]
50 macro_rules! get_tag_value {
51     { $params:expr, $variant:ident, $err:expr } => {
52         {
53             let mut result = None;
54             let mut count = 0;
55             for param in $params {
56                 if let kmr_wire::keymint::KeyParam::$variant(v) = param {
57                     count += 1;
58                     result = Some(*v);
59                 }
60             }
61             match count {
62                 0 => Err($crate::km_verr!($err, "missing tag {}", stringify!($variant))),
63                 1 => Ok(result.unwrap()),  /* safe: count=1 => exists */
64                 _ => Err($crate::km_verr!($err, "duplicate tag {}", stringify!($variant))),
65             }
66         }
67     }
68 }
69 
70 /// Macro to retrieve the value of an optional single-valued tag in a collection of `KeyParam`s.  It
71 /// may or may not be present, but multiple instances of the tag are assumed to be invalid.
72 #[macro_export]
73 macro_rules! get_opt_tag_value {
74     { $params:expr, $variant:ident } => {
75         get_opt_tag_value!($params, $variant, InvalidTag)
76     };
77     { $params:expr, $variant:ident, $dup_error:ident } => {
78         {
79             let mut result = None;
80             let mut count = 0;
81             for param in $params {
82                 if let kmr_wire::keymint::KeyParam::$variant(v) = param {
83                     count += 1;
84                     result = Some(v);
85                 }
86             }
87             match count {
88                 0 => Ok(None),
89                 1 => Ok(Some(result.unwrap())),  /* safe: count=1 => exists */
90                 _ => Err($crate::km_err!($dup_error, "duplicate tag {}", stringify!($variant))),
91             }
92         }
93     }
94 }
95 
96 /// Macro to retrieve a `bool` tag value, returning `false` if the tag is absent
97 #[macro_export]
98 macro_rules! get_bool_tag_value {
99     { $params:expr, $variant:ident } => {
100         {
101             let mut count = 0;
102             for param in $params {
103                 if let kmr_wire::keymint::KeyParam::$variant = param {
104                     count += 1;
105                 }
106             }
107             match count {
108                 0 => Ok(false),
109                 1 => Ok(true),
110                 _ => Err($crate::km_err!(InvalidTag, "duplicate tag {}", stringify!($variant))),
111             }
112         }
113     }
114 }
115 
116 /// Macro to check a collection of `KeyParam`s holds a value matching the given value.
117 #[macro_export]
118 macro_rules! contains_tag_value {
119     { $params:expr, $variant:ident, $value:expr } => {
120         {
121             let mut found = false;
122             for param in $params {
123                 if let kmr_wire::keymint::KeyParam::$variant(v) = param {
124                     if *v == $value {
125                         found = true;
126                     }
127                 }
128             }
129             found
130         }
131     }
132 }
133 
134 /// Check that a set of [`KeyParam`]s is valid when considered as key characteristics.
characteristics_valid(characteristics: &[KeyParam]) -> Result<(), Error>135 pub fn characteristics_valid(characteristics: &[KeyParam]) -> Result<(), Error> {
136     let mut dup_checker = DuplicateTagChecker::default();
137     for param in characteristics {
138         let tag = param.tag();
139         dup_checker.add(tag)?;
140         if info(tag)?.characteristic == Characteristic::NotKeyCharacteristic {
141             return Err(
142                 km_err!(InvalidKeyBlob, "tag {:?} is not a valid key characteristic", tag,),
143             );
144         }
145     }
146     Ok(())
147 }
148 
149 /// Copy anything in `src` that matches `tags` into `dest`.  Fails if any non-repeatable
150 /// tags occur more than once with a different value.
transcribe_tags( dest: &mut Vec<KeyParam>, src: &[KeyParam], tags: &[Tag], ) -> Result<(), Error>151 pub fn transcribe_tags(
152     dest: &mut Vec<KeyParam>,
153     src: &[KeyParam],
154     tags: &[Tag],
155 ) -> Result<(), Error> {
156     let mut dup_checker = DuplicateTagChecker::default();
157     for param in src {
158         let tag = param.tag();
159         dup_checker.add(tag)?;
160         if tags.iter().any(|t| *t == tag) {
161             dest.try_push(param.clone())?;
162         }
163     }
164     Ok(())
165 }
166 
167 /// Get the configured algorithm from a set of parameters.
get_algorithm(params: &[KeyParam]) -> Result<Algorithm, Error>168 pub fn get_algorithm(params: &[KeyParam]) -> Result<Algorithm, Error> {
169     get_tag_value!(params, Algorithm, ErrorCode::UnsupportedAlgorithm)
170 }
171 
172 /// Get the configured block mode from a set of parameters.
get_block_mode(params: &[KeyParam]) -> Result<BlockMode, Error>173 pub fn get_block_mode(params: &[KeyParam]) -> Result<BlockMode, Error> {
174     get_tag_value!(params, BlockMode, ErrorCode::UnsupportedBlockMode)
175 }
176 
177 /// Get the configured padding mode from a set of parameters.
get_padding_mode(params: &[KeyParam]) -> Result<PaddingMode, Error>178 pub fn get_padding_mode(params: &[KeyParam]) -> Result<PaddingMode, Error> {
179     get_tag_value!(params, Padding, ErrorCode::UnsupportedPaddingMode)
180 }
181 
182 /// Get the configured digest from a set of parameters.
get_digest(params: &[KeyParam]) -> Result<Digest, Error>183 pub fn get_digest(params: &[KeyParam]) -> Result<Digest, Error> {
184     get_tag_value!(params, Digest, ErrorCode::UnsupportedDigest)
185 }
186 
187 /// Get the configured elliptic curve from a set of parameters.
get_ec_curve(params: &[KeyParam]) -> Result<EcCurve, Error>188 pub fn get_ec_curve(params: &[KeyParam]) -> Result<EcCurve, Error> {
189     get_tag_value!(params, EcCurve, ErrorCode::UnsupportedKeySize)
190 }
191 
192 /// Get the configured MGF digest from a set of parameters.  If no MGF digest is specified,
193 /// a default value of SHA1 is returned.
get_mgf_digest(params: &[KeyParam]) -> Result<Digest, Error>194 pub fn get_mgf_digest(params: &[KeyParam]) -> Result<Digest, Error> {
195     Ok(*get_opt_tag_value!(params, RsaOaepMgfDigest)?.unwrap_or(&Digest::Sha1))
196 }
197 
198 /// Get the certificate serial number from a set of parameters, falling back to default value of 1
199 /// if not specified
get_cert_serial(params: &[KeyParam]) -> Result<&[u8], Error>200 pub fn get_cert_serial(params: &[KeyParam]) -> Result<&[u8], Error> {
201     Ok(get_opt_tag_value!(params, CertificateSerial)?
202         .map(Vec::as_ref)
203         .unwrap_or(DEFAULT_CERT_SERIAL))
204 }
205 
206 /// Return the set of key parameters at the provided security level.
characteristics_at( chars: &[KeyCharacteristics], sec_level: SecurityLevel, ) -> Result<&[KeyParam], Error>207 pub fn characteristics_at(
208     chars: &[KeyCharacteristics],
209     sec_level: SecurityLevel,
210 ) -> Result<&[KeyParam], Error> {
211     let mut result: Option<&[KeyParam]> = None;
212     for chars in chars {
213         if chars.security_level != sec_level {
214             continue;
215         }
216         if result.is_none() {
217             result = Some(&chars.authorizations);
218         } else {
219             return Err(km_err!(InvalidKeyBlob, "multiple key characteristics at {:?}", sec_level));
220         }
221     }
222     result.ok_or_else(|| {
223         km_err!(InvalidKeyBlob, "no parameters at security level {:?} found", sec_level)
224     })
225 }
226 
227 /// Get the certificate subject from a set of parameters, falling back to a default if not
228 /// specified.
get_cert_subject(params: &[KeyParam]) -> Result<&[u8], Error>229 pub fn get_cert_subject(params: &[KeyParam]) -> Result<&[u8], Error> {
230     Ok(get_opt_tag_value!(params, CertificateSubject)?
231         .map(Vec::as_ref)
232         .unwrap_or(DEFAULT_CERT_SUBJECT))
233 }
234 
235 /// Build the parameters that are used as the hidden input to KEK derivation calculations:
236 /// - `ApplicationId(data)` if present
237 /// - `ApplicationData(data)` if present
238 /// - `RootOfTrust(rot)` where `rot` is a hardcoded root of trust
hidden(params: &[KeyParam], rot: &[u8]) -> Result<Vec<KeyParam>, Error>239 pub fn hidden(params: &[KeyParam], rot: &[u8]) -> Result<Vec<KeyParam>, Error> {
240     let mut results = vec_try_with_capacity!(3)?;
241     if let Ok(Some(app_id)) = get_opt_tag_value!(params, ApplicationId) {
242         results.push(KeyParam::ApplicationId(try_to_vec(app_id)?));
243     }
244     if let Ok(Some(app_data)) = get_opt_tag_value!(params, ApplicationData) {
245         results.push(KeyParam::ApplicationData(try_to_vec(app_data)?));
246     }
247     results.push(KeyParam::RootOfTrust(try_to_vec(rot)?));
248     Ok(results)
249 }
250 
251 /// Build the set of key characteristics for a key that is about to be generated,
252 /// checking parameter validity along the way. Also return the information needed for key
253 /// generation.
extract_key_gen_characteristics( secure_storage: SecureStorage, params: &[KeyParam], sec_level: SecurityLevel, ) -> Result<(Vec<KeyCharacteristics>, KeyGenInfo), Error>254 pub fn extract_key_gen_characteristics(
255     secure_storage: SecureStorage,
256     params: &[KeyParam],
257     sec_level: SecurityLevel,
258 ) -> Result<(Vec<KeyCharacteristics>, KeyGenInfo), Error> {
259     let keygen_info = match get_algorithm(params)? {
260         Algorithm::Rsa => check_rsa_gen_params(params, sec_level),
261         Algorithm::Ec => check_ec_gen_params(params, sec_level),
262         Algorithm::Aes => check_aes_gen_params(params, sec_level),
263         Algorithm::TripleDes => check_3des_gen_params(params),
264         Algorithm::Hmac => check_hmac_gen_params(params, sec_level),
265     }?;
266     Ok((extract_key_characteristics(secure_storage, params, &[], sec_level)?, keygen_info))
267 }
268 
269 /// Build the set of key characteristics for a key that is about to be imported,
270 /// checking parameter validity along the way.
extract_key_import_characteristics( imp: &crypto::Implementation, secure_storage: SecureStorage, params: &[KeyParam], sec_level: SecurityLevel, key_format: KeyFormat, key_data: &[u8], ) -> Result<(Vec<KeyCharacteristics>, KeyMaterial), Error>271 pub fn extract_key_import_characteristics(
272     imp: &crypto::Implementation,
273     secure_storage: SecureStorage,
274     params: &[KeyParam],
275     sec_level: SecurityLevel,
276     key_format: KeyFormat,
277     key_data: &[u8],
278 ) -> Result<(Vec<KeyCharacteristics>, KeyMaterial), Error> {
279     let (deduced_params, key_material) = match get_algorithm(params)? {
280         Algorithm::Rsa => check_rsa_import_params(imp.rsa, params, sec_level, key_format, key_data),
281         Algorithm::Ec => check_ec_import_params(imp.ec, params, sec_level, key_format, key_data),
282         Algorithm::Aes => check_aes_import_params(imp.aes, params, sec_level, key_format, key_data),
283         Algorithm::TripleDes => check_3des_import_params(imp.des, params, key_format, key_data),
284         Algorithm::Hmac => {
285             check_hmac_import_params(imp.hmac, params, sec_level, key_format, key_data)
286         }
287     }?;
288     Ok((
289         extract_key_characteristics(secure_storage, params, &deduced_params, sec_level)?,
290         key_material,
291     ))
292 }
293 
294 /// Build the set of key characteristics for a key that is about to be generated or imported,
295 /// checking parameter validity along the way. The `extra_params` argument provides additional
296 /// parameters on top of `params`, such as those deduced from imported key material.
extract_key_characteristics( secure_storage: SecureStorage, params: &[KeyParam], extra_params: &[KeyParam], sec_level: SecurityLevel, ) -> Result<Vec<KeyCharacteristics>, Error>297 fn extract_key_characteristics(
298     secure_storage: SecureStorage,
299     params: &[KeyParam],
300     extra_params: &[KeyParam],
301     sec_level: SecurityLevel,
302 ) -> Result<Vec<KeyCharacteristics>, Error> {
303     // Separately accumulate any characteristics that are policed by Keystore.
304     let mut chars = Vec::new();
305     let mut keystore_chars = Vec::new();
306     for param in params.iter().chain(extra_params) {
307         let tag = param.tag();
308 
309         // Input params should not contain anything that KeyMint adds itself.
310         if AUTO_ADDED_CHARACTERISTICS.contains(&tag) {
311             return Err(km_err!(InvalidTag, "KeyMint-added tag included on key generation/import"));
312         }
313 
314         if sec_level == SecurityLevel::Strongbox
315             && [Tag::MaxUsesPerBoot, Tag::RollbackResistance].contains(&tag)
316         {
317             // StrongBox does not support tags that require per-key storage.
318             return Err(km_err!(InvalidTag, "tag {:?} not allowed in StrongBox", param.tag()));
319         }
320 
321         // UsageCountLimit is peculiar. If its value is > 1, it should be Keystore-enforced.
322         // If its value is = 1, then it is KeyMint-enforced if secure storage is available,
323         // and Keystore-enforced otherwise.
324         if let KeyParam::UsageCountLimit(use_limit) = param {
325             match (use_limit, secure_storage) {
326                 (1, SecureStorage::Available) => {
327                     chars.try_push(KeyParam::UsageCountLimit(*use_limit))?
328                 }
329                 (1, SecureStorage::Unavailable) | (_, _) => {
330                     keystore_chars.try_push(KeyParam::UsageCountLimit(*use_limit))?
331                 }
332             }
333         }
334 
335         if KEYMINT_ENFORCED_CHARACTERISTICS.contains(&tag) {
336             chars.try_push(param.clone())?;
337         } else if KEYSTORE_ENFORCED_CHARACTERISTICS.contains(&tag) {
338             keystore_chars.try_push(param.clone())?;
339         } else if tag == Tag::UnlockedDeviceRequired {
340             // `UnlockedDeviceRequired` is policed by both KeyMint and Keystore, so put it in the
341             // KeyMint security level.
342             chars.try_push(param.clone())?;
343         }
344     }
345 
346     reject_incompatible_auth(&chars)?;
347 
348     // Use the same sort order for tags as was previously used.
349     chars.sort_by(legacy::param_compare);
350     keystore_chars.sort_by(legacy::param_compare);
351 
352     let mut result = Vec::new();
353     result.try_push(KeyCharacteristics { security_level: sec_level, authorizations: chars })?;
354     if !keystore_chars.is_empty() {
355         result.try_push(KeyCharacteristics {
356             security_level: SecurityLevel::Keystore,
357             authorizations: keystore_chars,
358         })?;
359     }
360     Ok(result)
361 }
362 
363 /// Check that an RSA key size is valid.
check_rsa_key_size(key_size: KeySizeInBits, sec_level: SecurityLevel) -> Result<(), Error>364 fn check_rsa_key_size(key_size: KeySizeInBits, sec_level: SecurityLevel) -> Result<(), Error> {
365     // StrongBox only supports 2048-bit keys.
366     match key_size {
367         KeySizeInBits(512) if sec_level != SecurityLevel::Strongbox => Ok(()),
368         KeySizeInBits(768) if sec_level != SecurityLevel::Strongbox => Ok(()),
369         KeySizeInBits(1024) if sec_level != SecurityLevel::Strongbox => Ok(()),
370         KeySizeInBits(2048) => Ok(()),
371         KeySizeInBits(3072) if sec_level != SecurityLevel::Strongbox => Ok(()),
372         KeySizeInBits(4096) if sec_level != SecurityLevel::Strongbox => Ok(()),
373         _ => Err(km_err!(UnsupportedKeySize, "unsupported KEY_SIZE {:?} bits for RSA", key_size)),
374     }
375 }
376 
377 /// Check RSA key generation parameter validity.
check_rsa_gen_params( params: &[KeyParam], sec_level: SecurityLevel, ) -> Result<KeyGenInfo, Error>378 fn check_rsa_gen_params(
379     params: &[KeyParam],
380     sec_level: SecurityLevel,
381 ) -> Result<KeyGenInfo, Error> {
382     // For key generation, size and public exponent must be explicitly specified.
383     let key_size = get_tag_value!(params, KeySize, ErrorCode::UnsupportedKeySize)?;
384     check_rsa_key_size(key_size, sec_level)?;
385     let public_exponent = get_tag_value!(params, RsaPublicExponent, ErrorCode::InvalidArgument)?;
386 
387     check_rsa_params(params)?;
388     Ok(KeyGenInfo::Rsa(key_size, public_exponent))
389 }
390 
391 /// Check RSA key import parameter validity. Return the key material along with any key generation
392 /// parameters that have been deduced from the key material (but which are not present in the input
393 /// key parameters).
check_rsa_import_params( rsa: &dyn Rsa, params: &[KeyParam], sec_level: SecurityLevel, key_format: KeyFormat, key_data: &[u8], ) -> Result<(Vec<KeyParam>, KeyMaterial), Error>394 fn check_rsa_import_params(
395     rsa: &dyn Rsa,
396     params: &[KeyParam],
397     sec_level: SecurityLevel,
398     key_format: KeyFormat,
399     key_data: &[u8],
400 ) -> Result<(Vec<KeyParam>, KeyMaterial), Error> {
401     // Deduce key size and exponent from import data.
402     if key_format != KeyFormat::Pkcs8 {
403         return Err(km_err!(
404             UnsupportedKeyFormat,
405             "unsupported import format {:?}, expect PKCS8",
406             key_format
407         ));
408     }
409     let (key, key_size, public_exponent) = rsa.import_pkcs8_key(key_data, params)?;
410 
411     // If key size or exponent are explicitly specified, they must match. If they were not
412     // specified, we emit them.
413     let mut deduced_chars = Vec::new();
414     match get_opt_tag_value!(params, KeySize)? {
415         Some(param_key_size) => {
416             if *param_key_size != key_size {
417                 return Err(km_err!(
418                     ImportParameterMismatch,
419                     "specified KEY_SIZE {:?} bits != actual key size {:?} for PKCS8 import",
420                     param_key_size,
421                     key_size
422                 ));
423             }
424         }
425         None => deduced_chars.try_push(KeyParam::KeySize(key_size))?,
426     }
427     match get_opt_tag_value!(params, RsaPublicExponent)? {
428         Some(param_public_exponent) => {
429             if *param_public_exponent != public_exponent {
430                 return Err(km_err!(
431                     ImportParameterMismatch,
432                     "specified RSA_PUBLIC_EXPONENT {:?} != actual exponent {:?} for PKCS8 import",
433                     param_public_exponent,
434                     public_exponent,
435                 ));
436             }
437         }
438         None => deduced_chars.try_push(KeyParam::RsaPublicExponent(public_exponent))?,
439     }
440     check_rsa_key_size(key_size, sec_level)?;
441 
442     check_rsa_params(params)?;
443     Ok((deduced_chars, key))
444 }
445 
446 /// Check the parameter validity for an RSA key that is about to be generated or imported.
check_rsa_params(params: &[KeyParam]) -> Result<(), Error>447 fn check_rsa_params(params: &[KeyParam]) -> Result<(), Error> {
448     let mut seen_attest = false;
449     let mut seen_non_attest = false;
450     for param in params {
451         if let KeyParam::Purpose(purpose) = param {
452             match purpose {
453                 KeyPurpose::Sign | KeyPurpose::Decrypt | KeyPurpose::WrapKey => {
454                     seen_non_attest = true
455                 }
456                 KeyPurpose::AttestKey => seen_attest = true,
457                 KeyPurpose::Verify | KeyPurpose::Encrypt => {} // public key operations
458                 KeyPurpose::AgreeKey => {
459                     warn!("Generating RSA key with invalid purpose {:?}", purpose)
460                 }
461             }
462         }
463     }
464     if seen_attest && seen_non_attest {
465         return Err(km_err!(
466             IncompatiblePurpose,
467             "keys with ATTEST_KEY must have no other purpose"
468         ));
469     }
470     Ok(())
471 }
472 
473 /// Check EC key generation parameter validity.
check_ec_gen_params(params: &[KeyParam], sec_level: SecurityLevel) -> Result<KeyGenInfo, Error>474 fn check_ec_gen_params(params: &[KeyParam], sec_level: SecurityLevel) -> Result<KeyGenInfo, Error> {
475     // For key generation, the curve must be explicitly specified.
476     let ec_curve = get_ec_curve(params)?;
477 
478     let purpose = check_ec_params(ec_curve, params, sec_level)?;
479     let keygen_info = match (ec_curve, purpose) {
480         (EcCurve::Curve25519, Some(KeyPurpose::Sign)) => KeyGenInfo::Ed25519,
481         (EcCurve::Curve25519, Some(KeyPurpose::AttestKey)) => KeyGenInfo::Ed25519,
482         (EcCurve::Curve25519, Some(KeyPurpose::AgreeKey)) => KeyGenInfo::X25519,
483         (EcCurve::Curve25519, _) => {
484             return Err(km_err!(
485                 IncompatiblePurpose,
486                 "curve25519 keys with invalid purpose {:?}",
487                 purpose
488             ))
489         }
490         (EcCurve::P224, _) => KeyGenInfo::NistEc(ec::NistCurve::P224),
491         (EcCurve::P256, _) => KeyGenInfo::NistEc(ec::NistCurve::P256),
492         (EcCurve::P384, _) => KeyGenInfo::NistEc(ec::NistCurve::P384),
493         (EcCurve::P521, _) => KeyGenInfo::NistEc(ec::NistCurve::P521),
494     };
495     Ok(keygen_info)
496 }
497 
498 /// Find the first purpose value in the parameters.
primary_purpose(params: &[KeyParam]) -> Result<KeyPurpose, Error>499 pub fn primary_purpose(params: &[KeyParam]) -> Result<KeyPurpose, Error> {
500     params
501         .iter()
502         .find_map(
503             |param| if let KeyParam::Purpose(purpose) = param { Some(*purpose) } else { None },
504         )
505         .ok_or_else(|| km_err!(IncompatiblePurpose, "no purpose found for key!"))
506 }
507 
508 /// Check EC key import parameter validity. Return the key material along with any key generation
509 /// parameters that have been deduced from the key material (but which are not present in the input
510 /// key parameters).
check_ec_import_params( ec: &dyn Ec, params: &[KeyParam], sec_level: SecurityLevel, key_format: KeyFormat, key_data: &[u8], ) -> Result<(Vec<KeyParam>, KeyMaterial), Error>511 fn check_ec_import_params(
512     ec: &dyn Ec,
513     params: &[KeyParam],
514     sec_level: SecurityLevel,
515     key_format: KeyFormat,
516     key_data: &[u8],
517 ) -> Result<(Vec<KeyParam>, KeyMaterial), Error> {
518     // Curve25519 can be imported as PKCS8 or raw; all other curves must be PKCS8.
519     // If we need to disinguish between Ed25519 and X25519, we need to examine the purpose for the
520     // key -- look for `AgreeKey` as it cannot be combined with other purposes.
521     let (key, curve) = match key_format {
522         KeyFormat::Raw if get_ec_curve(params)? == EcCurve::Curve25519 => {
523             // Raw key import must specify the curve (and the only valid option is Curve25519
524             // currently).
525             if primary_purpose(params)? == KeyPurpose::AgreeKey {
526                 (ec.import_raw_x25519_key(key_data, params)?, EcCurve::Curve25519)
527             } else {
528                 (ec.import_raw_ed25519_key(key_data, params)?, EcCurve::Curve25519)
529             }
530         }
531         KeyFormat::Pkcs8 => {
532             let key = ec.import_pkcs8_key(key_data, params)?;
533             let curve = match &key {
534                 KeyMaterial::Ec(curve, CurveType::Nist, _) => *curve,
535                 KeyMaterial::Ec(EcCurve::Curve25519, CurveType::EdDsa, _) => {
536                     if primary_purpose(params)? == KeyPurpose::AgreeKey {
537                         return Err(km_err!(
538                             IncompatiblePurpose,
539                             "can't use EdDSA key for key agreement"
540                         ));
541                     }
542                     EcCurve::Curve25519
543                 }
544                 KeyMaterial::Ec(EcCurve::Curve25519, CurveType::Xdh, _) => {
545                     if primary_purpose(params)? != KeyPurpose::AgreeKey {
546                         return Err(km_err!(IncompatiblePurpose, "can't use XDH key for signing"));
547                     }
548                     EcCurve::Curve25519
549                 }
550                 _ => {
551                     return Err(km_err!(
552                         ImportParameterMismatch,
553                         "unexpected key type from EC import"
554                     ))
555                 }
556             };
557             (key, curve)
558         }
559         _ => {
560             return Err(km_err!(
561                 UnsupportedKeyFormat,
562                 "invalid import format ({:?}) for EC key",
563                 key_format,
564             ));
565         }
566     };
567 
568     // If curve was explicitly specified, it must match. If not specified, populate it in the
569     // deduced characteristics.
570     let mut deduced_chars = Vec::new();
571     match get_opt_tag_value!(params, EcCurve)? {
572         Some(specified_curve) => {
573             if *specified_curve != curve {
574                 return Err(km_err!(
575                     ImportParameterMismatch,
576                     "imported EC key claimed curve {:?} but is {:?}",
577                     specified_curve,
578                     curve
579                 ));
580             }
581         }
582         None => deduced_chars.try_push(KeyParam::EcCurve(curve))?,
583     }
584 
585     // If key size was explicitly specified, it must match. If not specified, populate it in the
586     // deduced characteristics.
587     let key_size = ec::curve_to_key_size(curve);
588     match get_opt_tag_value!(params, KeySize)? {
589         Some(param_key_size) => {
590             if *param_key_size != key_size {
591                 return Err(km_err!(
592                     ImportParameterMismatch,
593                     "specified KEY_SIZE {:?} bits != actual key size {:?} for PKCS8 import",
594                     param_key_size,
595                     key_size
596                 ));
597             }
598         }
599         None => deduced_chars.try_push(KeyParam::KeySize(key_size))?,
600     }
601 
602     check_ec_params(curve, params, sec_level)?;
603     Ok((deduced_chars, key))
604 }
605 
606 /// Check the parameter validity for an EC key that is about to be generated or imported.
check_ec_params( curve: EcCurve, params: &[KeyParam], sec_level: SecurityLevel, ) -> Result<Option<KeyPurpose>, Error>607 fn check_ec_params(
608     curve: EcCurve,
609     params: &[KeyParam],
610     sec_level: SecurityLevel,
611 ) -> Result<Option<KeyPurpose>, Error> {
612     if sec_level == SecurityLevel::Strongbox && curve != EcCurve::P256 {
613         return Err(km_err!(UnsupportedEcCurve, "invalid curve ({:?}) for StrongBox", curve));
614     }
615 
616     // Key size is not needed, but if present should match the curve.
617     if let Some(key_size) = get_opt_tag_value!(params, KeySize)? {
618         match curve {
619             EcCurve::P224 if *key_size == KeySizeInBits(224) => {}
620             EcCurve::P256 if *key_size == KeySizeInBits(256) => {}
621             EcCurve::P384 if *key_size == KeySizeInBits(384) => {}
622             EcCurve::P521 if *key_size == KeySizeInBits(521) => {}
623             EcCurve::Curve25519 if *key_size == KeySizeInBits(256) => {}
624             _ => {
625                 return Err(km_err!(
626                     InvalidArgument,
627                     "invalid curve ({:?}) / key size ({:?}) combination",
628                     curve,
629                     key_size
630                 ))
631             }
632         }
633     }
634 
635     let mut seen_attest = false;
636     let mut seen_sign = false;
637     let mut seen_agree = false;
638     let mut primary_purpose = None;
639     for param in params {
640         if let KeyParam::Purpose(purpose) = param {
641             match purpose {
642                 KeyPurpose::Sign => seen_sign = true,
643                 KeyPurpose::AgreeKey => seen_agree = true,
644                 KeyPurpose::AttestKey => seen_attest = true,
645                 KeyPurpose::Verify => {}
646                 _ => warn!("Generating EC key with invalid purpose {:?}", purpose),
647             }
648             if primary_purpose.is_none() {
649                 primary_purpose = Some(*purpose);
650             }
651         }
652     }
653     // Keys with Purpose::ATTEST_KEY must have no other purpose.
654     if seen_attest && (seen_sign || seen_agree) {
655         return Err(km_err!(
656             IncompatiblePurpose,
657             "keys with ATTEST_KEY must have no other purpose"
658         ));
659     }
660     // Curve25519 keys must be either signing/attesting keys (Ed25519), or key agreement
661     // keys (X25519), not both.
662     if curve == EcCurve::Curve25519 && seen_agree && (seen_sign || seen_attest) {
663         return Err(km_err!(
664             IncompatiblePurpose,
665             "curve25519 keys must be either SIGN/ATTEST_KEY or AGREE_KEY, not both"
666         ));
667     }
668 
669     Ok(primary_purpose)
670 }
671 
672 /// Check AES key generation parameter validity.
check_aes_gen_params( params: &[KeyParam], sec_level: SecurityLevel, ) -> Result<KeyGenInfo, Error>673 fn check_aes_gen_params(
674     params: &[KeyParam],
675     sec_level: SecurityLevel,
676 ) -> Result<KeyGenInfo, Error> {
677     // For key generation, the size must be explicitly specified.
678     let key_size = get_tag_value!(params, KeySize, ErrorCode::UnsupportedKeySize)?;
679 
680     let keygen_info = match key_size {
681         KeySizeInBits(128) => KeyGenInfo::Aes(aes::Variant::Aes128),
682         KeySizeInBits(256) => KeyGenInfo::Aes(aes::Variant::Aes256),
683         KeySizeInBits(192) if sec_level != SecurityLevel::Strongbox => {
684             KeyGenInfo::Aes(aes::Variant::Aes192)
685         }
686         _ => {
687             return Err(km_err!(
688                 UnsupportedKeySize,
689                 "unsupported KEY_SIZE {:?} bits for AES",
690                 key_size
691             ))
692         }
693     };
694 
695     check_aes_params(params)?;
696     Ok(keygen_info)
697 }
698 
699 /// Check AES key import parameter validity. Return the key material along with any key generation
700 /// parameters that have been deduced from the key material (but which are not present in the input
701 /// key parameters).
check_aes_import_params( aes: &dyn Aes, params: &[KeyParam], sec_level: SecurityLevel, key_format: KeyFormat, key_data: &[u8], ) -> Result<(Vec<KeyParam>, KeyMaterial), Error>702 fn check_aes_import_params(
703     aes: &dyn Aes,
704     params: &[KeyParam],
705     sec_level: SecurityLevel,
706     key_format: KeyFormat,
707     key_data: &[u8],
708 ) -> Result<(Vec<KeyParam>, KeyMaterial), Error> {
709     require_raw(key_format)?;
710     let (key, key_size) = aes.import_key(key_data, params)?;
711     if key_size == KeySizeInBits(192) && sec_level == SecurityLevel::Strongbox {
712         return Err(km_err!(
713             UnsupportedKeySize,
714             "unsupported KEY_SIZE=192 bits for AES on StrongBox",
715         ));
716     }
717     let deduced_chars = require_matching_key_size(params, key_size)?;
718 
719     check_aes_params(params)?;
720     Ok((deduced_chars, key))
721 }
722 
723 /// Check the parameter validity for an AES key that is about to be generated or imported.
check_aes_params(params: &[KeyParam]) -> Result<(), Error>724 fn check_aes_params(params: &[KeyParam]) -> Result<(), Error> {
725     let gcm_support = params.iter().any(|p| *p == KeyParam::BlockMode(BlockMode::Gcm));
726     if gcm_support {
727         let min_mac_len = get_tag_value!(params, MinMacLength, ErrorCode::MissingMinMacLength)?;
728         if (min_mac_len % 8 != 0) || !(96..=128).contains(&min_mac_len) {
729             return Err(km_err!(
730                 UnsupportedMinMacLength,
731                 "unsupported MIN_MAC_LENGTH {} bits",
732                 min_mac_len
733             ));
734         }
735     }
736     Ok(())
737 }
738 
739 /// Check triple DES key generation parameter validity.
check_3des_gen_params(params: &[KeyParam]) -> Result<KeyGenInfo, Error>740 fn check_3des_gen_params(params: &[KeyParam]) -> Result<KeyGenInfo, Error> {
741     // For key generation, the size (168) must be explicitly specified.
742     let key_size = get_tag_value!(params, KeySize, ErrorCode::UnsupportedKeySize)?;
743     if key_size != KeySizeInBits(168) {
744         return Err(km_err!(
745             UnsupportedKeySize,
746             "unsupported KEY_SIZE {:?} bits for TRIPLE_DES",
747             key_size
748         ));
749     }
750     Ok(KeyGenInfo::TripleDes)
751 }
752 
753 /// Check triple DES key import parameter validity. Return the key material along with any key
754 /// generation parameters that have been deduced from the key material (but which are not present in
755 /// the input key parameters).
check_3des_import_params( des: &dyn Des, params: &[KeyParam], key_format: KeyFormat, key_data: &[u8], ) -> Result<(Vec<KeyParam>, KeyMaterial), Error>756 fn check_3des_import_params(
757     des: &dyn Des,
758     params: &[KeyParam],
759     key_format: KeyFormat,
760     key_data: &[u8],
761 ) -> Result<(Vec<KeyParam>, KeyMaterial), Error> {
762     require_raw(key_format)?;
763     let key = des.import_key(key_data, params)?;
764     // If the key size is specified as a parameter, it must be 168. Note that this
765     // is not equal to 8 x 24 (the data size).
766     let deduced_chars = require_matching_key_size(params, des::KEY_SIZE_BITS)?;
767 
768     Ok((deduced_chars, key))
769 }
770 
771 /// Check HMAC key generation parameter validity.
check_hmac_gen_params( params: &[KeyParam], sec_level: SecurityLevel, ) -> Result<KeyGenInfo, Error>772 fn check_hmac_gen_params(
773     params: &[KeyParam],
774     sec_level: SecurityLevel,
775 ) -> Result<KeyGenInfo, Error> {
776     // For key generation the size must be explicitly specified.
777     let key_size = get_tag_value!(params, KeySize, ErrorCode::UnsupportedKeySize)?;
778     check_hmac_params(params, sec_level, key_size)?;
779     Ok(KeyGenInfo::Hmac(key_size))
780 }
781 
782 /// Build the set of key characteristics for an HMAC key that is about to be imported,
783 /// checking parameter validity along the way.
check_hmac_import_params( hmac: &dyn Hmac, params: &[KeyParam], sec_level: SecurityLevel, key_format: KeyFormat, key_data: &[u8], ) -> Result<(Vec<KeyParam>, KeyMaterial), Error>784 fn check_hmac_import_params(
785     hmac: &dyn Hmac,
786     params: &[KeyParam],
787     sec_level: SecurityLevel,
788     key_format: KeyFormat,
789     key_data: &[u8],
790 ) -> Result<(Vec<KeyParam>, KeyMaterial), Error> {
791     require_raw(key_format)?;
792     let (key, key_size) = hmac.import_key(key_data, params)?;
793     let deduced_chars = require_matching_key_size(params, key_size)?;
794 
795     check_hmac_params(params, sec_level, key_size)?;
796     Ok((deduced_chars, key))
797 }
798 
799 /// Check the parameter validity for an HMAC key that is about to be generated or imported.
check_hmac_params( params: &[KeyParam], sec_level: SecurityLevel, key_size: KeySizeInBits, ) -> Result<(), Error>800 fn check_hmac_params(
801     params: &[KeyParam],
802     sec_level: SecurityLevel,
803     key_size: KeySizeInBits,
804 ) -> Result<(), Error> {
805     if sec_level == SecurityLevel::Strongbox {
806         hmac::valid_strongbox_hal_size(key_size)?;
807     } else {
808         hmac::valid_hal_size(key_size)?;
809     }
810     let digest = get_tag_value!(params, Digest, ErrorCode::UnsupportedDigest)?;
811     if digest == Digest::None {
812         return Err(km_err!(UnsupportedDigest, "unsupported digest {:?}", digest));
813     }
814 
815     let min_mac_len = get_tag_value!(params, MinMacLength, ErrorCode::MissingMinMacLength)?;
816     if (min_mac_len % 8 != 0) || !(64..=512).contains(&min_mac_len) {
817         return Err(km_err!(
818             UnsupportedMinMacLength,
819             "unsupported MIN_MAC_LENGTH {:?} bits",
820             min_mac_len
821         ));
822     }
823     Ok(())
824 }
825 
826 /// Check for `KeyFormat::RAW`.
require_raw(key_format: KeyFormat) -> Result<(), Error>827 fn require_raw(key_format: KeyFormat) -> Result<(), Error> {
828     if key_format != KeyFormat::Raw {
829         return Err(km_err!(
830             UnsupportedKeyFormat,
831             "unsupported import format {:?}, expect RAW",
832             key_format
833         ));
834     }
835     Ok(())
836 }
837 
838 /// Check or populate a `Tag::KEY_SIZE` value.
require_matching_key_size( params: &[KeyParam], key_size: KeySizeInBits, ) -> Result<Vec<KeyParam>, Error>839 fn require_matching_key_size(
840     params: &[KeyParam],
841     key_size: KeySizeInBits,
842 ) -> Result<Vec<KeyParam>, Error> {
843     let mut deduced_chars = Vec::new();
844     match get_opt_tag_value!(params, KeySize)? {
845         Some(param_key_size) => {
846             if *param_key_size != key_size {
847                 return Err(km_err!(
848                     ImportParameterMismatch,
849                     "specified KEY_SIZE {:?} bits != actual key size {:?}",
850                     param_key_size,
851                     key_size
852                 ));
853             }
854         }
855         None => deduced_chars.try_push(KeyParam::KeySize(key_size))?,
856     }
857     Ok(deduced_chars)
858 }
859 
860 /// Return an error if any of the `exclude` tags are found in `params`.
reject_tags(params: &[KeyParam], exclude: &[Tag]) -> Result<(), Error>861 fn reject_tags(params: &[KeyParam], exclude: &[Tag]) -> Result<(), Error> {
862     for param in params {
863         if exclude.contains(&param.tag()) {
864             return Err(km_err!(InvalidTag, "tag {:?} not allowed", param.tag()));
865         }
866     }
867     Ok(())
868 }
869 
870 /// Return an error if non-None padding found.
reject_some_padding(params: &[KeyParam]) -> Result<(), Error>871 fn reject_some_padding(params: &[KeyParam]) -> Result<(), Error> {
872     if let Some(padding) = get_opt_tag_value!(params, Padding)? {
873         if *padding != PaddingMode::None {
874             return Err(km_err!(InvalidTag, "padding {:?} not allowed", padding));
875         }
876     }
877     Ok(())
878 }
879 
880 /// Return an error if non-None digest found.
reject_some_digest(params: &[KeyParam]) -> Result<(), Error>881 fn reject_some_digest(params: &[KeyParam]) -> Result<(), Error> {
882     if let Some(digest) = get_opt_tag_value!(params, Digest)? {
883         if *digest != Digest::None {
884             return Err(km_err!(InvalidTag, "digest {:?} not allowed", digest));
885         }
886     }
887     Ok(())
888 }
889 
890 /// Reject incompatible combinations of authentication tags.
reject_incompatible_auth(params: &[KeyParam]) -> Result<(), Error>891 fn reject_incompatible_auth(params: &[KeyParam]) -> Result<(), Error> {
892     let mut seen_user_secure_id = false;
893     let mut seen_auth_type = false;
894     let mut seen_no_auth = false;
895 
896     for param in params {
897         match param {
898             KeyParam::UserSecureId(_sid) => seen_user_secure_id = true,
899             KeyParam::UserAuthType(_atype) => seen_auth_type = true,
900             KeyParam::NoAuthRequired => seen_no_auth = true,
901             _ => {}
902         }
903     }
904 
905     if seen_no_auth {
906         if seen_user_secure_id {
907             return Err(km_err!(InvalidTag, "found both NO_AUTH_REQUIRED and USER_SECURE_ID"));
908         }
909         if seen_auth_type {
910             return Err(km_err!(InvalidTag, "found both NO_AUTH_REQUIRED and USER_AUTH_TYPE"));
911         }
912     }
913     if seen_user_secure_id && !seen_auth_type {
914         return Err(km_err!(InvalidTag, "found USER_SECURE_ID but no USER_AUTH_TYPE"));
915     }
916     Ok(())
917 }
918 
919 /// Indication of which parameters on a `begin` need to be checked against key authorizations.
920 struct BeginParamsToCheck {
921     block_mode: bool,
922     padding: bool,
923     digest: bool,
924     mgf_digest: bool,
925 }
926 
927 /// Check that an operation with the given `purpose` and `params` can validly be started
928 /// using a key with characteristics `chars`.
check_begin_params( chars: &[KeyParam], purpose: KeyPurpose, params: &[KeyParam], ) -> Result<(), Error>929 pub fn check_begin_params(
930     chars: &[KeyParam],
931     purpose: KeyPurpose,
932     params: &[KeyParam],
933 ) -> Result<(), Error> {
934     // General checks for all algorithms.
935     let algo = get_algorithm(chars)?;
936     let valid_purpose = matches!(
937         (algo, purpose),
938         (Algorithm::Aes, KeyPurpose::Encrypt)
939             | (Algorithm::Aes, KeyPurpose::Decrypt)
940             | (Algorithm::TripleDes, KeyPurpose::Encrypt)
941             | (Algorithm::TripleDes, KeyPurpose::Decrypt)
942             | (Algorithm::Hmac, KeyPurpose::Sign)
943             | (Algorithm::Hmac, KeyPurpose::Verify)
944             | (Algorithm::Ec, KeyPurpose::Sign)
945             | (Algorithm::Ec, KeyPurpose::AttestKey)
946             | (Algorithm::Ec, KeyPurpose::AgreeKey)
947             | (Algorithm::Rsa, KeyPurpose::Sign)
948             | (Algorithm::Rsa, KeyPurpose::Decrypt)
949             | (Algorithm::Rsa, KeyPurpose::AttestKey)
950     );
951     if !valid_purpose {
952         return Err(km_err!(
953             UnsupportedPurpose,
954             "invalid purpose {:?} for {:?} key",
955             purpose,
956             algo
957         ));
958     }
959     if !contains_tag_value!(chars, Purpose, purpose) {
960         return Err(km_err!(
961             IncompatiblePurpose,
962             "purpose {:?} not in key characteristics",
963             purpose
964         ));
965     }
966     if get_bool_tag_value!(chars, StorageKey)? {
967         return Err(km_err!(StorageKeyUnsupported, "attempt to use storage key",));
968     }
969     let nonce = get_opt_tag_value!(params, Nonce)?;
970     if get_bool_tag_value!(chars, CallerNonce)? {
971         // Caller-provided nonces are allowed.
972     } else if nonce.is_some() && purpose == KeyPurpose::Encrypt {
973         return Err(km_err!(CallerNonceProhibited, "caller nonce not allowed for encryption"));
974     }
975 
976     // Further algorithm-specific checks.
977     let check = match algo {
978         Algorithm::Rsa => check_begin_rsa_params(chars, purpose, params),
979         Algorithm::Ec => check_begin_ec_params(chars, purpose, params),
980         Algorithm::Aes => check_begin_aes_params(chars, params, nonce.map(|v| v.as_ref())),
981         Algorithm::TripleDes => check_begin_3des_params(params, nonce.map(|v| v.as_ref())),
982         Algorithm::Hmac => check_begin_hmac_params(chars, purpose, params),
983     }?;
984 
985     // For various parameters, if they are specified in the begin parameters and they
986     // are relevant for the algorithm, then the same value must also exist in the key
987     // characteristics. Also, there can be only one distinct value in the parameters.
988     if check.block_mode {
989         if let Some(bmode) = get_opt_tag_value!(params, BlockMode, UnsupportedBlockMode)? {
990             if !contains_tag_value!(chars, BlockMode, *bmode) {
991                 return Err(km_err!(
992                     IncompatibleBlockMode,
993                     "block mode {:?} not in key characteristics {:?}",
994                     bmode,
995                     chars,
996                 ));
997             }
998         }
999     }
1000     if check.padding {
1001         if let Some(pmode) = get_opt_tag_value!(params, Padding, UnsupportedPaddingMode)? {
1002             if !contains_tag_value!(chars, Padding, *pmode) {
1003                 return Err(km_err!(
1004                     IncompatiblePaddingMode,
1005                     "padding mode {:?} not in key characteristics {:?}",
1006                     pmode,
1007                     chars,
1008                 ));
1009             }
1010         }
1011     }
1012     if check.digest {
1013         if let Some(digest) = get_opt_tag_value!(params, Digest, UnsupportedDigest)? {
1014             if !contains_tag_value!(chars, Digest, *digest) {
1015                 return Err(km_err!(
1016                     IncompatibleDigest,
1017                     "digest {:?} not in key characteristics",
1018                     digest,
1019                 ));
1020             }
1021         }
1022     }
1023     if check.mgf_digest {
1024         let mut mgf_digest_to_find =
1025             get_opt_tag_value!(params, RsaOaepMgfDigest, UnsupportedMgfDigest)?;
1026 
1027         let chars_have_mgf_digest =
1028             chars.iter().any(|param| matches!(param, KeyParam::RsaOaepMgfDigest(_)));
1029         if chars_have_mgf_digest && mgf_digest_to_find.is_none() {
1030             // The key characteristics include an explicit set of MGF digests, but the begin()
1031             // operation is using the default SHA1.  Check that this default is in the
1032             // characteristics.
1033             mgf_digest_to_find = Some(&Digest::Sha1);
1034         }
1035 
1036         if let Some(mgf_digest) = mgf_digest_to_find {
1037             if !contains_tag_value!(chars, RsaOaepMgfDigest, *mgf_digest) {
1038                 return Err(km_err!(
1039                     IncompatibleMgfDigest,
1040                     "MGF digest {:?} not in key characteristics",
1041                     mgf_digest,
1042                 ));
1043             }
1044         }
1045     }
1046     Ok(())
1047 }
1048 
1049 /// Indicate whether a [`KeyPurpose`] is for encryption/decryption.
for_encryption(purpose: KeyPurpose) -> bool1050 fn for_encryption(purpose: KeyPurpose) -> bool {
1051     purpose == KeyPurpose::Encrypt
1052         || purpose == KeyPurpose::Decrypt
1053         || purpose == KeyPurpose::WrapKey
1054 }
1055 
1056 /// Indicate whether a [`KeyPurpose`] is for signing.
for_signing(purpose: KeyPurpose) -> bool1057 fn for_signing(purpose: KeyPurpose) -> bool {
1058     purpose == KeyPurpose::Sign
1059 }
1060 
1061 /// Check that an RSA operation with the given `purpose` and `params` can validly be started
1062 /// using a key with characteristics `chars`.
check_begin_rsa_params( chars: &[KeyParam], purpose: KeyPurpose, params: &[KeyParam], ) -> Result<BeginParamsToCheck, Error>1063 fn check_begin_rsa_params(
1064     chars: &[KeyParam],
1065     purpose: KeyPurpose,
1066     params: &[KeyParam],
1067 ) -> Result<BeginParamsToCheck, Error> {
1068     let padding = get_padding_mode(params)?;
1069     let mut digest = None;
1070     if for_signing(purpose) || (for_encryption(purpose) && padding == PaddingMode::RsaOaep) {
1071         digest = Some(get_digest(params)?);
1072     }
1073     if for_signing(purpose) && padding == PaddingMode::None && digest != Some(Digest::None) {
1074         return Err(km_err!(
1075             IncompatibleDigest,
1076             "unpadded RSA sign requires Digest::None not {:?}",
1077             digest
1078         ));
1079     }
1080     match padding {
1081         PaddingMode::None => {}
1082         PaddingMode::RsaOaep if for_encryption(purpose) => {
1083             if digest.is_none() || digest == Some(Digest::None) {
1084                 return Err(km_err!(IncompatibleDigest, "digest required for RSA-OAEP"));
1085             }
1086             let mgf_digest = get_mgf_digest(params)?;
1087             if mgf_digest == Digest::None {
1088                 return Err(km_err!(
1089                     UnsupportedMgfDigest,
1090                     "MGF digest cannot be NONE for RSA-OAEP"
1091                 ));
1092             }
1093         }
1094         PaddingMode::RsaPss if for_signing(purpose) => {
1095             if let Some(digest) = digest {
1096                 let key_size_bits = get_tag_value!(chars, KeySize, ErrorCode::InvalidArgument)?;
1097                 let d = digest_len(digest)?;
1098                 if key_size_bits < KeySizeInBits(2 * d + 9) {
1099                     return Err(km_err!(
1100                         IncompatibleDigest,
1101                         "key size {:?} < 2*8*D={} + 9",
1102                         key_size_bits,
1103                         d
1104                     ));
1105                 }
1106             } else {
1107                 return Err(km_err!(IncompatibleDigest, "digest required for RSA-PSS"));
1108             }
1109         }
1110         PaddingMode::RsaPkcs115Encrypt if for_encryption(purpose) => {
1111             if digest.is_some() && digest != Some(Digest::None) {
1112                 warn!(
1113                     "ignoring digest {:?} provided for PKCS#1 v1.5 encryption/decryption",
1114                     digest
1115                 );
1116             }
1117         }
1118         PaddingMode::RsaPkcs115Sign if for_signing(purpose) => {
1119             if digest.is_none() {
1120                 return Err(km_err!(IncompatibleDigest, "digest required for RSA-PKCS_1_5_SIGN"));
1121             }
1122         }
1123         _ => {
1124             return Err(km_err!(
1125                 UnsupportedPaddingMode,
1126                 "purpose {:?} incompatible with padding {:?}",
1127                 purpose,
1128                 padding
1129             ))
1130         }
1131     }
1132 
1133     Ok(BeginParamsToCheck { block_mode: false, padding: true, digest: true, mgf_digest: true })
1134 }
1135 
1136 /// Check that an EC operation with the given `purpose` and `params` can validly be started
1137 /// using a key with characteristics `chars`.
check_begin_ec_params( chars: &[KeyParam], purpose: KeyPurpose, params: &[KeyParam], ) -> Result<BeginParamsToCheck, Error>1138 fn check_begin_ec_params(
1139     chars: &[KeyParam],
1140     purpose: KeyPurpose,
1141     params: &[KeyParam],
1142 ) -> Result<BeginParamsToCheck, Error> {
1143     let curve = get_ec_curve(chars)?;
1144     if purpose == KeyPurpose::Sign {
1145         let digest = get_digest(params)?;
1146         if digest == Digest::Md5 {
1147             return Err(km_err!(UnsupportedDigest, "Digest::MD5 unsupported for EC signing"));
1148         }
1149         if curve == EcCurve::Curve25519 && digest != Digest::None {
1150             return Err(km_err!(
1151                 UnsupportedDigest,
1152                 "Ed25519 only supports Digest::None not {:?}",
1153                 digest
1154             ));
1155         }
1156     }
1157     Ok(BeginParamsToCheck { block_mode: false, padding: false, digest: true, mgf_digest: false })
1158 }
1159 
1160 /// Check that an AES operation with the given `purpose` and `params` can validly be started
1161 /// using a key with characteristics `chars`.
check_begin_aes_params( chars: &[KeyParam], params: &[KeyParam], caller_nonce: Option<&[u8]>, ) -> Result<BeginParamsToCheck, Error>1162 fn check_begin_aes_params(
1163     chars: &[KeyParam],
1164     params: &[KeyParam],
1165     caller_nonce: Option<&[u8]>,
1166 ) -> Result<BeginParamsToCheck, Error> {
1167     reject_tags(params, &[Tag::RsaOaepMgfDigest])?;
1168     reject_some_digest(params)?;
1169     let bmode = get_block_mode(params)?;
1170     let padding = get_padding_mode(params)?;
1171 
1172     if bmode == BlockMode::Gcm {
1173         let mac_len = get_tag_value!(params, MacLength, ErrorCode::MissingMacLength)?;
1174         if mac_len % 8 != 0 || mac_len > 128 {
1175             return Err(km_err!(UnsupportedMacLength, "invalid mac len {}", mac_len));
1176         }
1177         let min_mac_len = get_tag_value!(chars, MinMacLength, ErrorCode::MissingMinMacLength)?;
1178         if mac_len < min_mac_len {
1179             return Err(km_err!(
1180                 InvalidMacLength,
1181                 "mac len {} less than min {}",
1182                 mac_len,
1183                 min_mac_len
1184             ));
1185         }
1186     }
1187     match bmode {
1188         BlockMode::Gcm | BlockMode::Ctr => match padding {
1189             PaddingMode::None => {}
1190             _ => {
1191                 return Err(km_err!(
1192                     IncompatiblePaddingMode,
1193                     "padding {:?} not valid for AES GCM/CTR",
1194                     padding
1195                 ))
1196             }
1197         },
1198         BlockMode::Ecb | BlockMode::Cbc => match padding {
1199             PaddingMode::None | PaddingMode::Pkcs7 => {}
1200             _ => {
1201                 return Err(km_err!(
1202                     IncompatiblePaddingMode,
1203                     "padding {:?} not valid for AES GCM/CTR",
1204                     padding
1205                 ))
1206             }
1207         },
1208     }
1209 
1210     if let Some(nonce) = caller_nonce {
1211         match bmode {
1212             BlockMode::Cbc if nonce.len() == 16 => {}
1213             BlockMode::Ctr if nonce.len() == 16 => {}
1214             BlockMode::Gcm if nonce.len() == 12 => {}
1215             _ => {
1216                 return Err(km_err!(
1217                     InvalidNonce,
1218                     "invalid caller nonce len {} for {:?}",
1219                     nonce.len(),
1220                     bmode
1221                 ))
1222             }
1223         }
1224     }
1225     Ok(BeginParamsToCheck { block_mode: true, padding: true, digest: false, mgf_digest: false })
1226 }
1227 
1228 /// Check that a 3-DES operation with the given `purpose` and `params` can validly be started
1229 /// using a key with characteristics `chars`.
check_begin_3des_params( params: &[KeyParam], caller_nonce: Option<&[u8]>, ) -> Result<BeginParamsToCheck, Error>1230 fn check_begin_3des_params(
1231     params: &[KeyParam],
1232     caller_nonce: Option<&[u8]>,
1233 ) -> Result<BeginParamsToCheck, Error> {
1234     reject_tags(params, &[Tag::RsaOaepMgfDigest])?;
1235     reject_some_digest(params)?;
1236     let bmode = get_block_mode(params)?;
1237     let _padding = get_padding_mode(params)?;
1238 
1239     match bmode {
1240         BlockMode::Cbc | BlockMode::Ecb => {}
1241         _ => {
1242             return Err(km_err!(UnsupportedBlockMode, "block mode {:?} not valid for 3-DES", bmode))
1243         }
1244     }
1245 
1246     if let Some(nonce) = caller_nonce {
1247         match bmode {
1248             BlockMode::Cbc if nonce.len() == 8 => {}
1249             _ => {
1250                 return Err(km_err!(
1251                     InvalidNonce,
1252                     "invalid caller nonce len {} for {:?}",
1253                     nonce.len(),
1254                     bmode
1255                 ))
1256             }
1257         }
1258     }
1259     Ok(BeginParamsToCheck { block_mode: true, padding: true, digest: false, mgf_digest: false })
1260 }
1261 
1262 /// Check that an HMAC operation with the given `purpose` and `params` can validly be started
1263 /// using a key with characteristics `chars`.
check_begin_hmac_params( chars: &[KeyParam], purpose: KeyPurpose, params: &[KeyParam], ) -> Result<BeginParamsToCheck, Error>1264 fn check_begin_hmac_params(
1265     chars: &[KeyParam],
1266     purpose: KeyPurpose,
1267     params: &[KeyParam],
1268 ) -> Result<BeginParamsToCheck, Error> {
1269     reject_tags(params, &[Tag::BlockMode, Tag::RsaOaepMgfDigest])?;
1270     reject_some_padding(params)?;
1271     let digest = get_digest(params)?;
1272     if purpose == KeyPurpose::Sign {
1273         let mac_len = get_tag_value!(params, MacLength, ErrorCode::MissingMacLength)?;
1274         if mac_len % 8 != 0 || mac_len > digest_len(digest)? {
1275             return Err(km_err!(UnsupportedMacLength, "invalid mac len {}", mac_len));
1276         }
1277         let min_mac_len = get_tag_value!(chars, MinMacLength, ErrorCode::MissingMinMacLength)?;
1278         if mac_len < min_mac_len {
1279             return Err(km_err!(
1280                 InvalidMacLength,
1281                 "mac len {} less than min {}",
1282                 mac_len,
1283                 min_mac_len
1284             ));
1285         }
1286     }
1287 
1288     Ok(BeginParamsToCheck { block_mode: false, padding: false, digest: true, mgf_digest: false })
1289 }
1290 
1291 /// Return the length in bits of a [`Digest`] function.
digest_len(digest: Digest) -> Result<u32, Error>1292 pub fn digest_len(digest: Digest) -> Result<u32, Error> {
1293     match digest {
1294         Digest::Md5 => Ok(128),
1295         Digest::Sha1 => Ok(160),
1296         Digest::Sha224 => Ok(224),
1297         Digest::Sha256 => Ok(256),
1298         Digest::Sha384 => Ok(384),
1299         Digest::Sha512 => Ok(512),
1300         _ => Err(km_err!(IncompatibleDigest, "invalid digest {:?}", digest)),
1301     }
1302 }
1303 
1304 /// Check the required key params for an RSA wrapping key used in secure import and return the
1305 /// [`DecryptionMode`] constructed from the processed key characteristics.
check_rsa_wrapping_key_params( chars: &[KeyParam], params: &[KeyParam], ) -> Result<DecryptionMode, Error>1306 pub fn check_rsa_wrapping_key_params(
1307     chars: &[KeyParam],
1308     params: &[KeyParam],
1309 ) -> Result<DecryptionMode, Error> {
1310     // Check the purpose of the wrapping key
1311     if !contains_tag_value!(chars, Purpose, KeyPurpose::WrapKey) {
1312         return Err(km_err!(IncompatiblePurpose, "no wrap key purpose for the wrapping key"));
1313     }
1314     let padding_mode = get_tag_value!(params, Padding, ErrorCode::IncompatiblePaddingMode)?;
1315     if padding_mode != PaddingMode::RsaOaep {
1316         return Err(km_err!(
1317             IncompatiblePaddingMode,
1318             "invalid padding mode {:?} for RSA wrapping key",
1319             padding_mode
1320         ));
1321     }
1322     let msg_digest = get_tag_value!(params, Digest, ErrorCode::IncompatibleDigest)?;
1323     if msg_digest != Digest::Sha256 {
1324         return Err(km_err!(
1325             IncompatibleDigest,
1326             "invalid digest {:?} for RSA wrapping key",
1327             padding_mode
1328         ));
1329     }
1330     let opt_mgf_digest = get_opt_tag_value!(params, RsaOaepMgfDigest)?;
1331     if opt_mgf_digest == Some(&Digest::None) {
1332         return Err(km_err!(UnsupportedMgfDigest, "MGF digest cannot be NONE for RSA-OAEP"));
1333     }
1334 
1335     if !contains_tag_value!(chars, Padding, padding_mode) {
1336         return Err(km_err!(
1337             IncompatiblePaddingMode,
1338             "padding mode {:?} not in key characteristics {:?}",
1339             padding_mode,
1340             chars,
1341         ));
1342     }
1343     if !contains_tag_value!(chars, Digest, msg_digest) {
1344         return Err(km_err!(
1345             IncompatibleDigest,
1346             "digest {:?} not in key characteristics {:?}",
1347             msg_digest,
1348             chars,
1349         ));
1350     }
1351 
1352     if let Some(mgf_digest) = opt_mgf_digest {
1353         // MGF digest explicitly specified, check it is in key characteristics.
1354         if !contains_tag_value!(chars, RsaOaepMgfDigest, *mgf_digest) {
1355             return Err(km_err!(
1356                 IncompatibleDigest,
1357                 "MGF digest {:?} not in key characteristics {:?}",
1358                 mgf_digest,
1359                 chars,
1360             ));
1361         }
1362     }
1363     let mgf_digest = opt_mgf_digest.unwrap_or(&Digest::Sha1);
1364 
1365     let rsa_oaep_decrypt_mode = DecryptionMode::OaepPadding { msg_digest, mgf_digest: *mgf_digest };
1366     Ok(rsa_oaep_decrypt_mode)
1367 }
1368 
1369 /// Calculate the [Luhn checksum](https://en.wikipedia.org/wiki/Luhn_algorithm) of the given number.
luhn_checksum(mut val: u64) -> u641370 fn luhn_checksum(mut val: u64) -> u64 {
1371     let mut ii = 0;
1372     let mut sum_digits = 0;
1373     while val != 0 {
1374         let curr_digit = val % 10;
1375         let multiplier = if ii % 2 == 0 { 2 } else { 1 };
1376         let digit_multiplied = curr_digit * multiplier;
1377         sum_digits += (digit_multiplied % 10) + (digit_multiplied / 10);
1378         val /= 10;
1379         ii += 1;
1380     }
1381     (10 - (sum_digits % 10)) % 10
1382 }
1383 
1384 /// Derive an IMEI value from a first IMEI value, by incrementing by one and re-calculating
1385 /// the Luhn checksum.  Return an empty vector on any failure.
increment_imei(imei: &[u8]) -> Vec<u8>1386 pub fn increment_imei(imei: &[u8]) -> Vec<u8> {
1387     if imei.is_empty() {
1388         info!("empty IMEI");
1389         return Vec::new();
1390     }
1391 
1392     // Expect ASCII digits.
1393     let imei: &str = match core::str::from_utf8(imei) {
1394         Ok(v) => v,
1395         Err(_) => {
1396             warn!("IMEI is not UTF-8");
1397             return Vec::new();
1398         }
1399     };
1400     let imei: u64 = match imei.parse() {
1401         Ok(v) => v,
1402         Err(_) => {
1403             warn!("IMEI is not numeric");
1404             return Vec::new();
1405         }
1406     };
1407 
1408     // Drop trailing checksum digit, increment, and restore checksum.
1409     let imei2 = (imei / 10) + 1;
1410     let imei2 = (imei2 * 10) + luhn_checksum(imei2);
1411 
1412     // Convert back to bytes.
1413     alloc::format!("{}", imei2).into_bytes()
1414 }
1415