From 19b70b03997ca406744da5e5ba64e53b265567a7 Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Mon, 8 Jun 2020 16:36:01 +0100 Subject: [PATCH 1/9] Added get_key_attributes for export. Signed-off-by: Samuel Bailey --- psa-crypto-sys/src/c/shim.c | 6 +++ psa-crypto-sys/src/c/shim.h | 1 + psa-crypto-sys/src/lib.rs | 1 + psa-crypto-sys/src/shim_methods.rs | 6 ++- psa-crypto/src/operations/key_management.rs | 47 ++++++++++++++++++--- psa-crypto/src/types/key.rs | 2 +- 6 files changed, 56 insertions(+), 7 deletions(-) diff --git a/psa-crypto-sys/src/c/shim.c b/psa-crypto-sys/src/c/shim.c index a5b9846..8746fab 100644 --- a/psa-crypto-sys/src/c/shim.c +++ b/psa-crypto-sys/src/c/shim.c @@ -49,6 +49,12 @@ shim_key_attributes_init(void) return psa_key_attributes_init(); } +psa_status_t +shim_get_key_attributes(psa_key_handle_t key_handle, psa_key_attributes_t *attributes) +{ + return psa_get_key_attributes(key_handle, attributes); +} + void shim_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg) diff --git a/psa-crypto-sys/src/c/shim.h b/psa-crypto-sys/src/c/shim.h index cf5a4d7..56bdf5a 100644 --- a/psa-crypto-sys/src/c/shim.h +++ b/psa-crypto-sys/src/c/shim.h @@ -83,6 +83,7 @@ psa_algorithm_t shim_get_key_algorithm(const psa_key_attributes_t *attributes); psa_key_usage_t shim_get_key_usage_flags(const psa_key_attributes_t *attributes); psa_key_attributes_t shim_key_attributes_init(void); +psa_status_t shim_get_key_attributes(psa_key_handle_t key_handle, psa_key_attributes_t *attributes); void shim_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg); diff --git a/psa-crypto-sys/src/lib.rs b/psa-crypto-sys/src/lib.rs index 7ca54da..228ce63 100644 --- a/psa-crypto-sys/src/lib.rs +++ b/psa-crypto-sys/src/lib.rs @@ -53,3 +53,4 @@ pub use psa_crypto_binding::{ #[cfg(feature = "implementation-defined")] pub use shim_methods::*; + diff --git a/psa-crypto-sys/src/shim_methods.rs b/psa-crypto-sys/src/shim_methods.rs index 6e5941d..1a41994 100644 --- a/psa-crypto-sys/src/shim_methods.rs +++ b/psa-crypto-sys/src/shim_methods.rs @@ -3,7 +3,7 @@ use super::psa_crypto_binding::{ self, psa_algorithm_t, psa_dh_group_t, psa_ecc_curve_t, psa_key_attributes_t, psa_key_id_t, - psa_key_lifetime_t, psa_key_type_t, psa_key_usage_t, + psa_key_lifetime_t, psa_key_type_t, psa_key_usage_t, psa_status_t, psa_key_handle_t }; pub unsafe fn psa_get_key_bits(attributes: *const psa_key_attributes_t) -> usize { @@ -30,6 +30,10 @@ pub unsafe fn psa_key_attributes_init() -> psa_key_attributes_t { psa_crypto_binding::shim_key_attributes_init() } +pub unsafe fn psa_get_key_attributes(key_handle: psa_key_handle_t, attributes: *mut psa_key_attributes_t) -> psa_status_t { + psa_crypto_binding::shim_get_key_attributes(key_handle, attributes) +} + pub unsafe fn psa_set_key_algorithm(attributes: *mut psa_key_attributes_t, alg: psa_algorithm_t) { psa_crypto_binding::shim_set_key_algorithm(attributes, alg); } diff --git a/psa-crypto/src/operations/key_management.rs b/psa-crypto/src/operations/key_management.rs index b05a452..a209729 100644 --- a/psa-crypto/src/operations/key_management.rs +++ b/psa-crypto/src/operations/key_management.rs @@ -7,7 +7,6 @@ use crate::initialized; use crate::types::key::{Attributes, Id}; use crate::types::status::{Result, Status}; use core::convert::TryFrom; - /// Generate a key or a key pair /// /// `id` can be set to `None` when creating a volatile key. Setting the `id` to something will @@ -45,9 +44,9 @@ use core::convert::TryFrom; /// psa_crypto::init().unwrap(); /// let _my_key = key_management::generate(attributes, None).unwrap(); /// ``` +#[cfg(not(feature = "no-std"))] pub fn generate(attributes: Attributes, id: Option) -> Result { initialized()?; - let mut attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?; let id = if let Some(id) = id { unsafe { psa_crypto_sys::psa_set_key_id(&mut attributes, id) }; @@ -56,12 +55,9 @@ pub fn generate(attributes: Attributes, id: Option) -> Result { 0 }; let mut handle = 0; - Status::from(unsafe { psa_crypto_sys::psa_generate_key(&attributes, &mut handle) }) .to_result()?; - Attributes::reset(&mut attributes); - Ok(Id { id, handle: Some(handle), @@ -241,3 +237,44 @@ pub fn export_public(key: Id, data: &mut [u8]) -> Result { Ok(data_length) } + +/// Gets the attributes for a given key ID +/// +/// The `Id` structure can be created with the `from_persistent_key_id` constructor on `Id`. +/// +/// # Example +/// +/// ``` +/// # use psa_crypto::operations::key_management; +/// # use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags}; +/// # use psa_crypto::types::algorithm::{AsymmetricSignature, Hash}; +/// # let mut attributes = Attributes { +/// # key_type: Type::RsaKeyPair, +/// # bits: 1024, +/// # lifetime: Lifetime::Volatile, +/// # policy: Policy { +/// # usage_flags: UsageFlags { +/// # sign_hash: true, +/// # sign_message: true, +/// # verify_hash: true, +/// # verify_message: true, +/// # ..Default::default() +/// # }, +/// # permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { +/// # hash_alg: Hash::Sha256.into(), +/// # }.into(), +/// # }, +/// # }; +/// psa_crypto::init().unwrap(); +/// let my_key = key_management::generate(attributes, None).unwrap(); +/// //... +/// let key_attributes = key_management::get_key_attributes(my_key); +/// ``` + +pub fn get_key_attributes(key: Id) -> Result { + initialized()?; + let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() }; + + let _get_attributes_status = Status::from( unsafe { psa_crypto_sys::psa_get_key_attributes(key.handle()?.into(), &mut key_attributes) } ); + Ok(Attributes::try_from(key_attributes)?) +} \ No newline at end of file diff --git a/psa-crypto/src/types/key.rs b/psa-crypto/src/types/key.rs index 8b9dc70..fc6d637 100644 --- a/psa-crypto/src/types/key.rs +++ b/psa-crypto/src/types/key.rs @@ -493,7 +493,7 @@ impl Id { } pub(crate) fn close_handle(self, handle: psa_crypto_sys::psa_key_handle_t) -> Result<()> { - if self.handle.is_none() { + if !self.handle.is_none() { Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result() } else { Ok(()) From 3d1580e5dac46430132aaa9f1d5d68415d73d175 Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Wed, 10 Jun 2020 18:23:05 +0100 Subject: [PATCH 2/9] Generate, import and get_key_attributes close key handle on completion. Moved some error consts over from bnding. Signed-off-by: Samuel Bailey --- psa-crypto-sys/src/constants.rs | 3 + psa-crypto-sys/src/lib.rs | 1 - psa-crypto/src/lib.rs | 2 +- psa-crypto/src/operations/key_management.rs | 64 ++++++++++++++------- psa-crypto/src/types/key.rs | 5 +- psa-crypto/src/types/status.rs | 15 +++-- 6 files changed, 60 insertions(+), 30 deletions(-) diff --git a/psa-crypto-sys/src/constants.rs b/psa-crypto-sys/src/constants.rs index 6428004..3f36cd0 100644 --- a/psa-crypto-sys/src/constants.rs +++ b/psa-crypto-sys/src/constants.rs @@ -25,6 +25,9 @@ pub const PSA_ERROR_HARDWARE_FAILURE: psa_status_t = -147; pub const PSA_ERROR_INSUFFICIENT_ENTROPY: psa_status_t = -148; pub const PSA_ERROR_INVALID_SIGNATURE: psa_status_t = -149; pub const PSA_ERROR_INVALID_PADDING: psa_status_t = -150; +pub const PSA_ERROR_CORRUPTION_DETECTED: psa_status_t = -151; +pub const PSA_ERROR_DATA_CORRUPT: psa_status_t = -152; +pub const PSA_ERROR_DATA_INVALID: psa_status_t = -153; pub const PSA_ERROR_INSUFFICIENT_DATA: psa_status_t = -143; pub const PSA_ERROR_INVALID_HANDLE: psa_status_t = -136; diff --git a/psa-crypto-sys/src/lib.rs b/psa-crypto-sys/src/lib.rs index 228ce63..7ca54da 100644 --- a/psa-crypto-sys/src/lib.rs +++ b/psa-crypto-sys/src/lib.rs @@ -53,4 +53,3 @@ pub use psa_crypto_binding::{ #[cfg(feature = "implementation-defined")] pub use shim_methods::*; - diff --git a/psa-crypto/src/lib.rs b/psa-crypto/src/lib.rs index 422b881..fb43053 100644 --- a/psa-crypto/src/lib.rs +++ b/psa-crypto/src/lib.rs @@ -72,7 +72,7 @@ static INITIALISED: AtomicBool = AtomicBool::new(false); /// ``` #[cfg(feature = "with-mbed-crypto")] pub fn init() -> Result<()> { - // It it not a problem to call psa_crypto_init more than once. + // It is not a problem to call psa_crypto_init more than once. Status::from(unsafe { psa_crypto_sys::psa_crypto_init() }).to_result()?; let _ = INITIALISED.compare_and_swap(false, true, Ordering::Relaxed); diff --git a/psa-crypto/src/operations/key_management.rs b/psa-crypto/src/operations/key_management.rs index a209729..284df75 100644 --- a/psa-crypto/src/operations/key_management.rs +++ b/psa-crypto/src/operations/key_management.rs @@ -4,7 +4,7 @@ //! # Key Management operations use crate::initialized; -use crate::types::key::{Attributes, Id}; +use crate::types::key::{Attributes, Id, Lifetime}; use crate::types::status::{Result, Status}; use core::convert::TryFrom; /// Generate a key or a key pair @@ -47,21 +47,32 @@ use core::convert::TryFrom; #[cfg(not(feature = "no-std"))] pub fn generate(attributes: Attributes, id: Option) -> Result { initialized()?; - let mut attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?; + let mut key_attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?; let id = if let Some(id) = id { - unsafe { psa_crypto_sys::psa_set_key_id(&mut attributes, id) }; + unsafe { psa_crypto_sys::psa_set_key_id(&mut key_attributes, id) }; id } else { 0 }; let mut handle = 0; - Status::from(unsafe { psa_crypto_sys::psa_generate_key(&attributes, &mut handle) }) + Status::from(unsafe { psa_crypto_sys::psa_generate_key(&key_attributes, &mut handle) }) .to_result()?; - Attributes::reset(&mut attributes); - Ok(Id { - id, - handle: Some(handle), - }) + Attributes::reset(&mut key_attributes); + match attributes.lifetime { + Lifetime::Persistent | Lifetime::Custom(_) => { + Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result()?; + Ok(Id { + id, + handle: None + }) + }, + Lifetime::Volatile => { + Ok(Id { + id, + handle: Some(handle), + }) + } + } } /// Destroy a key @@ -109,8 +120,7 @@ pub fn generate(attributes: Attributes, id: Option) -> Result { pub unsafe fn destroy(key: Id) -> Result<()> { initialized()?; let handle = key.handle()?; - Status::from(psa_crypto_sys::psa_destroy_key(handle)).to_result()?; - key.close_handle(handle) + Status::from(psa_crypto_sys::psa_destroy_key(handle)).to_result() } /// Import a key in binary format @@ -162,9 +172,9 @@ pub unsafe fn destroy(key: Id) -> Result<()> { pub fn import(attributes: Attributes, id: Option, data: &[u8]) -> Result { initialized()?; - let mut attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?; + let mut key_attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?; let id = if let Some(id) = id { - unsafe { psa_crypto_sys::psa_set_key_id(&mut attributes, id) }; + unsafe { psa_crypto_sys::psa_set_key_id(&mut key_attributes, id) }; id } else { 0 @@ -172,16 +182,27 @@ pub fn import(attributes: Attributes, id: Option, data: &[u8]) -> Result { + Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result()?; + Ok(Id { + id, + handle: None, + }) + }, + Lifetime::Volatile => { + Ok(Id { + id, + handle: Some(handle), + }) + } + } } /// Export a public key or the public part of a key pair in binary format @@ -274,7 +295,8 @@ pub fn export_public(key: Id, data: &mut [u8]) -> Result { pub fn get_key_attributes(key: Id) -> Result { initialized()?; let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() }; - - let _get_attributes_status = Status::from( unsafe { psa_crypto_sys::psa_get_key_attributes(key.handle()?.into(), &mut key_attributes) } ); + let handle = key.handle()?; + let _get_attributes_status = Status::from( unsafe { psa_crypto_sys::psa_get_key_attributes(handle.into(), &mut key_attributes) } ); + key.close_handle(handle)?; Ok(Attributes::try_from(key_attributes)?) } \ No newline at end of file diff --git a/psa-crypto/src/types/key.rs b/psa-crypto/src/types/key.rs index fc6d637..0ff847f 100644 --- a/psa-crypto/src/types/key.rs +++ b/psa-crypto/src/types/key.rs @@ -13,6 +13,7 @@ use crate::types::status::{Error, Result}; use core::convert::{TryFrom, TryInto}; use log::error; use serde::{Deserialize, Serialize}; +pub use psa_crypto_sys::psa_key_id_t as key_id_type; /// Native definition of the attributes needed to fully describe /// a cryptographic key. @@ -473,7 +474,7 @@ pub struct UsageFlags { #[cfg(feature = "with-mbed-crypto")] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Id { - pub(crate) id: psa_crypto_sys::psa_key_id_t, + pub(crate) id: key_id_type, pub(crate) handle: Option, } @@ -493,7 +494,7 @@ impl Id { } pub(crate) fn close_handle(self, handle: psa_crypto_sys::psa_key_handle_t) -> Result<()> { - if !self.handle.is_none() { + if self.handle.is_none() { Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result() } else { Ok(()) diff --git a/psa-crypto/src/types/status.rs b/psa-crypto/src/types/status.rs index 1a1c81c..216a377 100644 --- a/psa-crypto/src/types/status.rs +++ b/psa-crypto/src/types/status.rs @@ -186,6 +186,9 @@ impl From for Status { psa_crypto_sys::PSA_ERROR_INVALID_PADDING => Error::InvalidPadding.into(), psa_crypto_sys::PSA_ERROR_INSUFFICIENT_DATA => Error::InsufficientData.into(), psa_crypto_sys::PSA_ERROR_INVALID_HANDLE => Error::InvalidHandle.into(), + psa_crypto_sys::PSA_ERROR_CORRUPTION_DETECTED => Error::CorruptionDetected.into(), + psa_crypto_sys::PSA_ERROR_DATA_CORRUPT => Error::DataCorrupt.into(), + psa_crypto_sys::PSA_ERROR_DATA_INVALID => Error::DataInvalid.into(), s => { error!("{} not recognised as a valid PSA status.", s); Status::Error(Error::GenericError) @@ -218,19 +221,21 @@ impl From for psa_crypto_sys::psa_status_t { Error::InsufficientStorage => psa_crypto_sys::PSA_ERROR_INSUFFICIENT_STORAGE, Error::CommunicationFailure => psa_crypto_sys::PSA_ERROR_COMMUNICATION_FAILURE, Error::StorageFailure => psa_crypto_sys::PSA_ERROR_STORAGE_FAILURE, - //Error::DataCorrupt => psa_crypto_sys::PSA_ERROR_DATA_CORRUPT, - //Error::DataInvalid => psa_crypto_sys::PSA_ERROR_DATA_INVALID, + Error::DataCorrupt => psa_crypto_sys::PSA_ERROR_DATA_CORRUPT, + Error::DataInvalid => psa_crypto_sys::PSA_ERROR_DATA_INVALID, Error::HardwareFailure => psa_crypto_sys::PSA_ERROR_HARDWARE_FAILURE, - //Error::CorruptionDetected => psa_crypto_sys::PSA_ERROR_CORRUPTION_DETECTED, + Error::CorruptionDetected => psa_crypto_sys::PSA_ERROR_CORRUPTION_DETECTED, Error::InsufficientEntropy => psa_crypto_sys::PSA_ERROR_INSUFFICIENT_ENTROPY, Error::InvalidSignature => psa_crypto_sys::PSA_ERROR_INVALID_SIGNATURE, Error::InvalidPadding => psa_crypto_sys::PSA_ERROR_INVALID_PADDING, Error::InsufficientData => psa_crypto_sys::PSA_ERROR_INSUFFICIENT_DATA, Error::InvalidHandle => psa_crypto_sys::PSA_ERROR_INVALID_HANDLE, - e => { + + // Commented out as all errors are currently matched against and this causes compilation error + /*e => { error!("No equivalent of {:?} to a psa_status_t.", e); psa_crypto_sys::PSA_ERROR_GENERIC_ERROR - } + }*/ } } } From d361726eb544d70900fead93d79710f299bb75af Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Fri, 12 Jun 2020 12:31:54 +0100 Subject: [PATCH 3/9] Changed error handling when psa-crypto-sys operation fails - prioritise key handle closing error. Signed-off-by: Samuel Bailey --- psa-crypto/src/operations/asym_signature.rs | 15 ++- psa-crypto/src/operations/key_management.rs | 73 ++++++------- psa-crypto/tests/mod.rs | 114 ++++++++++++++++++++ 3 files changed, 154 insertions(+), 48 deletions(-) create mode 100644 psa-crypto/tests/mod.rs diff --git a/psa-crypto/src/operations/asym_signature.rs b/psa-crypto/src/operations/asym_signature.rs index cf92947..bc5b83d 100644 --- a/psa-crypto/src/operations/asym_signature.rs +++ b/psa-crypto/src/operations/asym_signature.rs @@ -64,7 +64,7 @@ pub fn sign_hash( let mut signature_length = 0; let handle = key.handle()?; - Status::from(unsafe { + let sign_res = Status::from(unsafe { psa_crypto_sys::psa_sign_hash( handle, alg.into(), @@ -75,10 +75,9 @@ pub fn sign_hash( &mut signature_length, ) }) - .to_result()?; - + .to_result(); key.close_handle(handle)?; - + sign_res?; Ok(signature_length) } @@ -130,7 +129,7 @@ pub fn verify_hash(key: Id, alg: AsymmetricSignature, hash: &[u8], signature: &[ let handle = key.handle()?; - Status::from(unsafe { + let verify_res = Status::from(unsafe { psa_crypto_sys::psa_verify_hash( handle, alg.into(), @@ -140,7 +139,7 @@ pub fn verify_hash(key: Id, alg: AsymmetricSignature, hash: &[u8], signature: &[ signature.len(), ) }) - .to_result()?; - - key.close_handle(handle) + .to_result(); + key.close_handle(handle)?; + verify_res } diff --git a/psa-crypto/src/operations/key_management.rs b/psa-crypto/src/operations/key_management.rs index 284df75..632a787 100644 --- a/psa-crypto/src/operations/key_management.rs +++ b/psa-crypto/src/operations/key_management.rs @@ -7,6 +7,8 @@ use crate::initialized; use crate::types::key::{Attributes, Id, Lifetime}; use crate::types::status::{Result, Status}; use core::convert::TryFrom; +use psa_crypto_sys::{psa_key_handle_t, psa_key_id_t}; + /// Generate a key or a key pair /// /// `id` can be set to `None` when creating a volatile key. Setting the `id` to something will @@ -55,26 +57,14 @@ pub fn generate(attributes: Attributes, id: Option) -> Result { 0 }; let mut handle = 0; - Status::from(unsafe { psa_crypto_sys::psa_generate_key(&key_attributes, &mut handle) }) - .to_result()?; + let gen_res = Status::from(unsafe { psa_crypto_sys::psa_generate_key(&key_attributes, &mut handle) }) + .to_result(); Attributes::reset(&mut key_attributes); - match attributes.lifetime { - Lifetime::Persistent | Lifetime::Custom(_) => { - Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result()?; - Ok(Id { - id, - handle: None - }) - }, - Lifetime::Volatile => { - Ok(Id { - id, - handle: Some(handle), - }) - } - } + + complete_new_key_operation(attributes.lifetime, id, handle, gen_res) } + /// Destroy a key /// /// # Safety @@ -181,28 +171,14 @@ pub fn import(attributes: Attributes, id: Option, data: &[u8]) -> Result { - Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result()?; - Ok(Id { - id, - handle: None, - }) - }, - Lifetime::Volatile => { - Ok(Id { - id, - handle: Some(handle), - }) - } - } + complete_new_key_operation(attributes.lifetime, id, handle, gen_res) } /// Export a public key or the public part of a key pair in binary format @@ -244,18 +220,16 @@ pub fn export_public(key: Id, data: &mut [u8]) -> Result { let handle = key.handle()?; let mut data_length = 0; - Status::from(unsafe { + let export_res = Status::from(unsafe { psa_crypto_sys::psa_export_public_key( handle, data.as_mut_ptr(), data.len(), &mut data_length, ) - }) - .to_result()?; - + }).to_result(); key.close_handle(handle)?; - + export_res?; Ok(data_length) } @@ -296,7 +270,26 @@ pub fn get_key_attributes(key: Id) -> Result { initialized()?; let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() }; let handle = key.handle()?; - let _get_attributes_status = Status::from( unsafe { psa_crypto_sys::psa_get_key_attributes(handle.into(), &mut key_attributes) } ); + let attributes_res = Status::from( unsafe { psa_crypto_sys::psa_get_key_attributes( + handle.into(), &mut key_attributes) } ).to_result(); key.close_handle(handle)?; + attributes_res?; Ok(Attributes::try_from(key_attributes)?) +} + + +/// Completes a new key operation (either generate or import) +/// +/// If key is not `Volatile` (`Persistent` or `Custom(u32)`), handle is closed. +/// +/// If a key is `Volatile`, `Id` returned contains the key `handle`. Otherwise, it does not. +fn complete_new_key_operation(key_lifetime: Lifetime, id: psa_key_id_t, handle: psa_key_handle_t, operation_result: Result<()>) -> Result { + if key_lifetime != Lifetime::Volatile { + Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result()?; + } + operation_result?; + Ok(Id { + id, + handle: if key_lifetime == Lifetime::Volatile { Some(handle) } else { None } + }) } \ No newline at end of file diff --git a/psa-crypto/tests/mod.rs b/psa-crypto/tests/mod.rs new file mode 100644 index 0000000..2ad6300 --- /dev/null +++ b/psa-crypto/tests/mod.rs @@ -0,0 +1,114 @@ +// Copyright 2020 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + + +use psa_crypto::types::key::{Attributes, Lifetime, Type, Policy, UsageFlags}; +use psa_crypto::types::algorithm::{Algorithm, Hash, AsymmetricSignature}; + +#[test] +fn generate_integration_test() { + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaKeyPair, + bits: 1024, + policy: Policy { + usage_flags: UsageFlags { + sign_hash: true, + verify_hash: true, + sign_message: true, + verify_message: true, + export: true, + encrypt: false, + decrypt: false, + cache: false, + copy: false, + derive: false, + }, + permitted_algorithms: Algorithm::AsymmetricSignature( + AsymmetricSignature::RsaPkcs1v15Sign { + hash_alg: Hash::Sha256.into(), + }, + ), + }, + }; + let mut test_client = test_tools::TestClient::new(); + + // Ensure that a large number of keys can be generated + for key_index in 1..101u32 { + test_client.generate(attributes, key_index); + } +} + +#[test] +fn import_integration_test() { + const KEY_DATA: [u8; 140] = [ + 48, 129, 137, 2, 129, 129, 0, 153, 165, 220, 135, 89, 101, 254, 229, 28, 33, 138, 247, 20, 102, + 253, 217, 247, 246, 142, 107, 51, 40, 179, 149, 45, 117, 254, 236, 161, 109, 16, 81, 135, 72, + 112, 132, 150, 175, 128, 173, 182, 122, 227, 214, 196, 130, 54, 239, 93, 5, 203, 185, 233, 61, + 159, 156, 7, 161, 87, 48, 234, 105, 161, 108, 215, 211, 150, 168, 156, 212, 6, 63, 81, 24, 101, + 72, 160, 97, 243, 142, 86, 10, 160, 122, 8, 228, 178, 252, 35, 209, 222, 228, 16, 143, 99, 143, + 146, 241, 186, 187, 22, 209, 86, 141, 24, 159, 12, 146, 44, 111, 254, 183, 54, 229, 109, 28, + 39, 22, 141, 173, 85, 26, 58, 9, 128, 27, 57, 131, 2, 3, 1, 0, 1, + ]; + + let attributes = Attributes { + lifetime: Lifetime::Persistent, + key_type: Type::RsaPublicKey, + bits: 1024, + policy: Policy { + usage_flags: UsageFlags { + sign_hash: true, + sign_message: true, + verify_hash: true, + verify_message: true, + ..Default::default() + }, + permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { + hash_alg: Hash::Sha256.into(), + }.into(), + }, + }; + + let mut test_client = test_tools::TestClient::new(); + + // Ensure that a large number of keys can be imported + for key_index in 1..101u32 { + test_client.import(attributes, key_index, &KEY_DATA); + } + + +} + +mod test_tools { + use psa_crypto::types::key::{Attributes, Id}; + use psa_crypto::operations::key_management; + + pub struct TestClient { + keys: Vec + } + + impl TestClient { + pub fn new() -> Self { + psa_crypto::init().unwrap(); + TestClient { + keys: Vec::new(), + } + } + + pub fn generate(&mut self, attributes: Attributes, key_id: u32) { + self.keys.push(key_management::generate(attributes, Some(key_id)).unwrap()); + } + + pub fn import(&mut self, attributes: Attributes, key_id: u32, key_data: &[u8]) { + self.keys.push(key_management::import(attributes, Some(key_id), key_data).unwrap()); + } + } + + impl Drop for TestClient { + fn drop(&mut self) { + for key in self.keys.clone() { + unsafe { key_management::destroy(key) }.unwrap(); + } + } + } +} \ No newline at end of file From 6fd4469a07a5ecf96554dad02402478bffb8e765 Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Fri, 12 Jun 2020 13:21:39 +0100 Subject: [PATCH 4/9] Added drop method to clean up mbedtls resources. Signed-off-by: Samuel Bailey --- psa-crypto-sys/src/constants.rs | 2 ++ psa-crypto-sys/src/lib.rs | 2 +- psa-crypto/src/lib.rs | 15 +++++++++++++++ psa-crypto/src/types/key.rs | 3 ++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/psa-crypto-sys/src/constants.rs b/psa-crypto-sys/src/constants.rs index 3f36cd0..e0a6939 100644 --- a/psa-crypto-sys/src/constants.rs +++ b/psa-crypto-sys/src/constants.rs @@ -90,6 +90,8 @@ pub const PSA_KEY_USAGE_DECRYPT: psa_key_usage_t = 512; pub const PSA_KEY_USAGE_SIGN: psa_key_usage_t = 1024; pub const PSA_KEY_USAGE_VERIFY: psa_key_usage_t = 2048; pub const PSA_KEY_USAGE_DERIVE: psa_key_usage_t = 4096; +pub const PSA_KEY_SLOT_COUNT: isize = 32; +pub const PSA_MAX_PERSISTENT_KEY_IDENTIFIER: psa_key_id_t = 0x3fff_ffff; #[cfg(feature = "implementation-defined")] pub const PSA_DRV_SE_HAL_VERSION: u32 = 5; diff --git a/psa-crypto-sys/src/lib.rs b/psa-crypto-sys/src/lib.rs index 7ca54da..fbd5a36 100644 --- a/psa-crypto-sys/src/lib.rs +++ b/psa-crypto-sys/src/lib.rs @@ -41,7 +41,7 @@ pub use types::*; pub use psa_crypto_binding::{ psa_close_key, psa_crypto_init, psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, psa_key_attributes_t, psa_open_key, psa_reset_key_attributes, psa_sign_hash, - psa_verify_hash, + psa_verify_hash, mbedtls_psa_crypto_free, }; // Secure Element Driver definitions diff --git a/psa-crypto/src/lib.rs b/psa-crypto/src/lib.rs index fb43053..61f8655 100644 --- a/psa-crypto/src/lib.rs +++ b/psa-crypto/src/lib.rs @@ -96,3 +96,18 @@ pub fn initialized() -> Result<()> { Err(Error::BadState) } } + +/// Closes mbedtls, releasing resources +/// +/// Example +/// +/// ``` +/// use psa_crypto::{init, drop}; +/// init().unwrap(); +/// // ... +/// drop(); +/// ``` +#[cfg(feature = "with-mbed-crypto")] +pub fn drop() { + unsafe { psa_crypto_sys::mbedtls_psa_crypto_free(); } +} \ No newline at end of file diff --git a/psa-crypto/src/types/key.rs b/psa-crypto/src/types/key.rs index 0ff847f..32e4f79 100644 --- a/psa-crypto/src/types/key.rs +++ b/psa-crypto/src/types/key.rs @@ -13,7 +13,8 @@ use crate::types::status::{Error, Result}; use core::convert::{TryFrom, TryInto}; use log::error; use serde::{Deserialize, Serialize}; -pub use psa_crypto_sys::psa_key_id_t as key_id_type; +pub use psa_crypto_sys::{psa_key_id_t as key_id_type, PSA_KEY_SLOT_COUNT, + PSA_MAX_PERSISTENT_KEY_IDENTIFIER}; /// Native definition of the attributes needed to fully describe /// a cryptographic key. From fd73ed19fae0a3780546f80aff376bf7be904ce6 Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Mon, 15 Jun 2020 09:10:32 +0100 Subject: [PATCH 5/9] Removed unecessary shim binding for get_key_attributes Signed-off-by: Samuel Bailey --- psa-crypto-sys/src/c/shim.c | 6 ------ psa-crypto-sys/src/lib.rs | 2 +- psa-crypto-sys/src/shim_methods.rs | 6 +----- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/psa-crypto-sys/src/c/shim.c b/psa-crypto-sys/src/c/shim.c index 8746fab..a5b9846 100644 --- a/psa-crypto-sys/src/c/shim.c +++ b/psa-crypto-sys/src/c/shim.c @@ -49,12 +49,6 @@ shim_key_attributes_init(void) return psa_key_attributes_init(); } -psa_status_t -shim_get_key_attributes(psa_key_handle_t key_handle, psa_key_attributes_t *attributes) -{ - return psa_get_key_attributes(key_handle, attributes); -} - void shim_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg) diff --git a/psa-crypto-sys/src/lib.rs b/psa-crypto-sys/src/lib.rs index fbd5a36..0dfb7aa 100644 --- a/psa-crypto-sys/src/lib.rs +++ b/psa-crypto-sys/src/lib.rs @@ -41,7 +41,7 @@ pub use types::*; pub use psa_crypto_binding::{ psa_close_key, psa_crypto_init, psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, psa_key_attributes_t, psa_open_key, psa_reset_key_attributes, psa_sign_hash, - psa_verify_hash, mbedtls_psa_crypto_free, + psa_verify_hash, mbedtls_psa_crypto_free, psa_get_key_attributes, }; // Secure Element Driver definitions diff --git a/psa-crypto-sys/src/shim_methods.rs b/psa-crypto-sys/src/shim_methods.rs index 1a41994..bb740c6 100644 --- a/psa-crypto-sys/src/shim_methods.rs +++ b/psa-crypto-sys/src/shim_methods.rs @@ -3,7 +3,7 @@ use super::psa_crypto_binding::{ self, psa_algorithm_t, psa_dh_group_t, psa_ecc_curve_t, psa_key_attributes_t, psa_key_id_t, - psa_key_lifetime_t, psa_key_type_t, psa_key_usage_t, psa_status_t, psa_key_handle_t + psa_key_lifetime_t, psa_key_type_t, psa_key_usage_t }; pub unsafe fn psa_get_key_bits(attributes: *const psa_key_attributes_t) -> usize { @@ -30,10 +30,6 @@ pub unsafe fn psa_key_attributes_init() -> psa_key_attributes_t { psa_crypto_binding::shim_key_attributes_init() } -pub unsafe fn psa_get_key_attributes(key_handle: psa_key_handle_t, attributes: *mut psa_key_attributes_t) -> psa_status_t { - psa_crypto_binding::shim_get_key_attributes(key_handle, attributes) -} - pub unsafe fn psa_set_key_algorithm(attributes: *mut psa_key_attributes_t, alg: psa_algorithm_t) { psa_crypto_binding::shim_set_key_algorithm(attributes, alg); } From d539aed5c5be7b1e6b9784107ed2e214dfc8ba5d Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Mon, 15 Jun 2020 13:09:09 +0100 Subject: [PATCH 6/9] Fixes for CI Signed-off-by: Samuel Bailey --- psa-crypto-sys/src/lib.rs | 6 +-- psa-crypto-sys/src/shim_methods.rs | 2 +- psa-crypto-sys/vendor | 2 +- psa-crypto/src/lib.rs | 6 ++- psa-crypto/src/operations/key_management.rs | 38 ++++++++++++------- psa-crypto/src/types/key.rs | 5 ++- psa-crypto/src/types/status.rs | 1 - psa-crypto/tests/mod.rs | 41 ++++++++++----------- 8 files changed, 56 insertions(+), 45 deletions(-) diff --git a/psa-crypto-sys/src/lib.rs b/psa-crypto-sys/src/lib.rs index 0dfb7aa..5c98cfe 100644 --- a/psa-crypto-sys/src/lib.rs +++ b/psa-crypto-sys/src/lib.rs @@ -39,9 +39,9 @@ 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_import_key, psa_key_attributes_t, psa_open_key, psa_reset_key_attributes, psa_sign_hash, - psa_verify_hash, mbedtls_psa_crypto_free, psa_get_key_attributes, + mbedtls_psa_crypto_free, 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 bb740c6..6e5941d 100644 --- a/psa-crypto-sys/src/shim_methods.rs +++ b/psa-crypto-sys/src/shim_methods.rs @@ -3,7 +3,7 @@ use super::psa_crypto_binding::{ self, psa_algorithm_t, psa_dh_group_t, psa_ecc_curve_t, psa_key_attributes_t, psa_key_id_t, - psa_key_lifetime_t, psa_key_type_t, psa_key_usage_t + psa_key_lifetime_t, psa_key_type_t, psa_key_usage_t, }; pub unsafe fn psa_get_key_bits(attributes: *const psa_key_attributes_t) -> usize { diff --git a/psa-crypto-sys/vendor b/psa-crypto-sys/vendor index ac15f84..3c4a46c 160000 --- a/psa-crypto-sys/vendor +++ b/psa-crypto-sys/vendor @@ -1 +1 @@ -Subproject commit ac15f842a5bb8d4cbceb7175c5d7ab50d96173c0 +Subproject commit 3c4a46c44a3d149a71adf36629bfb6ddc5188bcb diff --git a/psa-crypto/src/lib.rs b/psa-crypto/src/lib.rs index 61f8655..d51d131 100644 --- a/psa-crypto/src/lib.rs +++ b/psa-crypto/src/lib.rs @@ -109,5 +109,7 @@ pub fn initialized() -> Result<()> { /// ``` #[cfg(feature = "with-mbed-crypto")] pub fn drop() { - unsafe { psa_crypto_sys::mbedtls_psa_crypto_free(); } -} \ No newline at end of file + unsafe { + psa_crypto_sys::mbedtls_psa_crypto_free(); + } +} diff --git a/psa-crypto/src/operations/key_management.rs b/psa-crypto/src/operations/key_management.rs index 632a787..4918f0b 100644 --- a/psa-crypto/src/operations/key_management.rs +++ b/psa-crypto/src/operations/key_management.rs @@ -46,7 +46,6 @@ use psa_crypto_sys::{psa_key_handle_t, psa_key_id_t}; /// psa_crypto::init().unwrap(); /// let _my_key = key_management::generate(attributes, None).unwrap(); /// ``` -#[cfg(not(feature = "no-std"))] pub fn generate(attributes: Attributes, id: Option) -> Result { initialized()?; let mut key_attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?; @@ -57,14 +56,14 @@ pub fn generate(attributes: Attributes, id: Option) -> Result { 0 }; let mut handle = 0; - let gen_res = Status::from(unsafe { psa_crypto_sys::psa_generate_key(&key_attributes, &mut handle) }) - .to_result(); + let gen_res = + Status::from(unsafe { psa_crypto_sys::psa_generate_key(&key_attributes, &mut handle) }) + .to_result(); Attributes::reset(&mut key_attributes); complete_new_key_operation(attributes.lifetime, id, handle, gen_res) } - /// Destroy a key /// /// # Safety @@ -227,18 +226,19 @@ pub fn export_public(key: Id, data: &mut [u8]) -> Result { data.len(), &mut data_length, ) - }).to_result(); + }) + .to_result(); key.close_handle(handle)?; export_res?; Ok(data_length) } /// Gets the attributes for a given key ID -/// +/// /// The `Id` structure can be created with the `from_persistent_key_id` constructor on `Id`. -/// +/// /// # Example -/// +/// /// ``` /// # use psa_crypto::operations::key_management; /// # use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags}; @@ -270,26 +270,36 @@ pub fn get_key_attributes(key: Id) -> Result { initialized()?; let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() }; let handle = key.handle()?; - let attributes_res = Status::from( unsafe { psa_crypto_sys::psa_get_key_attributes( - handle.into(), &mut key_attributes) } ).to_result(); + let attributes_res = Status::from(unsafe { + psa_crypto_sys::psa_get_key_attributes(handle, &mut key_attributes) + }) + .to_result(); key.close_handle(handle)?; attributes_res?; Ok(Attributes::try_from(key_attributes)?) } - /// Completes a new key operation (either generate or import) /// /// If key is not `Volatile` (`Persistent` or `Custom(u32)`), handle is closed. /// /// If a key is `Volatile`, `Id` returned contains the key `handle`. Otherwise, it does not. -fn complete_new_key_operation(key_lifetime: Lifetime, id: psa_key_id_t, handle: psa_key_handle_t, operation_result: Result<()>) -> Result { +fn complete_new_key_operation( + key_lifetime: Lifetime, + id: psa_key_id_t, + handle: psa_key_handle_t, + operation_result: Result<()>, +) -> Result { if key_lifetime != Lifetime::Volatile { Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result()?; } operation_result?; Ok(Id { id, - handle: if key_lifetime == Lifetime::Volatile { Some(handle) } else { None } + handle: if key_lifetime == Lifetime::Volatile { + Some(handle) + } else { + None + }, }) -} \ No newline at end of file +} diff --git a/psa-crypto/src/types/key.rs b/psa-crypto/src/types/key.rs index 32e4f79..278b9d9 100644 --- a/psa-crypto/src/types/key.rs +++ b/psa-crypto/src/types/key.rs @@ -12,9 +12,10 @@ use crate::types::status::{Error, Result}; #[cfg(feature = "with-mbed-crypto")] use core::convert::{TryFrom, TryInto}; use log::error; +pub use psa_crypto_sys::{ + psa_key_id_t as key_id_type, PSA_KEY_SLOT_COUNT, PSA_MAX_PERSISTENT_KEY_IDENTIFIER, +}; use serde::{Deserialize, Serialize}; -pub use psa_crypto_sys::{psa_key_id_t as key_id_type, PSA_KEY_SLOT_COUNT, - PSA_MAX_PERSISTENT_KEY_IDENTIFIER}; /// Native definition of the attributes needed to fully describe /// a cryptographic key. diff --git a/psa-crypto/src/types/status.rs b/psa-crypto/src/types/status.rs index 216a377..ff25983 100644 --- a/psa-crypto/src/types/status.rs +++ b/psa-crypto/src/types/status.rs @@ -230,7 +230,6 @@ impl From for psa_crypto_sys::psa_status_t { Error::InvalidPadding => psa_crypto_sys::PSA_ERROR_INVALID_PADDING, Error::InsufficientData => psa_crypto_sys::PSA_ERROR_INSUFFICIENT_DATA, Error::InvalidHandle => psa_crypto_sys::PSA_ERROR_INVALID_HANDLE, - // Commented out as all errors are currently matched against and this causes compilation error /*e => { error!("No equivalent of {:?} to a psa_status_t.", e); diff --git a/psa-crypto/tests/mod.rs b/psa-crypto/tests/mod.rs index 2ad6300..728696b 100644 --- a/psa-crypto/tests/mod.rs +++ b/psa-crypto/tests/mod.rs @@ -1,9 +1,8 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 - -use psa_crypto::types::key::{Attributes, Lifetime, Type, Policy, UsageFlags}; -use psa_crypto::types::algorithm::{Algorithm, Hash, AsymmetricSignature}; +use psa_crypto::types::algorithm::{Algorithm, AsymmetricSignature, Hash}; +use psa_crypto::types::key::{Attributes, Lifetime, Policy, Type, UsageFlags}; #[test] fn generate_integration_test() { @@ -42,13 +41,14 @@ fn generate_integration_test() { #[test] fn import_integration_test() { const KEY_DATA: [u8; 140] = [ - 48, 129, 137, 2, 129, 129, 0, 153, 165, 220, 135, 89, 101, 254, 229, 28, 33, 138, 247, 20, 102, - 253, 217, 247, 246, 142, 107, 51, 40, 179, 149, 45, 117, 254, 236, 161, 109, 16, 81, 135, 72, - 112, 132, 150, 175, 128, 173, 182, 122, 227, 214, 196, 130, 54, 239, 93, 5, 203, 185, 233, 61, - 159, 156, 7, 161, 87, 48, 234, 105, 161, 108, 215, 211, 150, 168, 156, 212, 6, 63, 81, 24, 101, - 72, 160, 97, 243, 142, 86, 10, 160, 122, 8, 228, 178, 252, 35, 209, 222, 228, 16, 143, 99, 143, - 146, 241, 186, 187, 22, 209, 86, 141, 24, 159, 12, 146, 44, 111, 254, 183, 54, 229, 109, 28, - 39, 22, 141, 173, 85, 26, 58, 9, 128, 27, 57, 131, 2, 3, 1, 0, 1, + 48, 129, 137, 2, 129, 129, 0, 153, 165, 220, 135, 89, 101, 254, 229, 28, 33, 138, 247, 20, + 102, 253, 217, 247, 246, 142, 107, 51, 40, 179, 149, 45, 117, 254, 236, 161, 109, 16, 81, + 135, 72, 112, 132, 150, 175, 128, 173, 182, 122, 227, 214, 196, 130, 54, 239, 93, 5, 203, + 185, 233, 61, 159, 156, 7, 161, 87, 48, 234, 105, 161, 108, 215, 211, 150, 168, 156, 212, + 6, 63, 81, 24, 101, 72, 160, 97, 243, 142, 86, 10, 160, 122, 8, 228, 178, 252, 35, 209, + 222, 228, 16, 143, 99, 143, 146, 241, 186, 187, 22, 209, 86, 141, 24, 159, 12, 146, 44, + 111, 254, 183, 54, 229, 109, 28, 39, 22, 141, 173, 85, 26, 58, 9, 128, 27, 57, 131, 2, 3, + 1, 0, 1, ]; let attributes = Attributes { @@ -65,7 +65,8 @@ fn import_integration_test() { }, permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { hash_alg: Hash::Sha256.into(), - }.into(), + } + .into(), }, }; @@ -75,32 +76,30 @@ fn import_integration_test() { for key_index in 1..101u32 { test_client.import(attributes, key_index, &KEY_DATA); } - - } mod test_tools { - use psa_crypto::types::key::{Attributes, Id}; use psa_crypto::operations::key_management; + use psa_crypto::types::key::{Attributes, Id}; pub struct TestClient { - keys: Vec + keys: Vec, } impl TestClient { pub fn new() -> Self { psa_crypto::init().unwrap(); - TestClient { - keys: Vec::new(), - } + TestClient { keys: Vec::new() } } pub fn generate(&mut self, attributes: Attributes, key_id: u32) { - self.keys.push(key_management::generate(attributes, Some(key_id)).unwrap()); + self.keys + .push(key_management::generate(attributes, Some(key_id)).unwrap()); } pub fn import(&mut self, attributes: Attributes, key_id: u32, key_data: &[u8]) { - self.keys.push(key_management::import(attributes, Some(key_id), key_data).unwrap()); + self.keys + .push(key_management::import(attributes, Some(key_id), key_data).unwrap()); } } @@ -111,4 +110,4 @@ mod test_tools { } } } -} \ No newline at end of file +} From 6f34968327f8c83507cd030577379bea02cb836d Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Mon, 15 Jun 2020 18:21:43 +0100 Subject: [PATCH 7/9] Addressed comments received. Signed-off-by: Samuel Bailey --- psa-crypto-sys/src/constants.rs | 2 - psa-crypto-sys/src/lib.rs | 6 +- psa-crypto/src/lib.rs | 18 +----- psa-crypto/src/operations/key_management.rs | 61 ++------------------- psa-crypto/src/types/key.rs | 54 ++++++++++++++++-- psa-crypto/src/types/status.rs | 5 -- 6 files changed, 60 insertions(+), 86 deletions(-) diff --git a/psa-crypto-sys/src/constants.rs b/psa-crypto-sys/src/constants.rs index e0a6939..3f36cd0 100644 --- a/psa-crypto-sys/src/constants.rs +++ b/psa-crypto-sys/src/constants.rs @@ -90,8 +90,6 @@ pub const PSA_KEY_USAGE_DECRYPT: psa_key_usage_t = 512; pub const PSA_KEY_USAGE_SIGN: psa_key_usage_t = 1024; pub const PSA_KEY_USAGE_VERIFY: psa_key_usage_t = 2048; pub const PSA_KEY_USAGE_DERIVE: psa_key_usage_t = 4096; -pub const PSA_KEY_SLOT_COUNT: isize = 32; -pub const PSA_MAX_PERSISTENT_KEY_IDENTIFIER: psa_key_id_t = 0x3fff_ffff; #[cfg(feature = "implementation-defined")] pub const PSA_DRV_SE_HAL_VERSION: u32 = 5; diff --git a/psa-crypto-sys/src/lib.rs b/psa-crypto-sys/src/lib.rs index 5c98cfe..735e270 100644 --- a/psa-crypto-sys/src/lib.rs +++ b/psa-crypto-sys/src/lib.rs @@ -39,9 +39,9 @@ pub use types::*; #[cfg(feature = "implementation-defined")] pub use psa_crypto_binding::{ - mbedtls_psa_crypto_free, 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_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/src/lib.rs b/psa-crypto/src/lib.rs index d51d131..a2a7e81 100644 --- a/psa-crypto/src/lib.rs +++ b/psa-crypto/src/lib.rs @@ -43,6 +43,7 @@ #[cfg(feature = "with-mbed-crypto")] pub mod operations; +#[cfg(feature = "with-mbed-crypto")] pub mod types; #[cfg(feature = "with-mbed-crypto")] @@ -96,20 +97,3 @@ pub fn initialized() -> Result<()> { Err(Error::BadState) } } - -/// Closes mbedtls, releasing resources -/// -/// Example -/// -/// ``` -/// use psa_crypto::{init, drop}; -/// init().unwrap(); -/// // ... -/// drop(); -/// ``` -#[cfg(feature = "with-mbed-crypto")] -pub fn drop() { - unsafe { - psa_crypto_sys::mbedtls_psa_crypto_free(); - } -} diff --git a/psa-crypto/src/operations/key_management.rs b/psa-crypto/src/operations/key_management.rs index 4918f0b..6ecf4aa 100644 --- a/psa-crypto/src/operations/key_management.rs +++ b/psa-crypto/src/operations/key_management.rs @@ -56,12 +56,11 @@ pub fn generate(attributes: Attributes, id: Option) -> Result { 0 }; let mut handle = 0; - let gen_res = - Status::from(unsafe { psa_crypto_sys::psa_generate_key(&key_attributes, &mut handle) }) - .to_result(); + Status::from(unsafe { psa_crypto_sys::psa_generate_key(&key_attributes, &mut handle) }) + .to_result()?; Attributes::reset(&mut key_attributes); - complete_new_key_operation(attributes.lifetime, id, handle, gen_res) + complete_new_key_operation(attributes.lifetime, id, handle) } /// Destroy a key @@ -170,14 +169,14 @@ pub fn import(attributes: Attributes, id: Option, data: &[u8]) -> Result Result { Ok(data_length) } -/// Gets the attributes for a given key ID -/// -/// The `Id` structure can be created with the `from_persistent_key_id` constructor on `Id`. -/// -/// # Example -/// -/// ``` -/// # use psa_crypto::operations::key_management; -/// # use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags}; -/// # use psa_crypto::types::algorithm::{AsymmetricSignature, Hash}; -/// # let mut attributes = Attributes { -/// # key_type: Type::RsaKeyPair, -/// # bits: 1024, -/// # lifetime: Lifetime::Volatile, -/// # policy: Policy { -/// # usage_flags: UsageFlags { -/// # sign_hash: true, -/// # sign_message: true, -/// # verify_hash: true, -/// # verify_message: true, -/// # ..Default::default() -/// # }, -/// # permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { -/// # hash_alg: Hash::Sha256.into(), -/// # }.into(), -/// # }, -/// # }; -/// psa_crypto::init().unwrap(); -/// let my_key = key_management::generate(attributes, None).unwrap(); -/// //... -/// let key_attributes = key_management::get_key_attributes(my_key); -/// ``` - -pub fn get_key_attributes(key: Id) -> Result { - initialized()?; - let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() }; - let handle = key.handle()?; - let attributes_res = Status::from(unsafe { - psa_crypto_sys::psa_get_key_attributes(handle, &mut key_attributes) - }) - .to_result(); - key.close_handle(handle)?; - attributes_res?; - Ok(Attributes::try_from(key_attributes)?) -} - /// Completes a new key operation (either generate or import) /// /// If key is not `Volatile` (`Persistent` or `Custom(u32)`), handle is closed. @@ -288,12 +241,10 @@ fn complete_new_key_operation( key_lifetime: Lifetime, id: psa_key_id_t, handle: psa_key_handle_t, - operation_result: Result<()>, ) -> Result { if key_lifetime != Lifetime::Volatile { Status::from(unsafe { psa_crypto_sys::psa_close_key(handle) }).to_result()?; } - operation_result?; Ok(Id { id, handle: if key_lifetime == Lifetime::Volatile { diff --git a/psa-crypto/src/types/key.rs b/psa-crypto/src/types/key.rs index 278b9d9..6d5330b 100644 --- a/psa-crypto/src/types/key.rs +++ b/psa-crypto/src/types/key.rs @@ -5,6 +5,7 @@ #![allow(deprecated)] +use crate::initialized; use crate::types::algorithm::{Algorithm, Cipher}; #[cfg(feature = "with-mbed-crypto")] use crate::types::status::Status; @@ -12,9 +13,7 @@ use crate::types::status::{Error, Result}; #[cfg(feature = "with-mbed-crypto")] use core::convert::{TryFrom, TryInto}; use log::error; -pub use psa_crypto_sys::{ - psa_key_id_t as key_id_type, PSA_KEY_SLOT_COUNT, PSA_MAX_PERSISTENT_KEY_IDENTIFIER, -}; +pub use psa_crypto_sys::{self, psa_key_id_t}; use serde::{Deserialize, Serialize}; /// Native definition of the attributes needed to fully describe @@ -258,6 +257,53 @@ impl Attributes { pub(crate) fn reset(attributes: &mut psa_crypto_sys::psa_key_attributes_t) { unsafe { psa_crypto_sys::psa_reset_key_attributes(attributes) }; } + + /// Gets the attributes for a given key ID + /// + /// The `Id` structure can be created with the `from_persistent_key_id` constructor on `Id`. + /// + /// # Example + /// + /// ``` + /// # use psa_crypto::operations::key_management; + /// # use psa_crypto::types::key::{Attributes, Type, Lifetime, Policy, UsageFlags}; + /// # use psa_crypto::types::algorithm::{AsymmetricSignature, Hash}; + /// # let mut attributes = Attributes { + /// # key_type: Type::RsaKeyPair, + /// # bits: 1024, + /// # lifetime: Lifetime::Volatile, + /// # policy: Policy { + /// # usage_flags: UsageFlags { + /// # sign_hash: true, + /// # sign_message: true, + /// # verify_hash: true, + /// # verify_message: true, + /// # ..Default::default() + /// # }, + /// # permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { + /// # hash_alg: Hash::Sha256.into(), + /// # }.into(), + /// # }, + /// # }; + /// psa_crypto::init().unwrap(); + /// let my_key_id = key_management::generate(attributes, None).unwrap(); + /// //... + /// let key_attributes = Attributes::from_key_id(my_key_id); + /// ``` + pub fn from_key_id(key_id: Id) -> Result { + initialized()?; + let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() }; + let handle = key_id.handle()?; + let get_attributes_res = Status::from(unsafe { + psa_crypto_sys::psa_get_key_attributes(handle, &mut key_attributes) + }) + .to_result(); + let attributes = Attributes::try_from(key_attributes); + Attributes::reset(&mut key_attributes); + key_id.close_handle(handle)?; + get_attributes_res?; + Ok(attributes?) + } } /// The lifetime of a key indicates where it is stored and which application and system actions @@ -476,7 +522,7 @@ pub struct UsageFlags { #[cfg(feature = "with-mbed-crypto")] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Id { - pub(crate) id: key_id_type, + pub(crate) id: psa_key_id_t, pub(crate) handle: Option, } diff --git a/psa-crypto/src/types/status.rs b/psa-crypto/src/types/status.rs index ff25983..2dfcc79 100644 --- a/psa-crypto/src/types/status.rs +++ b/psa-crypto/src/types/status.rs @@ -230,11 +230,6 @@ impl From for psa_crypto_sys::psa_status_t { Error::InvalidPadding => psa_crypto_sys::PSA_ERROR_INVALID_PADDING, Error::InsufficientData => psa_crypto_sys::PSA_ERROR_INSUFFICIENT_DATA, Error::InvalidHandle => psa_crypto_sys::PSA_ERROR_INVALID_HANDLE, - // Commented out as all errors are currently matched against and this causes compilation error - /*e => { - error!("No equivalent of {:?} to a psa_status_t.", e); - psa_crypto_sys::PSA_ERROR_GENERIC_ERROR - }*/ } } } From 2d7b6aed283866f7895e7c32690ab1986403777c Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Tue, 16 Jun 2020 09:50:55 +0100 Subject: [PATCH 8/9] Addresses further comments: Make feature gate for Attributes::from_key_id more local Tidy up and organise function and constant declarations Re-add ID min and max range values Signed-off-by: Samuel Bailey --- psa-crypto-sys/src/c/shim.h | 28 ++++++++-------------------- psa-crypto-sys/src/constants.rs | 12 +++++++----- psa-crypto/src/lib.rs | 2 +- psa-crypto/src/types/key.rs | 5 +++-- 4 files changed, 19 insertions(+), 28 deletions(-) diff --git a/psa-crypto-sys/src/c/shim.h b/psa-crypto-sys/src/c/shim.h index 56bdf5a..6169869 100644 --- a/psa-crypto-sys/src/c/shim.h +++ b/psa-crypto-sys/src/c/shim.h @@ -72,33 +72,21 @@ const psa_algorithm_t shim_PSA_ALG_TLS12_PSK_TO_MS_BASE = const psa_algorithm_t shim_PSA_ALG_KEY_DERIVATION_MASK = PSA_ALG_KEY_DERIVATION_MASK; -psa_key_id_t shim_get_key_id(const psa_key_attributes_t *attributes); - +psa_algorithm_t shim_get_key_algorithm(const psa_key_attributes_t *attributes); +psa_status_t shim_get_key_attributes(psa_key_handle_t key_handle, psa_key_attributes_t *attributes); size_t shim_get_key_bits(const psa_key_attributes_t *attributes); - +psa_key_id_t shim_get_key_id(const psa_key_attributes_t *attributes); +psa_key_lifetime_t shim_get_key_lifetime(const psa_key_attributes_t *attributes); psa_key_type_t shim_get_key_type(const psa_key_attributes_t *attributes); -psa_key_lifetime_t -shim_get_key_lifetime(const psa_key_attributes_t *attributes); -psa_algorithm_t shim_get_key_algorithm(const psa_key_attributes_t *attributes); -psa_key_usage_t -shim_get_key_usage_flags(const psa_key_attributes_t *attributes); +psa_key_usage_t shim_get_key_usage_flags(const psa_key_attributes_t *attributes); psa_key_attributes_t shim_key_attributes_init(void); -psa_status_t shim_get_key_attributes(psa_key_handle_t key_handle, psa_key_attributes_t *attributes); - -void shim_set_key_algorithm(psa_key_attributes_t *attributes, - psa_algorithm_t alg); +void shim_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg); void shim_set_key_bits(psa_key_attributes_t *attributes, size_t bits); - void shim_set_key_id(psa_key_attributes_t *attributes, psa_key_id_t id); - -void shim_set_key_lifetime(psa_key_attributes_t *attributes, - psa_key_lifetime_t lifetime); - +void shim_set_key_lifetime(psa_key_attributes_t *attributes, psa_key_lifetime_t lifetime); void shim_set_key_type(psa_key_attributes_t *attributes, psa_key_type_t type_); - -void shim_set_key_usage_flags(psa_key_attributes_t *attributes, - psa_key_usage_t usage_flags); +void shim_set_key_usage_flags(psa_key_attributes_t *attributes, psa_key_usage_t usage_flags); int shim_PSA_ALG_IS_HASH(psa_algorithm_t alg); int shim_PSA_ALG_IS_MAC(psa_algorithm_t alg); diff --git a/psa-crypto-sys/src/constants.rs b/psa-crypto-sys/src/constants.rs index 3f36cd0..25b65b2 100644 --- a/psa-crypto-sys/src/constants.rs +++ b/psa-crypto-sys/src/constants.rs @@ -10,15 +10,17 @@ use super::types::*; // PSA error codes pub const PSA_SUCCESS: psa_status_t = 0; pub const PSA_ERROR_GENERIC_ERROR: psa_status_t = -132; -pub const PSA_ERROR_NOT_SUPPORTED: psa_status_t = -134; pub const PSA_ERROR_NOT_PERMITTED: psa_status_t = -133; +pub const PSA_ERROR_NOT_SUPPORTED: psa_status_t = -134; +pub const PSA_ERROR_INVALID_ARGUMENT: psa_status_t = -135; +pub const PSA_ERROR_INVALID_HANDLE: psa_status_t = -136; +pub const PSA_ERROR_BAD_STATE: psa_status_t = -137; pub const PSA_ERROR_BUFFER_TOO_SMALL: psa_status_t = -138; pub const PSA_ERROR_ALREADY_EXISTS: psa_status_t = -139; pub const PSA_ERROR_DOES_NOT_EXIST: psa_status_t = -140; -pub const PSA_ERROR_BAD_STATE: psa_status_t = -137; -pub const PSA_ERROR_INVALID_ARGUMENT: psa_status_t = -135; pub const PSA_ERROR_INSUFFICIENT_MEMORY: psa_status_t = -141; pub const PSA_ERROR_INSUFFICIENT_STORAGE: psa_status_t = -142; +pub const PSA_ERROR_INSUFFICIENT_DATA: psa_status_t = -143; pub const PSA_ERROR_COMMUNICATION_FAILURE: psa_status_t = -145; pub const PSA_ERROR_STORAGE_FAILURE: psa_status_t = -146; pub const PSA_ERROR_HARDWARE_FAILURE: psa_status_t = -147; @@ -28,8 +30,6 @@ pub const PSA_ERROR_INVALID_PADDING: psa_status_t = -150; pub const PSA_ERROR_CORRUPTION_DETECTED: psa_status_t = -151; pub const PSA_ERROR_DATA_CORRUPT: psa_status_t = -152; pub const PSA_ERROR_DATA_INVALID: psa_status_t = -153; -pub const PSA_ERROR_INSUFFICIENT_DATA: psa_status_t = -143; -pub const PSA_ERROR_INVALID_HANDLE: psa_status_t = -136; pub const PSA_MAX_KEY_BITS: usize = 65528; pub const PSA_KEY_TYPE_NONE: psa_key_type_t = 0; @@ -90,6 +90,8 @@ pub const PSA_KEY_USAGE_DECRYPT: psa_key_usage_t = 512; pub const PSA_KEY_USAGE_SIGN: psa_key_usage_t = 1024; pub const PSA_KEY_USAGE_VERIFY: psa_key_usage_t = 2048; pub const PSA_KEY_USAGE_DERIVE: psa_key_usage_t = 4096; +pub const PSA_KEY_ID_USER_MIN: psa_key_id_t = 0x0000_0001; +pub const PSA_KEY_ID_USER_MAX: psa_key_id_t = 0x3fff_ffff; #[cfg(feature = "implementation-defined")] pub const PSA_DRV_SE_HAL_VERSION: u32 = 5; diff --git a/psa-crypto/src/lib.rs b/psa-crypto/src/lib.rs index a2a7e81..b535722 100644 --- a/psa-crypto/src/lib.rs +++ b/psa-crypto/src/lib.rs @@ -43,7 +43,6 @@ #[cfg(feature = "with-mbed-crypto")] pub mod operations; -#[cfg(feature = "with-mbed-crypto")] pub mod types; #[cfg(feature = "with-mbed-crypto")] @@ -63,6 +62,7 @@ static INITIALISED: AtomicBool = AtomicBool::new(false); /// Applications are permitted to call this function more than once. Once a call succeeds, /// subsequent calls are guaranteed to succeed. /// +/// /// # Example /// /// ```rust diff --git a/psa-crypto/src/types/key.rs b/psa-crypto/src/types/key.rs index 6d5330b..73741c1 100644 --- a/psa-crypto/src/types/key.rs +++ b/psa-crypto/src/types/key.rs @@ -4,7 +4,7 @@ //! # PSA Key types #![allow(deprecated)] - +#[cfg(feature = "with-mbed-crypto")] use crate::initialized; use crate::types::algorithm::{Algorithm, Cipher}; #[cfg(feature = "with-mbed-crypto")] @@ -13,7 +13,7 @@ use crate::types::status::{Error, Result}; #[cfg(feature = "with-mbed-crypto")] use core::convert::{TryFrom, TryInto}; use log::error; -pub use psa_crypto_sys::{self, psa_key_id_t}; +pub use psa_crypto_sys::{self, psa_key_id_t, PSA_KEY_ID_USER_MAX, PSA_KEY_ID_USER_MIN}; use serde::{Deserialize, Serialize}; /// Native definition of the attributes needed to fully describe @@ -290,6 +290,7 @@ impl Attributes { /// //... /// let key_attributes = Attributes::from_key_id(my_key_id); /// ``` + #[cfg(feature = "with-mbed-crypto")] pub fn from_key_id(key_id: Id) -> Result { initialized()?; let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() }; From 999187c806fbed4caf606a35ef567f04a0b046dd Mon Sep 17 00:00:00 2001 From: Samuel Bailey Date: Tue, 16 Jun 2020 10:37:21 +0100 Subject: [PATCH 9/9] Fix conflict between generate and import test ranges when running sumultaneously Signed-off-by: Samuel Bailey --- psa-crypto/tests/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psa-crypto/tests/mod.rs b/psa-crypto/tests/mod.rs index 728696b..caea2bf 100644 --- a/psa-crypto/tests/mod.rs +++ b/psa-crypto/tests/mod.rs @@ -73,7 +73,7 @@ fn import_integration_test() { let mut test_client = test_tools::TestClient::new(); // Ensure that a large number of keys can be imported - for key_index in 1..101u32 { + for key_index in 101..201u32 { test_client.import(attributes, key_index, &KEY_DATA); } }