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