diff --git a/psa-crypto-sys/src/c/shim.c b/psa-crypto-sys/src/c/shim.c index 7829a2c..fffaf03 100644 --- a/psa-crypto-sys/src/c/shim.c +++ b/psa-crypto-sys/src/c/shim.c @@ -122,6 +122,11 @@ shim_PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(psa_algorithm_t alg) { return PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg); } +int +shim_PSA_ALG_IS_RSA_OAEP(psa_algorithm_t alg) { + return PSA_ALG_IS_RSA_OAEP(alg); +} + int shim_PSA_ALG_IS_KEY_AGREEMENT(psa_algorithm_t alg) { return PSA_ALG_IS_KEY_AGREEMENT(alg); @@ -157,6 +162,11 @@ shim_PSA_ALG_SIGN_GET_HASH(psa_algorithm_t alg) { return PSA_ALG_SIGN_GET_HASH(alg); } +psa_algorithm_t +shim_PSA_ALG_RSA_OAEP_GET_HASH(psa_algorithm_t alg) { + return PSA_ALG_RSA_OAEP_GET_HASH(alg); +} + psa_algorithm_t shim_PSA_ALG_RSA_PKCS1V15_SIGN(psa_algorithm_t hash_alg) { return PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg); @@ -201,6 +211,12 @@ shim_PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_key_type_t key_type) return PSA_KEY_TYPE_IS_DH_KEY_PAIR(key_type); } +psa_algorithm_t +shim_PSA_ALG_RSA_OAEP(psa_algorithm_t alg_type) +{ + return PSA_ALG_RSA_OAEP(alg_type); +} + psa_ecc_curve_t shim_PSA_KEY_TYPE_GET_CURVE(psa_key_type_t key_type) { @@ -249,6 +265,18 @@ shim_PSA_SIGN_OUTPUT_SIZE(psa_key_type_t key_type, size_t key_bits, psa_algorith return PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg); } +size_t +shim_PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(psa_key_type_t key_type, size_t key_bits, psa_algorithm_t alg) +{ + return PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg); +} + +size_t +shim_PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(psa_key_type_t key_type, size_t key_bits, psa_algorithm_t alg) +{ + return PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg); +} + size_t shim_PSA_KEY_EXPORT_MAX_SIZE(psa_key_type_t key_type, size_t key_bits) { diff --git a/psa-crypto-sys/src/c/shim.h b/psa-crypto-sys/src/c/shim.h index 9e105b4..4cb9d8a 100644 --- a/psa-crypto-sys/src/c/shim.h +++ b/psa-crypto-sys/src/c/shim.h @@ -94,17 +94,20 @@ int shim_PSA_ALG_IS_CIPHER(psa_algorithm_t alg); int shim_PSA_ALG_IS_AEAD(psa_algorithm_t alg); int shim_PSA_ALG_IS_SIGN(psa_algorithm_t alg); int shim_PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(psa_algorithm_t alg); +int shim_PSA_ALG_IS_RSA_OAEP(psa_algorithm_t alg); int shim_PSA_ALG_IS_KEY_AGREEMENT(psa_algorithm_t alg); int shim_PSA_ALG_IS_KEY_DERIVATION(psa_algorithm_t alg); int shim_PSA_ALG_IS_RSA_PKCS1V15_SIGN(psa_algorithm_t alg); int shim_PSA_ALG_IS_RSA_PSS(psa_algorithm_t alg); int shim_PSA_ALG_IS_ECDSA(psa_algorithm_t alg); int shim_PSA_ALG_IS_DETERMINISTIC_ECDSA(psa_algorithm_t alg); +psa_algorithm_t shim_PSA_ALG_RSA_OAEP(psa_algorithm_t alg); psa_algorithm_t shim_PSA_ALG_RSA_PKCS1V15_SIGN(psa_algorithm_t hash_alg); psa_algorithm_t shim_PSA_ALG_RSA_PSS(psa_algorithm_t hash_alg); psa_algorithm_t shim_PSA_ALG_ECDSA(psa_algorithm_t hash_alg); psa_algorithm_t shim_PSA_ALG_DETERMINISTIC_ECDSA(psa_algorithm_t hash_alg); psa_algorithm_t shim_PSA_ALG_SIGN_GET_HASH(psa_algorithm_t alg); +psa_algorithm_t shim_PSA_ALG_RSA_OAEP_GET_HASH(psa_algorithm_t alg); int shim_PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_key_type_t key_type); int shim_PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(psa_key_type_t key_type); int shim_PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(psa_key_type_t key_type); @@ -117,4 +120,6 @@ psa_key_type_t shim_PSA_KEY_TYPE_DH_KEY_PAIR(psa_dh_group_t group); psa_key_type_t shim_PSA_KEY_TYPE_DH_PUBLIC_KEY(psa_dh_group_t group); psa_key_type_t shim_PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_key_type_t key_type); size_t shim_PSA_SIGN_OUTPUT_SIZE(psa_key_type_t key_type, size_t key_bits, psa_algorithm_t alg); +size_t shim_PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(psa_key_type_t key_type, size_t key_bits, psa_algorithm_t alg); +size_t shim_PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(psa_key_type_t key_type, size_t key_bits, psa_algorithm_t alg); size_t shim_PSA_KEY_EXPORT_MAX_SIZE(psa_key_type_t key_type, size_t key_bits); \ No newline at end of file diff --git a/psa-crypto-sys/src/lib.rs b/psa-crypto-sys/src/lib.rs index 735e270..6144d7b 100644 --- a/psa-crypto-sys/src/lib.rs +++ b/psa-crypto-sys/src/lib.rs @@ -39,9 +39,10 @@ pub use types::*; #[cfg(feature = "implementation-defined")] pub use psa_crypto_binding::{ - psa_close_key, psa_crypto_init, psa_destroy_key, psa_export_public_key, psa_generate_key, - psa_get_key_attributes, psa_import_key, psa_key_attributes_t, psa_open_key, - psa_reset_key_attributes, psa_sign_hash, psa_verify_hash, + psa_asymmetric_decrypt, psa_asymmetric_encrypt, psa_close_key, psa_crypto_init, + psa_destroy_key, psa_export_public_key, psa_generate_key, psa_get_key_attributes, + psa_import_key, psa_key_attributes_t, psa_open_key, psa_reset_key_attributes, psa_sign_hash, + psa_verify_hash, }; // Secure Element Driver definitions diff --git a/psa-crypto-sys/src/shim_methods.rs b/psa-crypto-sys/src/shim_methods.rs index 5db058a..f6d8dc6 100644 --- a/psa-crypto-sys/src/shim_methods.rs +++ b/psa-crypto-sys/src/shim_methods.rs @@ -88,6 +88,10 @@ pub fn PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg: psa_algorithm_t) -> bool { unsafe { psa_crypto_binding::shim_PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) == 1 } } +pub unsafe fn PSA_ALG_IS_RSA_OAEP(alg: psa_algorithm_t) -> bool { + psa_crypto_binding::shim_PSA_ALG_IS_RSA_OAEP(alg) == 1 +} + pub fn PSA_ALG_IS_KEY_AGREEMENT(alg: psa_algorithm_t) -> bool { unsafe { psa_crypto_binding::shim_PSA_ALG_IS_KEY_AGREEMENT(alg) == 1 } } @@ -116,6 +120,10 @@ pub fn PSA_ALG_SIGN_GET_HASH(alg: psa_algorithm_t) -> psa_algorithm_t { unsafe { psa_crypto_binding::shim_PSA_ALG_SIGN_GET_HASH(alg) } } +pub fn PSA_ALG_RSA_OAEP_GET_HASH(alg: psa_algorithm_t) -> psa_algorithm_t { + unsafe { psa_crypto_binding::shim_PSA_ALG_RSA_OAEP_GET_HASH(alg) } +} + pub fn PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg: psa_algorithm_t) -> psa_algorithm_t { unsafe { psa_crypto_binding::shim_PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) } } @@ -132,6 +140,10 @@ pub fn PSA_ALG_DETERMINISTIC_ECDSA(hash_alg: psa_algorithm_t) -> psa_algorithm_t unsafe { psa_crypto_binding::shim_PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) } } +pub unsafe fn PSA_ALG_RSA_OAEP(hash_alg: psa_algorithm_t) -> psa_algorithm_t { + psa_crypto_binding::shim_PSA_ALG_RSA_OAEP(hash_alg) +} + pub fn PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type: psa_key_type_t) -> bool { unsafe { psa_crypto_binding::shim_PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) == 1 } } @@ -184,6 +196,22 @@ pub unsafe fn PSA_SIGN_OUTPUT_SIZE( psa_crypto_binding::shim_PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) } +pub unsafe fn PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( + key_type: psa_key_type_t, + key_bits: usize, + alg: psa_algorithm_t, +) -> usize { + psa_crypto_binding::shim_PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) +} + +pub unsafe fn PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( + key_type: psa_key_type_t, + key_bits: usize, + alg: psa_algorithm_t, +) -> usize { + psa_crypto_binding::shim_PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) +} + pub unsafe fn PSA_EXPORT_KEY_OUTPUT_SIZE(key_type: psa_key_type_t, key_bits: usize) -> usize { psa_crypto_binding::shim_PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) } diff --git a/psa-crypto/Cargo.toml b/psa-crypto/Cargo.toml index 1109df0..99e0c17 100644 --- a/psa-crypto/Cargo.toml +++ b/psa-crypto/Cargo.toml @@ -19,6 +19,10 @@ log = "0.4.8" serde = { version = "1.0.110", features = ["derive"] } zeroize = { version = "1.1.0", features = ["zeroize_derive"] } +[dev-dependencies] +rsa = "0.3.0" +rand = "0.7.3" + [features] default = ["with-mbed-crypto", "no-std"] with-mbed-crypto = ["psa-crypto-sys/implementation-defined"] diff --git a/psa-crypto/src/operations/asym_encryption.rs b/psa-crypto/src/operations/asym_encryption.rs index c7b04ed..17ad814 100644 --- a/psa-crypto/src/operations/asym_encryption.rs +++ b/psa-crypto/src/operations/asym_encryption.rs @@ -2,3 +2,173 @@ // SPDX-License-Identifier: Apache-2.0 //! # Asymmetric Encryption operations +//! +//! See the PSA Crypto API for the format of the different parameters used in this module. + +use crate::initialized; +use crate::types::algorithm::AsymmetricEncryption; +use crate::types::key::Id; +use crate::types::status::{Result, Status}; + +/// Encrypt a short message with a key pair or public key +/// +/// The encrypted message is written in `ciphertext`. The function returns the number of bytes written. +/// +/// # Example +/// +/// ``` +/// # use psa_crypto::operations::key_management::generate; +/// # use psa_crypto::operations::asym_encryption::encrypt; +/// # use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags}; +/// # use psa_crypto::types::algorithm::{AsymmetricEncryption, Hash}; +/// # +/// # let mut attributes = Attributes { +/// # key_type: Type::RsaKeyPair, +/// # bits: 1024, +/// # lifetime: Lifetime::Volatile, +/// # policy: Policy { +/// # usage_flags: UsageFlags { +/// # encrypt: true, +/// # ..Default::default() +/// # }, +/// # permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into(), +/// # }, +/// # }; +/// # const MESSAGE: [u8; 32] = [ +/// # 0x69, 0x3E, 0xDB, 0x1B, 0x22, 0x79, 0x03, 0xF4, 0xC0, 0xBF, 0xD6, 0x91, 0x76, 0x37, 0x84, 0xA2, +/// # 0x94, 0x8E, 0x92, 0x50, 0x35, 0xC2, 0x8C, 0x5C, 0x3C, 0xCA, 0xFE, 0x18, 0xE8, 0x81, 0x37, 0x78, +/// # ]; +/// psa_crypto::init().unwrap(); +/// let my_key = generate(attributes, None).unwrap(); +/// let alg = AsymmetricEncryption::RsaPkcs1v15Crypt; +/// let buffer_size = attributes.asymmetric_encrypt_output_size(alg).unwrap(); +/// let mut encrypted_message = vec![0; buffer_size]; +/// +/// let size = encrypt(my_key, +/// alg, +/// &MESSAGE, +/// None, +/// &mut encrypted_message).unwrap(); +/// encrypted_message.resize(size, 0); +/// ``` +pub fn encrypt( + key_id: Id, + alg: AsymmetricEncryption, + plaintext: &[u8], + salt: Option<&[u8]>, + ciphertext: &mut [u8], +) -> Result { + initialized()?; + + let handle = key_id.handle()?; + + let mut output_length = 0; + let (salt_ptr, salt_len) = match salt { + Some(salt) => (salt.as_ptr(), salt.len()), + None => (core::ptr::null(), 0), + }; + + let encrypt_res = Status::from(unsafe { + psa_crypto_sys::psa_asymmetric_encrypt( + handle, + alg.into(), + plaintext.as_ptr(), + plaintext.len(), + salt_ptr, + salt_len, + ciphertext.as_mut_ptr(), + ciphertext.len(), + &mut output_length, + ) + }) + .to_result(); + let close_key_handle_res = key_id.close_handle(handle); + encrypt_res?; + close_key_handle_res?; + Ok(output_length) +} + +/// Decrypt a short message with a key pair or private key +/// +/// The decrypted message is written in `plaintext`. The function returns the number of bytes written. +/// +/// # Example +/// +/// ``` +/// # use psa_crypto::operations::key_management::{generate, export_public}; +/// # use psa_crypto::operations::asym_encryption::decrypt; +/// # use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags}; +/// # use psa_crypto::types::algorithm::{AsymmetricEncryption, Hash}; +/// # use rsa::{RSAPublicKey, PaddingScheme, PublicKey}; +/// # use rand::rngs::OsRng; +/// # let mut attributes = Attributes { +/// # key_type: Type::RsaKeyPair, +/// # bits: 1024, +/// # lifetime: Lifetime::Volatile, +/// # policy: Policy { +/// # usage_flags: UsageFlags { +/// # decrypt: true, +/// # ..Default::default() +/// # }, +/// # permitted_algorithms: AsymmetricEncryption::RsaPkcs1v15Crypt.into() +/// # }, +/// # }; +/// # const MESSAGE: [u8; 64] = [ 0x4e, 0x31, 0x74, 0x96, 0x8f, 0xe4, 0xba, 0xb3, 0xaf, 0x77, 0x75, +/// # 0x76, 0x61, 0xde, 0xe5, 0xb8, 0x2c, 0x4f, 0x2a, 0x77, 0x6f, 0x2a, 0x86, 0x36, 0x13, 0xc3, 0xd1, +/// # 0x26, 0x77, 0x30, 0x64, 0x9c, 0xb9, 0x95, 0x84, 0x73, 0x54, 0xfd, 0x6d, 0x2f, 0xba, 0x7e, 0x6c, +/// # 0xb5, 0x0a, 0xe1, 0x09, 0x4e, 0x57, 0x3e, 0xeb, 0x7c, 0x64, 0xcc, 0x9d, 0xf2, 0xf2, 0x37, 0x2e, +/// # 0xb1, 0xe9, 0x92, 0xb7, 0x7b]; +/// psa_crypto::init().unwrap(); +/// +/// let key_id = generate(attributes, None).unwrap(); +/// let mut pub_key = vec![0; attributes.export_public_key_output_size().unwrap()]; +/// let _pub_key_length = export_public(key_id.clone(), &mut pub_key); +/// let rsa_pub_key = RSAPublicKey::from_pkcs1(&pub_key).unwrap(); +/// let ciphertext = rsa_pub_key.encrypt(&mut OsRng, PaddingScheme::new_pkcs1v15_encrypt(), &MESSAGE).unwrap(); +/// +/// let alg = AsymmetricEncryption::RsaPkcs1v15Crypt; +/// let buffer_size = attributes.asymmetric_decrypt_output_size(alg).unwrap(); +/// let mut decrypted_message = vec![0; buffer_size]; +/// let size = decrypt(key_id, +/// alg, +/// &ciphertext, +/// None, +/// &mut decrypted_message).unwrap(); +/// decrypted_message.resize(size, 0); +/// ``` +pub fn decrypt( + key_id: Id, + alg: AsymmetricEncryption, + encrypted_message: &[u8], + salt: Option<&[u8]>, + plaintext: &mut [u8], +) -> Result { + initialized()?; + + let handle = key_id.handle()?; + + let mut output_length = 0; + let (salt_ptr, salt_len) = match salt { + Some(salt) => (salt.as_ptr(), salt.len()), + None => (core::ptr::null(), 0), + }; + + let decrypt_res = Status::from(unsafe { + psa_crypto_sys::psa_asymmetric_decrypt( + handle, + alg.into(), + encrypted_message.as_ptr(), + encrypted_message.len(), + salt_ptr, + salt_len, + plaintext.as_mut_ptr(), + plaintext.len(), + &mut output_length, + ) + }) + .to_result(); + let close_handle_res = key_id.close_handle(handle); + decrypt_res?; + close_handle_res?; + Ok(output_length) +} diff --git a/psa-crypto/src/types/algorithm.rs b/psa-crypto/src/types/algorithm.rs index f6b4f7e..ce53dcb 100644 --- a/psa-crypto/src/types/algorithm.rs +++ b/psa-crypto/src/types/algorithm.rs @@ -560,8 +560,8 @@ impl TryFrom for Algorithm { let asym_sign: AsymmetricSignature = alg.try_into()?; Ok(asym_sign.into()) } else if psa_crypto_sys::PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) { - error!("Asymmetric Encryption algorithms are not supported."); - Err(Error::NotSupported) + let asym_encryption: AsymmetricEncryption = alg.try_into()?; + Ok(asym_encryption.into()) } else if psa_crypto_sys::PSA_ALG_IS_KEY_AGREEMENT(alg) { error!("Key Agreement algorithms are not supported."); Err(Error::NotSupported) @@ -583,6 +583,7 @@ impl TryFrom for psa_crypto_sys::psa_algorithm_t { Algorithm::None => Ok(0), Algorithm::Hash(hash) => Ok(hash.into()), Algorithm::AsymmetricSignature(asym_sign) => Ok(asym_sign.into()), + Algorithm::AsymmetricEncryption(asym_encrypt) => Ok(asym_encrypt.into()), _ => { error!("Algorithm not supported: {:?}.", alg); Err(Error::NotSupported) @@ -722,6 +723,38 @@ impl From for psa_crypto_sys::psa_algorithm_t { } } +#[cfg(feature = "with-mbed-crypto")] +impl TryFrom for AsymmetricEncryption { + type Error = Error; + fn try_from(alg: psa_crypto_sys::psa_algorithm_t) -> Result { + if alg == psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_CRYPT { + Ok(AsymmetricEncryption::RsaPkcs1v15Crypt) + } else if unsafe { psa_crypto_sys::PSA_ALG_IS_RSA_OAEP(alg) } { + Ok(AsymmetricEncryption::RsaOaep { + hash_alg: psa_crypto_sys::PSA_ALG_RSA_OAEP_GET_HASH(alg).try_into()?, + }) + } else { + error!( + "Can not find a valid AsymmetricEncryption algorithm for {}.", + alg + ); + Err(Error::InvalidArgument) + } + } +} + +#[cfg(feature = "with-mbed-crypto")] +impl From for psa_crypto_sys::psa_algorithm_t { + fn from(asym_encrypt: AsymmetricEncryption) -> Self { + match asym_encrypt { + AsymmetricEncryption::RsaPkcs1v15Crypt => psa_crypto_sys::PSA_ALG_RSA_PKCS1V15_CRYPT, + AsymmetricEncryption::RsaOaep { hash_alg } => unsafe { + psa_crypto_sys::PSA_ALG_RSA_OAEP(hash_alg.into()) + }, + } + } +} + #[cfg(test)] mod test { use crate::types::algorithm::{Algorithm, AsymmetricSignature, Hash, SignHash}; diff --git a/psa-crypto/src/types/key.rs b/psa-crypto/src/types/key.rs index 83b8fbc..92fb533 100644 --- a/psa-crypto/src/types/key.rs +++ b/psa-crypto/src/types/key.rs @@ -6,10 +6,10 @@ #![allow(deprecated)] #[cfg(feature = "with-mbed-crypto")] use crate::initialized; -#[cfg(feature = "with-mbed-crypto")] -use crate::types::algorithm::AsymmetricSignature; use crate::types::algorithm::{Algorithm, Cipher}; #[cfg(feature = "with-mbed-crypto")] +use crate::types::algorithm::{AsymmetricEncryption, AsymmetricSignature}; +#[cfg(feature = "with-mbed-crypto")] use crate::types::status::Status; use crate::types::status::{Error, Result}; #[cfg(feature = "with-mbed-crypto")] @@ -112,6 +112,36 @@ impl Attributes { } } + /// Check if a key has permissions to encrypt a message + pub fn is_encrypt_permitted(self) -> bool { + self.policy.usage_flags.encrypt + } + + /// Check encrypt permission in a fallible way + pub fn can_encrypt_message(self) -> Result<()> { + if self.is_encrypt_permitted() { + Ok(()) + } else { + error!("Key attributes do not permit encrypting messages."); + Err(Error::NotPermitted) + } + } + + /// Check if a key has permissions to decrypt a message + pub fn is_decrypt_permitted(self) -> bool { + self.policy.usage_flags.decrypt + } + + /// Check decrypt permission in a fallible way + pub fn can_decrypt_message(self) -> Result<()> { + if self.is_decrypt_permitted() { + Ok(()) + } else { + error!("Key attributes do not permit decrypting messages."); + Err(Error::NotPermitted) + } + } + /// Check if the alg given for a cryptographic operation is permitted to be used with the key pub fn is_alg_permitted(self, alg: Algorithm) -> bool { match self.policy.permitted_algorithms { @@ -335,23 +365,46 @@ impl Attributes { /// Sufficient size for a buffer to export the given key type, if supported #[cfg(feature = "with-mbed-crypto")] fn export_key_output_size_base(key_type: Type, bits: usize) -> Result { - let size = - unsafe { psa_crypto_sys::PSA_EXPORT_KEY_OUTPUT_SIZE(key_type.try_into()?, bits) }; - if size > 0 { - Ok(size) - } else { - Err(Error::NotSupported) + match unsafe { psa_crypto_sys::PSA_EXPORT_KEY_OUTPUT_SIZE(key_type.try_into()?, bits) } { + 0 => Err(Error::NotSupported), + size => Ok(size), } } /// Sufficient buffer size for a signature using the given key, if the key is supported #[cfg(feature = "with-mbed-crypto")] pub fn sign_output_size(self, alg: AsymmetricSignature) -> Result { - self.compatible_with_alg(Algorithm::AsymmetricSignature(alg))?; + self.compatible_with_alg(alg.into())?; Ok(unsafe { psa_crypto_sys::PSA_SIGN_OUTPUT_SIZE(self.key_type.try_into()?, self.bits, alg.into()) }) } + + /// Sufficient buffer size for an encrypted message using the given algorithm + #[cfg(feature = "with-mbed-crypto")] + pub fn asymmetric_encrypt_output_size(self, alg: AsymmetricEncryption) -> Result { + self.compatible_with_alg(alg.into())?; + Ok(unsafe { + psa_crypto_sys::PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( + self.key_type.try_into()?, + self.bits, + alg.into(), + ) + }) + } + + /// Sufficient buffer size for a decrypted message using the given algorithm + #[cfg(feature = "with-mbed-crypto")] + pub fn asymmetric_decrypt_output_size(self, alg: AsymmetricEncryption) -> Result { + self.compatible_with_alg(alg.into())?; + Ok(unsafe { + psa_crypto_sys::PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( + self.key_type.try_into()?, + self.bits, + alg.into(), + ) + }) + } } /// The lifetime of a key indicates where it is stored and which application and system actions diff --git a/psa-crypto/tests/mod.rs b/psa-crypto/tests/mod.rs index caea2bf..9959989 100644 --- a/psa-crypto/tests/mod.rs +++ b/psa-crypto/tests/mod.rs @@ -1,6 +1,6 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 - +#![allow(clippy::multiple_crate_versions)] use psa_crypto::types::algorithm::{Algorithm, AsymmetricSignature, Hash}; use psa_crypto::types::key::{Attributes, Lifetime, Policy, Type, UsageFlags};