1#![allow(deprecated)]
7
8#[cfg(feature = "interface")]
9use crate::types::status::{Error, Result};
10#[cfg(feature = "interface")]
11use core::convert::{TryFrom, TryInto};
12#[cfg(feature = "interface")]
13use log::error;
14use serde::{Deserialize, Serialize};
15use zeroize::Zeroize;
16
17#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
21pub enum Algorithm {
22 None,
26 Hash(Hash),
28 Mac(Mac),
30 Cipher(Cipher),
32 Aead(Aead),
34 AsymmetricSignature(AsymmetricSignature),
36 AsymmetricEncryption(AsymmetricEncryption),
38 KeyAgreement(KeyAgreement),
40 KeyDerivation(KeyDerivation),
42}
43
44impl Algorithm {
45 pub fn is_hmac(self) -> bool {
58 match self {
59 Algorithm::Mac(mac_alg) => mac_alg.is_hmac(),
60 _ => false,
61 }
62 }
63}
64
65#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
67#[allow(deprecated)]
68pub enum Hash {
69 #[deprecated = "The MD2 hash is weak and deprecated and is only recommended for use in legacy protocols."]
71 Md2,
72 #[deprecated = "The MD4 hash is weak and deprecated and is only recommended for use in legacy protocols."]
74 Md4,
75 #[deprecated = "The MD5 hash is weak and deprecated and is only recommended for use in legacy protocols."]
77 Md5,
78 Ripemd160,
80 #[deprecated = "The SHA-1 hash is weak and deprecated and is only recommended for use in legacy protocols."]
82 Sha1,
83 Sha224,
85 Sha256,
87 Sha384,
89 Sha512,
91 Sha512_224,
93 Sha512_256,
95 Sha3_224,
97 Sha3_256,
99 Sha3_384,
101 Sha3_512,
103}
104
105impl Hash {
106 pub fn hash_length(self) -> usize {
116 match self {
117 Hash::Md2 | Hash::Md4 | Hash::Md5 => 16,
118 Hash::Ripemd160 | Hash::Sha1 => 20,
119 Hash::Sha224 | Hash::Sha512_224 | Hash::Sha3_224 => 28,
120 Hash::Sha256 | Hash::Sha512_256 | Hash::Sha3_256 => 32,
121 Hash::Sha384 | Hash::Sha3_384 => 48,
122 Hash::Sha3_512 | Hash::Sha512 => 64,
123 }
124 }
125}
126
127#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
129pub enum FullLengthMac {
130 Hmac {
132 hash_alg: Hash,
134 },
135 CbcMac,
137 Cmac,
139}
140
141#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
143pub enum Mac {
144 FullLength(FullLengthMac),
146 Truncated {
148 mac_alg: FullLengthMac,
150 mac_length: usize,
152 },
153}
154
155impl Mac {
156 pub fn is_hmac(self) -> bool {
158 matches!(
159 self,
160 Mac::FullLength(FullLengthMac::Hmac { .. })
161 | Mac::Truncated {
162 mac_alg: FullLengthMac::Hmac { .. },
163 ..
164 }
165 )
166 }
167
168 pub fn is_block_cipher_needed(self) -> bool {
170 matches!(
171 self,
172 Mac::FullLength(FullLengthMac::CbcMac)
173 | Mac::FullLength(FullLengthMac::Cmac)
174 | Mac::Truncated {
175 mac_alg: FullLengthMac::CbcMac,
176 ..
177 }
178 | Mac::Truncated {
179 mac_alg: FullLengthMac::Cmac,
180 ..
181 }
182 )
183 }
184}
185
186#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
188pub enum Cipher {
189 StreamCipher,
191 Ctr,
193 Cfb,
195 Ofb,
197 Xts,
199 EcbNoPadding,
201 CbcNoPadding,
203 CbcPkcs7,
205}
206
207impl Cipher {
208 pub fn is_block_cipher_mode(self) -> bool {
210 matches!(
211 self,
212 Cipher::Ctr
213 | Cipher::Cfb
214 | Cipher::Ofb
215 | Cipher::Xts
216 | Cipher::EcbNoPadding
217 | Cipher::CbcNoPadding
218 | Cipher::CbcPkcs7
219 )
220 }
221}
222
223#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
224pub enum AeadWithDefaultLengthTag {
226 Ccm,
228 Gcm,
230 Chacha20Poly1305,
232}
233
234#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
237pub enum Aead {
238 AeadWithDefaultLengthTag(AeadWithDefaultLengthTag),
240 AeadWithShortenedTag {
242 aead_alg: AeadWithDefaultLengthTag,
244 tag_length: usize,
246 },
247}
248
249impl Aead {
250 pub fn is_aead_on_block_cipher(self) -> bool {
252 matches!(
253 self,
254 Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Ccm)
255 | Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Gcm)
256 | Aead::AeadWithShortenedTag {
257 aead_alg: AeadWithDefaultLengthTag::Ccm,
258 ..
259 }
260 | Aead::AeadWithShortenedTag {
261 aead_alg: AeadWithDefaultLengthTag::Gcm,
262 ..
263 }
264 )
265 }
266
267 pub fn is_chacha20_poly1305_alg(self) -> bool {
269 matches!(
270 self,
271 Aead::AeadWithDefaultLengthTag(AeadWithDefaultLengthTag::Chacha20Poly1305)
272 | Aead::AeadWithShortenedTag {
273 aead_alg: AeadWithDefaultLengthTag::Chacha20Poly1305,
274 ..
275 }
276 )
277 }
278}
279
280#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
282pub enum SignHash {
283 Specific(Hash),
285 Any,
289}
290
291impl SignHash {
292 pub fn is_alg_permitted(self, alg: SignHash) -> bool {
295 if let SignHash::Specific(_) = alg {
296 if self == SignHash::Any {
297 true
298 } else {
299 self == alg
300 }
301 } else {
302 false
304 }
305 }
306}
307
308impl From<Hash> for SignHash {
309 fn from(hash: Hash) -> Self {
310 SignHash::Specific(hash)
311 }
312}
313
314#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
316pub enum AsymmetricSignature {
317 RsaPkcs1v15Sign {
319 hash_alg: SignHash,
321 },
322 RsaPkcs1v15SignRaw,
324 RsaPss {
326 hash_alg: SignHash,
328 },
329 Ecdsa {
331 hash_alg: SignHash,
333 },
334 EcdsaAny,
336 DeterministicEcdsa {
338 hash_alg: SignHash,
340 },
341}
342
343impl AsymmetricSignature {
344 pub fn is_alg_permitted(self, alg: AsymmetricSignature) -> bool {
363 match self {
364 AsymmetricSignature::RsaPkcs1v15Sign {
365 hash_alg: hash_policy,
366 } => {
367 if let AsymmetricSignature::RsaPkcs1v15Sign { hash_alg } = alg {
368 hash_policy.is_alg_permitted(hash_alg)
369 } else {
370 false
371 }
372 }
373 AsymmetricSignature::RsaPss {
374 hash_alg: hash_policy,
375 } => {
376 if let AsymmetricSignature::RsaPss { hash_alg } = alg {
377 hash_policy.is_alg_permitted(hash_alg)
378 } else {
379 false
380 }
381 }
382 AsymmetricSignature::Ecdsa {
383 hash_alg: hash_policy,
384 } => {
385 if let AsymmetricSignature::Ecdsa { hash_alg } = alg {
386 hash_policy.is_alg_permitted(hash_alg)
387 } else {
388 false
389 }
390 }
391 AsymmetricSignature::DeterministicEcdsa {
392 hash_alg: hash_policy,
393 } => {
394 if let AsymmetricSignature::DeterministicEcdsa { hash_alg } = alg {
395 hash_policy.is_alg_permitted(hash_alg)
396 } else {
397 false
398 }
399 }
400 asymmetric_signature_alg => asymmetric_signature_alg == alg,
402 }
403 }
404
405 pub fn is_rsa_alg(self) -> bool {
407 matches!(
408 self,
409 AsymmetricSignature::RsaPkcs1v15Sign { .. }
410 | AsymmetricSignature::RsaPkcs1v15SignRaw
411 | AsymmetricSignature::RsaPss { .. }
412 )
413 }
414
415 pub fn is_ecc_alg(self) -> bool {
417 matches!(
418 self,
419 AsymmetricSignature::Ecdsa { .. }
420 | AsymmetricSignature::EcdsaAny
421 | AsymmetricSignature::DeterministicEcdsa { .. }
422 )
423 }
424
425 pub fn is_hash_len_permitted(self, hash_len: usize) -> bool {
427 match self {
428 AsymmetricSignature::EcdsaAny | AsymmetricSignature::RsaPkcs1v15SignRaw => true,
429 AsymmetricSignature::DeterministicEcdsa { hash_alg }
430 | AsymmetricSignature::RsaPkcs1v15Sign { hash_alg }
431 | AsymmetricSignature::Ecdsa { hash_alg }
432 | AsymmetricSignature::RsaPss { hash_alg } => {
433 if let SignHash::Specific(hash_alg) = hash_alg {
434 hash_alg.hash_length() == hash_len
435 } else {
436 false
437 }
438 }
439 }
440 }
441
442 pub fn hash(self) -> Option<SignHash> {
446 match self {
447 AsymmetricSignature::EcdsaAny | AsymmetricSignature::RsaPkcs1v15SignRaw => None,
448 AsymmetricSignature::DeterministicEcdsa { hash_alg }
449 | AsymmetricSignature::RsaPkcs1v15Sign { hash_alg }
450 | AsymmetricSignature::Ecdsa { hash_alg }
451 | AsymmetricSignature::RsaPss { hash_alg } => Some(hash_alg),
452 }
453 }
454}
455
456#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
458pub enum AsymmetricEncryption {
459 RsaPkcs1v15Crypt,
461 RsaOaep {
463 hash_alg: Hash,
465 },
466}
467
468#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
470pub enum RawKeyAgreement {
471 Ffdh,
473 Ecdh,
475}
476
477#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
479pub enum KeyAgreement {
480 Raw(RawKeyAgreement),
482 WithKeyDerivation {
484 ka_alg: RawKeyAgreement,
486 kdf_alg: KeyDerivation,
488 },
489}
490
491#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
493pub enum KeyDerivation {
494 Hkdf {
496 hash_alg: Hash,
498 },
499 Tls12Prf {
501 hash_alg: Hash,
503 },
504 Tls12PskToMs {
506 hash_alg: Hash,
508 },
509}
510
511impl From<Hash> for Algorithm {
512 fn from(alg: Hash) -> Self {
513 Algorithm::Hash(alg)
514 }
515}
516impl From<Mac> for Algorithm {
517 fn from(alg: Mac) -> Self {
518 Algorithm::Mac(alg)
519 }
520}
521impl From<Cipher> for Algorithm {
522 fn from(alg: Cipher) -> Self {
523 Algorithm::Cipher(alg)
524 }
525}
526impl From<Aead> for Algorithm {
527 fn from(alg: Aead) -> Self {
528 Algorithm::Aead(alg)
529 }
530}
531impl From<AsymmetricSignature> for Algorithm {
532 fn from(alg: AsymmetricSignature) -> Self {
533 Algorithm::AsymmetricSignature(alg)
534 }
535}
536impl From<AsymmetricEncryption> for Algorithm {
537 fn from(alg: AsymmetricEncryption) -> Self {
538 Algorithm::AsymmetricEncryption(alg)
539 }
540}
541impl From<KeyAgreement> for Algorithm {
542 fn from(alg: KeyAgreement) -> Self {
543 Algorithm::KeyAgreement(alg)
544 }
545}
546impl From<KeyDerivation> for Algorithm {
547 fn from(alg: KeyDerivation) -> Self {
548 Algorithm::KeyDerivation(alg)
549 }
550}
551
552#[cfg(feature = "interface")]
553impl TryFrom<psa_crypto_sys::psa_algorithm_t> for Algorithm {
554 type Error = Error;
555 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
556 if alg == 0 {
557 Ok(Algorithm::None)
558 } else if psa_crypto_sys::PSA_ALG_IS_HASH(alg) {
559 let hash: Hash = alg.try_into()?;
560 Ok(hash.into())
561 } else if psa_crypto_sys::PSA_ALG_IS_MAC(alg) {
562 let mac: Mac = alg.try_into()?;
563 Ok(mac.into())
564 } else if psa_crypto_sys::PSA_ALG_IS_CIPHER(alg) {
565 error!("Cipher algorithms are not supported.");
566 Err(Error::NotSupported)
567 } else if psa_crypto_sys::PSA_ALG_IS_AEAD(alg) {
568 let aead: Aead = alg.try_into()?;
569 Ok(aead.into())
570 } else if psa_crypto_sys::PSA_ALG_IS_SIGN(alg) {
571 let asym_sign: AsymmetricSignature = alg.try_into()?;
572 Ok(asym_sign.into())
573 } else if psa_crypto_sys::PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) {
574 let asym_encryption: AsymmetricEncryption = alg.try_into()?;
575 Ok(asym_encryption.into())
576 } else if psa_crypto_sys::PSA_ALG_IS_KEY_AGREEMENT(alg) {
577 let key_agreement: KeyAgreement = alg.try_into()?;
578 Ok(key_agreement.into())
579 } else if psa_crypto_sys::PSA_ALG_IS_KEY_DERIVATION(alg) {
580 let key_derivation: KeyDerivation = alg.try_into()?;
581 Ok(key_derivation.into())
582 } else {
583 error!("Can not find a valid Algorithm for {}.", alg);
584 Err(Error::NotSupported)
585 }
586 }
587}
588
589#[cfg(feature = "interface")]
590impl TryFrom<Algorithm> for psa_crypto_sys::psa_algorithm_t {
591 type Error = Error;
592 fn try_from(alg: Algorithm) -> Result<Self> {
593 match alg {
594 Algorithm::None => Ok(0),
595 Algorithm::Hash(hash) => Ok(hash.into()),
596 Algorithm::AsymmetricSignature(asym_sign) => Ok(asym_sign.into()),
597 Algorithm::AsymmetricEncryption(asym_encrypt) => Ok(asym_encrypt.into()),
598 Algorithm::Mac(mac) => Ok(mac.into()),
599 Algorithm::KeyAgreement(key_agreement) => Ok(key_agreement.into()),
600 Algorithm::KeyDerivation(key_derivation) => Ok(key_derivation.into()),
601 Algorithm::Aead(aead) => Ok(aead.into()),
602 Algorithm::Cipher(cipher) => Ok(cipher.into()),
603 }
604 }
605}
606
607#[cfg(feature = "interface")]
608impl TryFrom<psa_crypto_sys::psa_algorithm_t> for Hash {
609 type Error = Error;
610 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
611 match alg {
612 psa_crypto_sys::PSA_ALG_MD2 => Ok(Hash::Md2),
613 psa_crypto_sys::PSA_ALG_MD4 => Ok(Hash::Md4),
614 psa_crypto_sys::PSA_ALG_MD5 => Ok(Hash::Md5),
615 psa_crypto_sys::PSA_ALG_RIPEMD160 => Ok(Hash::Ripemd160),
616 psa_crypto_sys::PSA_ALG_SHA_1 => Ok(Hash::Sha1),
617 psa_crypto_sys::PSA_ALG_SHA_224 => Ok(Hash::Sha224),
618 psa_crypto_sys::PSA_ALG_SHA_256 => Ok(Hash::Sha256),
619 psa_crypto_sys::PSA_ALG_SHA_384 => Ok(Hash::Sha384),
620 psa_crypto_sys::PSA_ALG_SHA_512 => Ok(Hash::Sha512),
621 psa_crypto_sys::PSA_ALG_SHA_512_224 => Ok(Hash::Sha512_224),
622 psa_crypto_sys::PSA_ALG_SHA_512_256 => Ok(Hash::Sha512_256),
623 psa_crypto_sys::PSA_ALG_SHA3_224 => Ok(Hash::Sha3_224),
624 psa_crypto_sys::PSA_ALG_SHA3_256 => Ok(Hash::Sha3_256),
625 psa_crypto_sys::PSA_ALG_SHA3_384 => Ok(Hash::Sha3_384),
626 psa_crypto_sys::PSA_ALG_SHA3_512 => Ok(Hash::Sha3_512),
627 a => {
628 error!("Can not find a valid Hash algorithm for {}.", a);
629 Err(Error::InvalidArgument)
630 }
631 }
632 }
633}
634
635#[cfg(feature = "interface")]
636impl From<Hash> for psa_crypto_sys::psa_algorithm_t {
637 fn from(hash: Hash) -> Self {
638 match hash {
639 Hash::Md2 => psa_crypto_sys::PSA_ALG_MD2,
640 Hash::Md4 => psa_crypto_sys::PSA_ALG_MD4,
641 Hash::Md5 => psa_crypto_sys::PSA_ALG_MD5,
642 Hash::Ripemd160 => psa_crypto_sys::PSA_ALG_RIPEMD160,
643 Hash::Sha1 => psa_crypto_sys::PSA_ALG_SHA_1,
644 Hash::Sha224 => psa_crypto_sys::PSA_ALG_SHA_224,
645 Hash::Sha256 => psa_crypto_sys::PSA_ALG_SHA_256,
646 Hash::Sha384 => psa_crypto_sys::PSA_ALG_SHA_384,
647 Hash::Sha512 => psa_crypto_sys::PSA_ALG_SHA_512,
648 Hash::Sha512_224 => psa_crypto_sys::PSA_ALG_SHA_512_224,
649 Hash::Sha512_256 => psa_crypto_sys::PSA_ALG_SHA_512_256,
650 Hash::Sha3_224 => psa_crypto_sys::PSA_ALG_SHA3_224,
651 Hash::Sha3_256 => psa_crypto_sys::PSA_ALG_SHA3_256,
652 Hash::Sha3_384 => psa_crypto_sys::PSA_ALG_SHA3_384,
653 Hash::Sha3_512 => psa_crypto_sys::PSA_ALG_SHA3_512,
654 }
655 }
656}
657
658#[cfg(feature = "interface")]
659impl TryFrom<psa_crypto_sys::psa_algorithm_t> for SignHash {
660 type Error = Error;
661 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
662 if alg == psa_crypto_sys::PSA_ALG_ANY_HASH {
663 Ok(SignHash::Any)
664 } else {
665 Ok(SignHash::Specific(alg.try_into()?))
666 }
667 }
668}
669
670#[cfg(feature = "interface")]
671impl From<SignHash> for psa_crypto_sys::psa_algorithm_t {
672 fn from(sign_hash: SignHash) -> Self {
673 match sign_hash {
674 SignHash::Specific(hash) => hash.into(),
675 SignHash::Any => psa_crypto_sys::PSA_ALG_ANY_HASH,
676 }
677 }
678}
679
680#[cfg(feature = "interface")]
681impl TryFrom<psa_crypto_sys::psa_algorithm_t> for AsymmetricSignature {
682 type Error = Error;
683 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
684 if alg == psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_SIGN_RAW {
685 Ok(AsymmetricSignature::RsaPkcs1v15SignRaw)
686 } else if alg == psa_crypto_sys::PSA_ALG_ECDSA_ANY {
687 Ok(AsymmetricSignature::EcdsaAny)
688 } else if psa_crypto_sys::PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) {
689 Ok(AsymmetricSignature::RsaPkcs1v15Sign {
690 hash_alg: psa_crypto_sys::PSA_ALG_SIGN_GET_HASH(alg).try_into()?,
691 })
692 } else if psa_crypto_sys::PSA_ALG_IS_RSA_PSS(alg) {
693 Ok(AsymmetricSignature::RsaPss {
694 hash_alg: psa_crypto_sys::PSA_ALG_SIGN_GET_HASH(alg).try_into()?,
695 })
696 } else if psa_crypto_sys::PSA_ALG_IS_ECDSA(alg) {
697 Ok(AsymmetricSignature::Ecdsa {
698 hash_alg: psa_crypto_sys::PSA_ALG_SIGN_GET_HASH(alg).try_into()?,
699 })
700 } else if psa_crypto_sys::PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) {
701 Ok(AsymmetricSignature::DeterministicEcdsa {
702 hash_alg: psa_crypto_sys::PSA_ALG_SIGN_GET_HASH(alg).try_into()?,
703 })
704 } else {
705 error!(
706 "Can not find a valid AsymmetricSignature algorithm for {}.",
707 alg
708 );
709 Err(Error::InvalidArgument)
710 }
711 }
712}
713
714#[cfg(feature = "interface")]
715impl From<AsymmetricSignature> for psa_crypto_sys::psa_algorithm_t {
716 fn from(asym_sign: AsymmetricSignature) -> Self {
717 match asym_sign {
718 AsymmetricSignature::RsaPkcs1v15Sign { hash_alg } => {
719 psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg.into())
720 }
721 AsymmetricSignature::RsaPkcs1v15SignRaw => {
722 psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_SIGN_RAW
723 }
724 AsymmetricSignature::RsaPss { hash_alg } => {
725 psa_crypto_sys::PSA_ALG_RSA_PSS(hash_alg.into())
726 }
727 AsymmetricSignature::Ecdsa { hash_alg } => {
728 psa_crypto_sys::PSA_ALG_ECDSA(hash_alg.into())
729 }
730 AsymmetricSignature::EcdsaAny => psa_crypto_sys::PSA_ALG_ECDSA_ANY,
731 AsymmetricSignature::DeterministicEcdsa { hash_alg } => {
732 psa_crypto_sys::PSA_ALG_DETERMINISTIC_ECDSA(hash_alg.into())
733 }
734 }
735 }
736}
737
738#[cfg(feature = "interface")]
739impl TryFrom<psa_crypto_sys::psa_algorithm_t> for AsymmetricEncryption {
740 type Error = Error;
741 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
742 if alg == psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_CRYPT {
743 Ok(AsymmetricEncryption::RsaPkcs1v15Crypt)
744 } else if unsafe { psa_crypto_sys::PSA_ALG_IS_RSA_OAEP(alg) } {
745 Ok(AsymmetricEncryption::RsaOaep {
746 hash_alg: psa_crypto_sys::PSA_ALG_RSA_OAEP_GET_HASH(alg).try_into()?,
747 })
748 } else {
749 error!(
750 "Can not find a valid AsymmetricEncryption algorithm for {}.",
751 alg
752 );
753 Err(Error::InvalidArgument)
754 }
755 }
756}
757
758#[cfg(feature = "interface")]
759impl From<AsymmetricEncryption> for psa_crypto_sys::psa_algorithm_t {
760 fn from(asym_encrypt: AsymmetricEncryption) -> Self {
761 match asym_encrypt {
762 AsymmetricEncryption::RsaPkcs1v15Crypt => psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_CRYPT,
763 AsymmetricEncryption::RsaOaep { hash_alg } => unsafe {
764 psa_crypto_sys::PSA_ALG_RSA_OAEP(hash_alg.into())
765 },
766 }
767 }
768}
769
770#[cfg(feature = "interface")]
771impl From<Cipher> for psa_crypto_sys::psa_algorithm_t {
772 fn from(cipher: Cipher) -> Self {
773 match cipher {
774 Cipher::StreamCipher => psa_crypto_sys::PSA_ALG_STREAM_CIPHER,
775 Cipher::Ctr => psa_crypto_sys::PSA_ALG_CTR,
776 Cipher::Cfb => psa_crypto_sys::PSA_ALG_CFB,
777 Cipher::Ofb => psa_crypto_sys::PSA_ALG_OFB,
778 Cipher::Xts => psa_crypto_sys::PSA_ALG_XTS,
779 Cipher::EcbNoPadding => psa_crypto_sys::PSA_ALG_ECB_NO_PADDING,
780 Cipher::CbcNoPadding => psa_crypto_sys::PSA_ALG_CBC_NO_PADDING,
781 Cipher::CbcPkcs7 => psa_crypto_sys::PSA_ALG_CBC_PKCS7,
782 }
783 }
784}
785
786#[cfg(feature = "interface")]
787impl TryFrom<psa_crypto_sys::psa_algorithm_t> for Mac {
788 type Error = Error;
789 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
790 if psa_crypto_sys::PSA_ALG_IS_MAC(alg) {
791 if unsafe { psa_crypto_sys::PSA_ALG_FULL_LENGTH_MAC(alg) } == alg {
792 Ok(Mac::FullLength(alg.try_into()?))
793 } else {
794 let mac_length = unsafe { psa_crypto_sys::PSA_MAC_TRUNCATED_LENGTH(alg) };
795 let mac_alg: FullLengthMac =
796 unsafe { psa_crypto_sys::PSA_ALG_FULL_LENGTH_MAC(alg) }.try_into()?;
797 Ok(Mac::Truncated {
798 mac_alg,
799 mac_length,
800 })
801 }
802 } else {
803 error!("Can not find a valid MAC algorithm for {}.", alg);
804 Err(Error::InvalidArgument)
805 }
806 }
807}
808
809#[cfg(feature = "interface")]
810impl TryFrom<psa_crypto_sys::psa_algorithm_t> for FullLengthMac {
811 type Error = Error;
812
813 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
814 if psa_crypto_sys::PSA_ALG_IS_HMAC(alg) {
815 Ok(FullLengthMac::Hmac {
816 hash_alg: psa_crypto_sys::PSA_ALG_HMAC_GET_HASH(alg).try_into()?,
817 })
818 } else if alg == psa_crypto_sys::PSA_ALG_CBC_MAC {
819 Ok(FullLengthMac::CbcMac)
820 } else if alg == psa_crypto_sys::PSA_ALG_CMAC {
821 Ok(FullLengthMac::Cmac)
822 } else {
823 error!("Can not find a valid MAC algorithm for {}.", alg);
824 Err(Error::InvalidArgument)
825 }
826 }
827}
828
829#[cfg(feature = "interface")]
830impl From<Mac> for psa_crypto_sys::psa_algorithm_t {
831 fn from(mac: Mac) -> Self {
832 match mac {
833 Mac::FullLength(full_length_mac) => full_length_mac.into(),
834 Mac::Truncated {
835 mac_alg: alg,
836 mac_length: length,
837 } => unsafe { psa_crypto_sys::PSA_ALG_TRUNCATED_MAC(alg.into(), length) },
839 }
840 }
841}
842
843impl From<FullLengthMac> for Mac {
844 fn from(full_length_mac: FullLengthMac) -> Self {
845 Mac::FullLength(full_length_mac)
846 }
847}
848
849#[cfg(feature = "interface")]
850impl From<FullLengthMac> for psa_crypto_sys::psa_algorithm_t {
851 fn from(full_length_mac: FullLengthMac) -> Self {
852 match full_length_mac {
853 FullLengthMac::CbcMac => psa_crypto_sys::PSA_ALG_CBC_MAC,
854 FullLengthMac::Cmac => psa_crypto_sys::PSA_ALG_CMAC,
855 FullLengthMac::Hmac { hash_alg } => unsafe {
856 psa_crypto_sys::PSA_ALG_HMAC(hash_alg.into())
857 },
858 }
859 }
860}
861
862#[cfg(feature = "interface")]
863impl TryFrom<psa_crypto_sys::psa_algorithm_t> for Aead {
864 type Error = Error;
865 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
866 if let Ok(aead_with_default_length_tag) = AeadWithDefaultLengthTag::try_from(alg) {
867 Ok(Aead::AeadWithDefaultLengthTag(aead_with_default_length_tag))
868 } else {
869 let aead_alg = AeadWithDefaultLengthTag::try_from(unsafe {
871 psa_crypto_sys::PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg)
872 })?;
873 let tag_length = psa_crypto_sys::PSA_ALG_AEAD_TAG_TRUNCATED_LENGTH(alg);
874 Ok(Aead::AeadWithShortenedTag {
875 aead_alg,
876 tag_length,
877 })
878 }
879 }
880}
881
882#[cfg(feature = "interface")]
883impl TryFrom<psa_crypto_sys::psa_algorithm_t> for AeadWithDefaultLengthTag {
884 type Error = Error;
885
886 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
887 if alg
888 == unsafe {
889 psa_crypto_sys::PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(psa_crypto_sys::PSA_ALG_CCM)
890 }
891 {
892 Ok(AeadWithDefaultLengthTag::Ccm)
893 } else if alg
894 == unsafe {
895 psa_crypto_sys::PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(psa_crypto_sys::PSA_ALG_GCM)
896 }
897 {
898 Ok(AeadWithDefaultLengthTag::Gcm)
899 } else if alg
900 == unsafe {
901 psa_crypto_sys::PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(
902 psa_crypto_sys::PSA_ALG_CHACHA20_POLY1305,
903 )
904 }
905 {
906 Ok(AeadWithDefaultLengthTag::Chacha20Poly1305)
907 } else {
908 error!("Can not find a valid Aead algorithm for {}.", alg);
909 Err(Error::InvalidArgument)
910 }
911 }
912}
913
914#[cfg(feature = "interface")]
915impl From<Aead> for psa_crypto_sys::psa_algorithm_t {
916 fn from(aead: Aead) -> Self {
917 match aead {
918 Aead::AeadWithDefaultLengthTag(aead_with_default_length_mac) => {
919 aead_with_default_length_mac.into()
920 }
921 Aead::AeadWithShortenedTag {
923 aead_alg,
924 tag_length,
925 } => unsafe {
926 psa_crypto_sys::PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg.into(), tag_length)
927 },
928 }
929 }
930}
931
932#[cfg(feature = "interface")]
933impl From<AeadWithDefaultLengthTag> for psa_crypto_sys::psa_algorithm_t {
934 fn from(aead_with_default_length_tag: AeadWithDefaultLengthTag) -> Self {
935 match aead_with_default_length_tag {
936 AeadWithDefaultLengthTag::Ccm => unsafe {
937 psa_crypto_sys::PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(psa_crypto_sys::PSA_ALG_CCM)
938 },
939 AeadWithDefaultLengthTag::Gcm => unsafe {
940 psa_crypto_sys::PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(psa_crypto_sys::PSA_ALG_GCM)
941 },
942 AeadWithDefaultLengthTag::Chacha20Poly1305 => unsafe {
943 psa_crypto_sys::PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(
944 psa_crypto_sys::PSA_ALG_CHACHA20_POLY1305,
945 )
946 },
947 }
948 }
949}
950
951impl From<AeadWithDefaultLengthTag> for Aead {
952 fn from(aead_with_default_tag_length: AeadWithDefaultLengthTag) -> Self {
953 Aead::AeadWithDefaultLengthTag(aead_with_default_tag_length)
954 }
955}
956
957#[cfg(feature = "interface")]
958impl From<KeyAgreement> for psa_crypto_sys::psa_algorithm_t {
959 fn from(key_agreement: KeyAgreement) -> Self {
960 match key_agreement {
961 KeyAgreement::Raw(raw_key_agreement) => raw_key_agreement.into(),
962 KeyAgreement::WithKeyDerivation { ka_alg, kdf_alg } => unsafe {
963 psa_crypto_sys::PSA_ALG_KEY_AGREEMENT(ka_alg.into(), kdf_alg.into())
964 },
965 }
966 }
967}
968
969#[cfg(feature = "interface")]
970impl TryFrom<psa_crypto_sys::psa_algorithm_t> for KeyAgreement {
971 type Error = Error;
972 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
973 if psa_crypto_sys::PSA_ALG_IS_KEY_AGREEMENT(alg) {
974 if psa_crypto_sys::PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) {
975 Ok(KeyAgreement::Raw(alg.try_into()?))
976 } else {
977 Ok(KeyAgreement::WithKeyDerivation {
978 ka_alg: unsafe { psa_crypto_sys::PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) }
979 .try_into()?,
980 kdf_alg: unsafe { psa_crypto_sys::PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) }
981 .try_into()?,
982 })
983 }
984 } else {
985 error!("Can not find a valid KeyAgreement algorithm for {}.", alg);
986 Err(Error::InvalidArgument)
987 }
988 }
989}
990
991#[cfg(feature = "interface")]
992impl TryFrom<psa_crypto_sys::psa_algorithm_t> for RawKeyAgreement {
993 type Error = Error;
994 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
995 if psa_crypto_sys::PSA_ALG_IS_FFDH(alg) {
996 Ok(RawKeyAgreement::Ffdh)
997 } else if psa_crypto_sys::PSA_ALG_IS_ECDH(alg) {
998 Ok(RawKeyAgreement::Ecdh)
999 } else {
1000 error!(
1001 "Can not find a valid RawKeyAgreement algorithm for {}.",
1002 alg
1003 );
1004 Err(Error::InvalidArgument)
1005 }
1006 }
1007}
1008
1009#[cfg(feature = "interface")]
1010impl From<RawKeyAgreement> for psa_crypto_sys::psa_algorithm_t {
1011 fn from(raw_key_agreement: RawKeyAgreement) -> Self {
1012 match raw_key_agreement {
1013 RawKeyAgreement::Ecdh => psa_crypto_sys::PSA_ALG_ECDH,
1014 RawKeyAgreement::Ffdh => psa_crypto_sys::PSA_ALG_FFDH,
1015 }
1016 }
1017}
1018
1019impl From<RawKeyAgreement> for KeyAgreement {
1020 fn from(raw_key_agreement: RawKeyAgreement) -> Self {
1021 KeyAgreement::Raw(raw_key_agreement)
1022 }
1023}
1024
1025#[cfg(feature = "interface")]
1026impl From<KeyDerivation> for psa_crypto_sys::psa_algorithm_t {
1027 fn from(key_derivation: KeyDerivation) -> Self {
1028 match key_derivation {
1029 KeyDerivation::Hkdf { hash_alg, .. } => unsafe {
1030 psa_crypto_sys::PSA_ALG_HKDF(hash_alg.into())
1031 },
1032 KeyDerivation::Tls12Prf { hash_alg, .. } => unsafe {
1033 psa_crypto_sys::PSA_ALG_TLS12_PRF(hash_alg.into())
1034 },
1035 KeyDerivation::Tls12PskToMs { hash_alg, .. } => unsafe {
1036 psa_crypto_sys::PSA_ALG_TLS12_PSK_TO_MS(hash_alg.into())
1037 },
1038 }
1039 }
1040}
1041
1042#[cfg(feature = "interface")]
1043impl TryFrom<psa_crypto_sys::psa_algorithm_t> for KeyDerivation {
1044 type Error = Error;
1045 fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result<Self> {
1046 if psa_crypto_sys::PSA_ALG_IS_HKDF(alg) {
1047 Ok(KeyDerivation::Hkdf {
1048 hash_alg: psa_crypto_sys::PSA_ALG_HKDF_GET_HASH(alg).try_into()?,
1049 })
1050 } else if psa_crypto_sys::PSA_ALG_IS_TLS12_PRF(alg) {
1051 Ok(KeyDerivation::Tls12Prf {
1052 hash_alg: psa_crypto_sys::PSA_ALG_TLS12_PRF_GET_HASH(alg).try_into()?,
1053 })
1054 } else if psa_crypto_sys::PSA_ALG_IS_TLS12_PSK_TO_MS(alg) {
1055 Ok(KeyDerivation::Tls12PskToMs {
1056 hash_alg: psa_crypto_sys::PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(alg).try_into()?,
1057 })
1058 } else {
1059 error!("Can not find a valid KeyDerivation algorithm for {}.", alg);
1060 Err(Error::InvalidArgument)
1061 }
1062 }
1063}
1064
1065#[cfg(test)]
1066mod test {
1067 use crate::types::algorithm::{Algorithm, AsymmetricSignature, Hash, SignHash};
1068 use core::convert::{TryFrom, TryInto};
1069
1070 #[test]
1071 fn conversion() {
1072 assert_eq!(
1073 Hash::Sha256,
1074 psa_crypto_sys::PSA_ALG_SHA_256.try_into().unwrap()
1075 );
1076 assert_eq!(psa_crypto_sys::PSA_ALG_SHA_256, Hash::Sha256.into());
1077 assert_eq!(
1078 SignHash::Any,
1079 psa_crypto_sys::PSA_ALG_ANY_HASH.try_into().unwrap()
1080 );
1081 assert_eq!(
1082 SignHash::Specific(Hash::Sha256),
1083 psa_crypto_sys::PSA_ALG_SHA_256.try_into().unwrap()
1084 );
1085 assert_eq!(
1086 Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa {
1087 hash_alg: SignHash::Specific(Hash::Sha3_512),
1088 }),
1089 psa_crypto_sys::PSA_ALG_ECDSA(psa_crypto_sys::PSA_ALG_SHA3_512)
1090 .try_into()
1091 .unwrap()
1092 );
1093 assert_eq!(
1094 psa_crypto_sys::PSA_ALG_ECDSA(psa_crypto_sys::PSA_ALG_SHA3_512),
1095 Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa {
1096 hash_alg: SignHash::Specific(Hash::Sha3_512),
1097 })
1098 .try_into()
1099 .unwrap()
1100 );
1101 }
1102
1103 #[test]
1104 fn convert_fail() {
1105 let _ = AsymmetricSignature::try_from(0xDEAD_BEEF).unwrap_err();
1106 let _ = AsymmetricSignature::try_from(psa_crypto_sys::PSA_ALG_ANY_HASH).unwrap_err();
1107 let _ = Hash::try_from(psa_crypto_sys::PSA_ALG_ANY_HASH).unwrap_err();
1108 let _ = Hash::try_from(psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_SIGN_RAW).unwrap_err();
1109 }
1110}