1use crate::requests::{ResponseStatus, Result};
8use psa_crypto::types::algorithm::*;
9use psa_crypto::types::key;
10use psa_crypto::types::key::Type;
11
12fn get_deprecated_hashes() -> Vec<Hash> {
13 vec![Hash::Md2, Hash::Md4, Hash::Md5, Hash::Sha1]
14}
15
16pub fn is_hash_deprecated(hash: Hash) -> bool {
18 get_deprecated_hashes().contains(&hash)
19}
20
21pub fn is_signhash_deprecated(signhash: SignHash) -> bool {
23 match signhash {
24 SignHash::Specific(hash) => is_hash_deprecated(hash),
25 SignHash::Any => false,
26 }
27}
28
29pub fn is_mac_deprecated(mac: Mac) -> bool {
31 pub fn is_full_length_mac_deprecated(full_length_mac: FullLengthMac) -> bool {
32 match full_length_mac {
33 FullLengthMac::Hmac { hash_alg } => is_hash_deprecated(hash_alg),
34 _ => false,
35 }
36 }
37 match mac {
38 Mac::FullLength(full_length_mac) => is_full_length_mac_deprecated(full_length_mac),
39 Mac::Truncated { mac_alg, .. } => is_full_length_mac_deprecated(mac_alg),
40 }
41}
42
43pub fn is_cipher_deprecated(_cipher: Cipher) -> bool {
45 false
46}
47
48pub fn is_aead_deprecated(_aead: Aead) -> bool {
50 false
51}
52
53pub fn is_asymmetric_signature_deprecated(asymm_sig: AsymmetricSignature) -> bool {
55 match asymm_sig {
56 AsymmetricSignature::RsaPkcs1v15Sign { hash_alg }
57 | AsymmetricSignature::RsaPss { hash_alg }
58 | AsymmetricSignature::Ecdsa { hash_alg }
59 | AsymmetricSignature::DeterministicEcdsa { hash_alg } => is_signhash_deprecated(hash_alg),
60 _ => false,
61 }
62}
63
64pub fn is_asymmetric_encryption_deprecated(asymm_enc: AsymmetricEncryption) -> bool {
66 match asymm_enc {
67 AsymmetricEncryption::RsaOaep { hash_alg } => is_hash_deprecated(hash_alg),
68 _ => false,
69 }
70}
71
72pub fn is_key_agreement_deprecated(key_agreement: KeyAgreement) -> bool {
74 match key_agreement {
75 KeyAgreement::WithKeyDerivation { kdf_alg, .. } => is_key_derivation_deprecated(kdf_alg),
76 _ => false,
77 }
78}
79
80pub fn is_key_derivation_deprecated(keyderv: KeyDerivation) -> bool {
82 match keyderv {
83 KeyDerivation::Hkdf { hash_alg }
84 | KeyDerivation::Tls12Prf { hash_alg }
85 | KeyDerivation::Tls12PskToMs { hash_alg } => is_hash_deprecated(hash_alg),
86 }
87}
88
89pub fn is_algorithm_deprecated(alg: Algorithm) -> bool {
91 match alg {
92 Algorithm::None => false,
93 Algorithm::Hash(hash) => is_hash_deprecated(hash),
94 Algorithm::Mac(mac) => is_mac_deprecated(mac),
95 Algorithm::Cipher(cipher) => is_cipher_deprecated(cipher),
96 Algorithm::Aead(aead) => is_aead_deprecated(aead),
97 Algorithm::AsymmetricSignature(asymm_sig) => is_asymmetric_signature_deprecated(asymm_sig),
98 Algorithm::AsymmetricEncryption(asymm_enc) => {
99 is_asymmetric_encryption_deprecated(asymm_enc)
100 }
101 Algorithm::KeyAgreement(key_agreement) => is_key_agreement_deprecated(key_agreement),
102 Algorithm::KeyDerivation(keyderv) => is_key_derivation_deprecated(keyderv),
103 }
104}
105
106fn get_deprecated_keys() -> Vec<(Type, Option<usize>)> {
108 vec![
109 (Type::Des, None),
110 (Type::Arc4, None),
111 (
112 Type::EccPublicKey {
113 curve_family: key::EccFamily::BrainpoolPR1,
114 },
115 Some(160),
116 ),
117 (
118 Type::EccPublicKey {
119 curve_family: key::EccFamily::SectR2,
120 },
121 None,
122 ),
123 (
124 Type::EccPublicKey {
125 curve_family: key::EccFamily::SectR1,
126 },
127 Some(163),
128 ),
129 (
130 Type::EccPublicKey {
131 curve_family: key::EccFamily::SectK1,
132 },
133 Some(163),
134 ),
135 (
136 Type::EccPublicKey {
137 curve_family: key::EccFamily::SecpR2,
138 },
139 None,
140 ),
141 ]
142}
143
144pub fn is_key_deprecated(key_type: Type, key_size: usize) -> bool {
146 for (ktype, ksize) in get_deprecated_keys() {
147 if ktype == key_type && (ksize.is_none() || ksize == Some(key_size)) {
148 return true;
149 }
150 }
151 false
152}
153
154pub trait CheckDeprecated {
156 fn check_deprecated(&self) -> Result<()>;
159}
160
161impl CheckDeprecated for crate::operations::psa_import_key::Operation {
162 fn check_deprecated(&self) -> Result<()> {
164 if is_algorithm_deprecated(self.attributes.policy.permitted_algorithms)
165 || is_key_deprecated(self.attributes.key_type, self.attributes.bits)
166 {
167 return Err(ResponseStatus::DeprecatedPrimitive);
168 }
169 Ok(())
170 }
171}
172
173impl CheckDeprecated for crate::operations::psa_generate_key::Operation {
174 fn check_deprecated(&self) -> Result<()> {
176 if is_algorithm_deprecated(self.attributes.policy.permitted_algorithms)
177 || is_key_deprecated(self.attributes.key_type, self.attributes.bits)
178 {
179 return Err(ResponseStatus::DeprecatedPrimitive);
180 }
181 Ok(())
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188 fn get_selection_non_deprecated_hashes() -> Vec<Hash> {
189 vec![Hash::Sha256, Hash::Sha3_512, Hash::Sha384, Hash::Ripemd160]
190 }
191
192 fn get_deprecated_macs() -> Vec<Mac> {
193 let mut deprecated_macs: Vec<Mac> = vec![];
194 for hash in get_deprecated_hashes() {
195 deprecated_macs.push(Mac::FullLength(FullLengthMac::Hmac { hash_alg: hash }));
196 deprecated_macs.push(Mac::Truncated {
198 mac_alg: FullLengthMac::Hmac { hash_alg: hash },
199 mac_length: 1234,
200 });
201 }
202 deprecated_macs
203 }
204
205 fn get_selection_non_deprecated_macs() -> Vec<Mac> {
206 let mut selection_non_deprecated_macs: Vec<Mac> = vec![
207 Mac::FullLength(FullLengthMac::CbcMac),
208 Mac::FullLength(FullLengthMac::Cmac),
209 Mac::Truncated {
210 mac_alg: FullLengthMac::CbcMac,
211 mac_length: 1234,
213 },
214 Mac::Truncated {
215 mac_alg: FullLengthMac::Cmac,
216 mac_length: 1234,
218 },
219 ];
220 for hash in get_selection_non_deprecated_hashes() {
221 selection_non_deprecated_macs
222 .push(Mac::FullLength(FullLengthMac::Hmac { hash_alg: hash }));
223 selection_non_deprecated_macs.push(Mac::Truncated {
224 mac_alg: FullLengthMac::Hmac { hash_alg: hash },
225 mac_length: 1234,
227 });
228 }
229 selection_non_deprecated_macs
230 }
231
232 fn get_deprecated_ciphers() -> Vec<Cipher> {
233 vec![]
234 }
235
236 fn get_selection_non_deprecated_ciphers() -> Vec<Cipher> {
237 vec![Cipher::Ctr, Cipher::CbcNoPadding, Cipher::StreamCipher]
238 }
239
240 fn get_deprecated_aeads() -> Vec<Aead> {
241 vec![]
242 }
243
244 fn get_selection_non_deprecated_aeads() -> Vec<Aead> {
245 vec![
246 Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Ccm),
247 Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Gcm),
248 Aead::AeadWithShortenedTag {
250 aead_alg: AeadWithDefaultLengthTag::Chacha20Poly1305,
251 tag_length: 121,
252 },
253 Aead::AeadWithShortenedTag {
254 aead_alg: AeadWithDefaultLengthTag::Ccm,
255 tag_length: 212,
256 },
257 ]
258 }
259
260 fn get_deprecated_asymmetric_signatures() -> Vec<AsymmetricSignature> {
261 let mut deprecated_asymmetric_signatures = vec![];
262 for hash in get_deprecated_hashes() {
263 deprecated_asymmetric_signatures.push(AsymmetricSignature::RsaPkcs1v15Sign {
264 hash_alg: hash.into(),
265 });
266 deprecated_asymmetric_signatures.push(AsymmetricSignature::RsaPss {
267 hash_alg: hash.into(),
268 });
269 deprecated_asymmetric_signatures.push(AsymmetricSignature::Ecdsa {
270 hash_alg: hash.into(),
271 });
272 deprecated_asymmetric_signatures.push(AsymmetricSignature::DeterministicEcdsa {
273 hash_alg: hash.into(),
274 });
275 }
276 deprecated_asymmetric_signatures
277 }
278
279 fn get_selection_non_deprecated_asymmetric_signatures() -> Vec<AsymmetricSignature> {
280 let mut selection_non_deprecated_asymmetric_signatures = vec![
281 AsymmetricSignature::RsaPkcs1v15SignRaw,
282 AsymmetricSignature::EcdsaAny,
283 ];
284 for hash in get_selection_non_deprecated_hashes() {
285 selection_non_deprecated_asymmetric_signatures.push(
286 AsymmetricSignature::RsaPkcs1v15Sign {
287 hash_alg: hash.into(),
288 },
289 );
290 selection_non_deprecated_asymmetric_signatures.push(AsymmetricSignature::RsaPss {
291 hash_alg: hash.into(),
292 });
293 selection_non_deprecated_asymmetric_signatures.push(AsymmetricSignature::Ecdsa {
294 hash_alg: hash.into(),
295 });
296 selection_non_deprecated_asymmetric_signatures.push(
297 AsymmetricSignature::DeterministicEcdsa {
298 hash_alg: hash.into(),
299 },
300 );
301 }
302 selection_non_deprecated_asymmetric_signatures
303 }
304
305 fn get_deprecated_asymmetric_encryptions() -> Vec<AsymmetricEncryption> {
306 let mut deprecated_asymmetric_encryptions = vec![];
307 for hash in get_deprecated_hashes() {
308 deprecated_asymmetric_encryptions
309 .push(AsymmetricEncryption::RsaOaep { hash_alg: hash });
310 }
311 deprecated_asymmetric_encryptions
312 }
313
314 fn get_selection_non_deprecated_asymmetric_encryptions() -> Vec<AsymmetricEncryption> {
315 let mut selection_non_deprecated_asymmetric_encryptions =
316 vec![AsymmetricEncryption::RsaPkcs1v15Crypt];
317 for hash in get_selection_non_deprecated_hashes() {
318 selection_non_deprecated_asymmetric_encryptions
319 .push(AsymmetricEncryption::RsaOaep { hash_alg: hash });
320 }
321 selection_non_deprecated_asymmetric_encryptions
322 }
323
324 fn get_deprecated_key_derivations() -> Vec<KeyDerivation> {
325 let mut deprecated_key_derivations = vec![];
326 for hash in get_deprecated_hashes() {
327 deprecated_key_derivations.push(KeyDerivation::Hkdf { hash_alg: hash });
328 deprecated_key_derivations.push(KeyDerivation::Tls12Prf { hash_alg: hash });
329 deprecated_key_derivations.push(KeyDerivation::Tls12PskToMs { hash_alg: hash });
330 }
331 deprecated_key_derivations
332 }
333
334 fn get_selection_non_deprecated_key_derivations() -> Vec<KeyDerivation> {
335 let mut selection_non_deprecated_key_derivations = vec![];
336 for hash in get_selection_non_deprecated_hashes() {
337 selection_non_deprecated_key_derivations.push(KeyDerivation::Hkdf { hash_alg: hash });
338 selection_non_deprecated_key_derivations
339 .push(KeyDerivation::Tls12Prf { hash_alg: hash });
340 selection_non_deprecated_key_derivations
341 .push(KeyDerivation::Tls12PskToMs { hash_alg: hash });
342 }
343 selection_non_deprecated_key_derivations
344 }
345
346 fn get_deprecated_key_agreements() -> Vec<KeyAgreement> {
347 let mut deprecated_key_agreements = vec![];
348 for keyderv in get_deprecated_key_derivations() {
349 deprecated_key_agreements.push(KeyAgreement::WithKeyDerivation {
350 ka_alg: RawKeyAgreement::Ffdh,
351 kdf_alg: keyderv,
352 });
353 deprecated_key_agreements.push(KeyAgreement::WithKeyDerivation {
354 ka_alg: RawKeyAgreement::Ecdh,
355 kdf_alg: keyderv,
356 });
357 }
358 deprecated_key_agreements
359 }
360
361 fn get_selection_non_deprecated_key_agreements() -> Vec<KeyAgreement> {
362 let mut selection_non_deprecated_key_agreements = vec![];
363 for keyderv in get_selection_non_deprecated_key_derivations() {
364 selection_non_deprecated_key_agreements.push(KeyAgreement::WithKeyDerivation {
365 ka_alg: RawKeyAgreement::Ffdh,
366 kdf_alg: keyderv,
367 });
368 selection_non_deprecated_key_agreements.push(KeyAgreement::WithKeyDerivation {
369 ka_alg: RawKeyAgreement::Ecdh,
370 kdf_alg: keyderv,
371 });
372 }
373 selection_non_deprecated_key_agreements.push(KeyAgreement::Raw(RawKeyAgreement::Ffdh));
374 selection_non_deprecated_key_agreements.push(KeyAgreement::Raw(RawKeyAgreement::Ecdh));
375 selection_non_deprecated_key_agreements
376 }
377
378 fn get_deprecated_algorithms() -> Vec<Algorithm> {
379 let mut deprecated_algorithms: Vec<Algorithm> = vec![];
380 for hash in get_deprecated_hashes() {
382 deprecated_algorithms.push(Algorithm::Hash(hash));
383 }
384
385 for mac in get_deprecated_macs() {
387 deprecated_algorithms.push(Algorithm::Mac(mac));
388 }
389
390 for cipher in get_deprecated_ciphers() {
392 deprecated_algorithms.push(Algorithm::Cipher(cipher));
393 }
394 for aead in get_deprecated_aeads() {
396 deprecated_algorithms.push(Algorithm::Aead(aead));
397 }
398
399 for asymm_sig in get_deprecated_asymmetric_signatures() {
401 deprecated_algorithms.push(Algorithm::AsymmetricSignature(asymm_sig));
402 }
403
404 for asymm_enc in get_deprecated_asymmetric_encryptions() {
406 deprecated_algorithms.push(Algorithm::AsymmetricEncryption(asymm_enc));
407 }
408
409 for key_derv in get_deprecated_key_derivations() {
411 deprecated_algorithms.push(Algorithm::KeyDerivation(key_derv));
412 }
413
414 for key_agreement in get_deprecated_key_agreements() {
416 deprecated_algorithms.push(Algorithm::KeyAgreement(key_agreement));
417 }
418 deprecated_algorithms
419 }
420
421 fn get_selection_non_deprecated_algorithms() -> Vec<Algorithm> {
422 let mut selection_non_deprecated_algorithms: Vec<Algorithm> = vec![];
423 for hash in get_selection_non_deprecated_hashes() {
425 selection_non_deprecated_algorithms.push(Algorithm::Hash(hash));
426 }
427
428 for mac in get_selection_non_deprecated_macs() {
430 selection_non_deprecated_algorithms.push(Algorithm::Mac(mac));
431 }
432
433 for cipher in get_selection_non_deprecated_ciphers() {
435 selection_non_deprecated_algorithms.push(Algorithm::Cipher(cipher));
436 }
437 for aead in get_selection_non_deprecated_aeads() {
439 selection_non_deprecated_algorithms.push(Algorithm::Aead(aead));
440 }
441
442 for asymm_sig in get_selection_non_deprecated_asymmetric_signatures() {
444 selection_non_deprecated_algorithms.push(Algorithm::AsymmetricSignature(asymm_sig));
445 }
446
447 for asymm_enc in get_selection_non_deprecated_asymmetric_encryptions() {
449 selection_non_deprecated_algorithms.push(Algorithm::AsymmetricEncryption(asymm_enc));
450 }
451
452 for key_derv in get_selection_non_deprecated_key_derivations() {
454 selection_non_deprecated_algorithms.push(Algorithm::KeyDerivation(key_derv));
455 }
456
457 for key_agreement in get_selection_non_deprecated_key_agreements() {
459 selection_non_deprecated_algorithms.push(Algorithm::KeyAgreement(key_agreement));
460 }
461 selection_non_deprecated_algorithms
462 }
463
464 #[test]
465 fn deprecated_algorithms() {
466 for algo in get_deprecated_algorithms() {
467 assert!(is_algorithm_deprecated(algo), "algorithm: {algo:?}");
468 }
469 }
470
471 #[test]
472 fn non_deprecated_algorithms() {
473 for algo in get_selection_non_deprecated_algorithms() {
474 assert!(!is_algorithm_deprecated(algo), "algorithm: {algo:?}");
475 }
476 }
477
478 #[test]
479 fn deprecated_keys() {
480 let test_keys = vec![
481 (
482 Type::EccPublicKey {
483 curve_family: key::EccFamily::SecpR2,
484 },
485 160,
486 ),
487 (
488 Type::EccPublicKey {
489 curve_family: key::EccFamily::SectK1,
490 },
491 163,
492 ),
493 (
494 Type::EccPublicKey {
495 curve_family: key::EccFamily::SectR1,
496 },
497 163,
498 ),
499 (
500 Type::EccPublicKey {
501 curve_family: key::EccFamily::SectR2,
502 },
503 163,
504 ),
505 (
506 Type::EccPublicKey {
507 curve_family: key::EccFamily::BrainpoolPR1,
508 },
509 160,
510 ),
511 (Type::Des, 56),
512 (Type::Des, 56 * 2),
513 (Type::Des, 56 * 3),
514 (Type::Arc4, 40),
515 (Type::Arc4, 2048),
516 ];
517 for (ktype, ksize) in test_keys {
518 assert!(
519 is_key_deprecated(ktype, ksize),
520 "key: ({ktype:?} : {ksize:?})"
521 );
522 }
523 }
524
525 #[test]
526 fn non_deprecated_keys() {
527 let test_keys = vec![
528 (
529 Type::EccPublicKey {
530 curve_family: key::EccFamily::SecpK1,
531 },
532 192,
533 ),
534 (
535 Type::EccPublicKey {
536 curve_family: key::EccFamily::SecpR1,
537 },
538 256,
539 ),
540 (
541 Type::EccPublicKey {
542 curve_family: key::EccFamily::SectK1,
543 },
544 239,
545 ),
546 (
547 Type::EccPublicKey {
548 curve_family: key::EccFamily::SectR1,
549 },
550 409,
551 ),
552 (
553 Type::EccPublicKey {
554 curve_family: key::EccFamily::BrainpoolPR1,
555 },
556 192,
557 ),
558 (
559 Type::EccPublicKey {
560 curve_family: key::EccFamily::BrainpoolPR1,
561 },
562 256,
563 ),
564 (Type::Aes, 256),
565 (Type::RsaPublicKey, 2048),
566 (Type::Hmac, 128),
567 (Type::Chacha20, 256),
568 ];
569 for (ktype, ksize) in test_keys {
570 assert!(
571 !is_key_deprecated(ktype, ksize),
572 "key: ({ktype:?} : {ksize:?})"
573 );
574 }
575 }
576
577 #[test]
578 fn op_check_deprecated_for_deprecated() {
579 use psa_crypto::types::key::{Attributes, Lifetime, Policy, UsageFlags};
580 let mut generate_key_op = crate::operations::psa_generate_key::Operation {
581 key_name: "dummy".to_string(),
582 attributes: Attributes {
583 lifetime: Lifetime::Persistent,
584 key_type: Type::RawData,
585 bits: 0,
586 policy: Policy {
587 usage_flags: UsageFlags::default(),
588 permitted_algorithms: Algorithm::None,
589 },
590 },
591 };
592 let mut import_key_op = crate::operations::psa_import_key::Operation {
593 key_name: "dummy".to_string(),
594 attributes: Attributes {
595 lifetime: Lifetime::Persistent,
596 key_type: Type::RawData,
597 bits: 0,
598 policy: Policy {
599 usage_flags: UsageFlags::default(),
600 permitted_algorithms: Algorithm::None,
601 },
602 },
603 data: secrecy::Secret::new(vec![]),
604 };
605
606 let (test_key_type, test_key_size) = get_deprecated_keys()[0];
607 let test_algorithm = Algorithm::Hash(Hash::Md2);
608 generate_key_op.attributes.key_type = test_key_type;
609 generate_key_op.attributes.bits = test_key_size.unwrap_or(0);
610 generate_key_op.attributes.policy.permitted_algorithms = test_algorithm;
611 assert_eq!(
612 generate_key_op.check_deprecated(),
613 Err(ResponseStatus::DeprecatedPrimitive)
614 );
615 import_key_op.attributes.key_type = test_key_type;
616 import_key_op.attributes.bits = test_key_size.unwrap_or(0);
617 import_key_op.attributes.policy.permitted_algorithms = test_algorithm;
618 assert_eq!(
619 import_key_op.check_deprecated(),
620 Err(ResponseStatus::DeprecatedPrimitive)
621 );
622 }
623
624 #[test]
625 fn op_check_deprecated_for_non_deprecated() {
626 use psa_crypto::types::key::{Attributes, Lifetime, Policy, UsageFlags};
627 let mut generate_key_op = crate::operations::psa_generate_key::Operation {
628 key_name: "dummy".to_string(),
629 attributes: Attributes {
630 lifetime: Lifetime::Persistent,
631 key_type: Type::RawData,
632 bits: 0,
633 policy: Policy {
634 usage_flags: UsageFlags::default(),
635 permitted_algorithms: Algorithm::None,
636 },
637 },
638 };
639 let mut import_key_op = crate::operations::psa_import_key::Operation {
640 key_name: "dummy".to_string(),
641 attributes: Attributes {
642 lifetime: Lifetime::Persistent,
643 key_type: Type::RawData,
644 bits: 0,
645 policy: Policy {
646 usage_flags: UsageFlags::default(),
647 permitted_algorithms: Algorithm::None,
648 },
649 },
650 data: secrecy::Secret::new(vec![]),
651 };
652
653 let test_key_type = Type::Aes;
654 let test_key_size: usize = 256;
655 let test_algorithm = Algorithm::Cipher(Cipher::CbcNoPadding);
656 generate_key_op.attributes.key_type = test_key_type;
657 generate_key_op.attributes.bits = test_key_size;
658 generate_key_op.attributes.policy.permitted_algorithms = test_algorithm;
659 assert_eq!(generate_key_op.check_deprecated(), Ok(()));
660 import_key_op.attributes.key_type = test_key_type;
661 import_key_op.attributes.bits = test_key_size;
662 import_key_op.attributes.policy.permitted_algorithms = test_algorithm;
663 assert_eq!(import_key_op.check_deprecated(), Ok(()));
664 }
665}