From 6e65925fc02696cbe25a9bae3239b084fd4a65de Mon Sep 17 00:00:00 2001 From: Ionut Mihalcea Date: Thu, 24 Oct 2019 13:40:59 +0100 Subject: [PATCH] Upgrade dependency on Mbed Crypto to v2.0.0 This commit bumps the import version for the Mbed Crypto dependency to 2.0.0. It includes updates to make the code compatible and tests passing again. Signed-off-by: Ionut Mihalcea --- Cargo.lock | 8 +- Cargo.toml | 4 +- src/providers/mbed_provider/constants.rs | 4 +- src/providers/mbed_provider/mod.rs | 467 ++++++------------ .../{conversion_utils.rs => utils.rs} | 65 ++- 5 files changed, 203 insertions(+), 345 deletions(-) rename src/providers/mbed_provider/{conversion_utils.rs => utils.rs} (70%) diff --git a/Cargo.lock b/Cargo.lock index 116eeca5..027292d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,7 +417,7 @@ dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parsec-client-test 0.1.3 (git+https://github.com/parallaxsecond/parsec-client-test?tag=0.1.4)", + "parsec-client-test 0.1.5 (git+https://github.com/parallaxsecond/parsec-client-test?tag=0.1.5)", "parsec-interface 0.1.0 (git+https://github.com/parallaxsecond/parsec-interface-rs?tag=0.2.0)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sd-notify 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -431,8 +431,8 @@ dependencies = [ [[package]] name = "parsec-client-test" -version = "0.1.3" -source = "git+https://github.com/parallaxsecond/parsec-client-test?tag=0.1.4#5601b1fec07666febfcee54f953f95332d811008" +version = "0.1.5" +source = "git+https://github.com/parallaxsecond/parsec-client-test?tag=0.1.5#24964b0961c3a2d51fd567594f4c4c51a325739f" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -906,7 +906,7 @@ dependencies = [ "checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" -"checksum parsec-client-test 0.1.3 (git+https://github.com/parallaxsecond/parsec-client-test?tag=0.1.4)" = "" +"checksum parsec-client-test 0.1.5 (git+https://github.com/parallaxsecond/parsec-client-test?tag=0.1.5)" = "" "checksum parsec-interface 0.1.0 (git+https://github.com/parallaxsecond/parsec-interface-rs?tag=0.2.0)" = "" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" diff --git a/Cargo.toml b/Cargo.toml index ef09aa12..aae2c8e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ env_logger = "0.7.1" log = { version = "0.4.8", features = ["serde"] } [dev-dependencies] -parsec-client-test = { git = "https://github.com/parallaxsecond/parsec-client-test", tag = "0.1.4" } +parsec-client-test = { git = "https://github.com/parallaxsecond/parsec-client-test", tag = "0.1.5" } num_cpus = "1.10.1" [build-dependencies] @@ -34,7 +34,7 @@ toml = "0.4.2" serde = { version = "1.0", features = ["derive"] } [package.metadata.config] -mbed-crypto-version = "mbedcrypto-1.1.0" +mbed-crypto-version = "mbedcrypto-2.0.0" [features] default = ["mbed"] diff --git a/src/providers/mbed_provider/constants.rs b/src/providers/mbed_provider/constants.rs index e5eb1bc1..67fdc524 100644 --- a/src/providers/mbed_provider/constants.rs +++ b/src/providers/mbed_provider/constants.rs @@ -38,7 +38,9 @@ pub const PSA_ERROR_INVALID_PADDING: psa_status_t = -150; pub const PSA_ERROR_INSUFFICIENT_DATA: psa_status_t = -143; pub const PSA_ERROR_INVALID_HANDLE: psa_status_t = -136; -pub const PSA_MAX_PERSISTENT_KEY_IDENTIFIER: psa_key_id_t = 0xfffe_ffff; +pub const PSA_MAX_KEY_BITS: usize = 0xfff8; +pub const PSA_KEY_BITS_TOO_LARGE: psa_key_bits_t = 0xffff; +pub const PSA_MAX_PERSISTENT_KEY_IDENTIFIER: psa_key_id_t = 0x3fff_ffff; pub const PSA_KEY_SLOT_COUNT: isize = 32; pub const EMPTY_KEY_HANDLE: psa_key_handle_t = 0; pub const PSA_KEY_TYPE_NONE: psa_key_type_t = 0x0000_0000; diff --git a/src/providers/mbed_provider/mod.rs b/src/providers/mbed_provider/mod.rs index 6edac4fe..9212d437 100644 --- a/src/providers/mbed_provider/mod.rs +++ b/src/providers/mbed_provider/mod.rs @@ -29,6 +29,8 @@ use parsec_interface::operations::{OpExportPublicKey, ResultExportPublicKey}; use parsec_interface::operations::{OpImportKey, ResultImportKey}; use parsec_interface::operations::{OpListOpcodes, ResultListOpcodes}; use parsec_interface::requests::{Opcode, ProviderID, ResponseStatus, Result}; +use psa_crypto_binding::psa_key_handle_t as KeyHandle; +use psa_crypto_binding::psa_key_id_t as KeyId; use std_semaphore::Semaphore; use uuid::Uuid; @@ -43,9 +45,9 @@ mod psa_crypto_binding; #[allow(dead_code)] mod constants; -mod conversion_utils; +mod utils; -type LocalIdStore = HashSet; +type LocalIdStore = HashSet; const SUPPORTED_OPCODES: [Opcode; 7] = [ Opcode::CreateKey, @@ -79,10 +81,7 @@ pub struct MbedProvider { /// Gets a PSA Key ID from the Key ID Manager. /// Wrapper around the get method of the Key ID Manager to convert the key ID to the psa_key_id_t /// type. -fn get_key_id( - key_triple: &KeyTriple, - store_handle: &dyn ManageKeyIDs, -) -> Result { +fn get_key_id(key_triple: &KeyTriple, store_handle: &dyn ManageKeyIDs) -> Result { match store_handle.get(key_triple) { Ok(Some(key_id)) => { if let Ok(key_id_bytes) = key_id.try_into() { @@ -105,13 +104,13 @@ fn create_key_id( key_triple: KeyTriple, store_handle: &mut dyn ManageKeyIDs, local_ids_handle: &mut LocalIdStore, -) -> Result { - let mut key_id = rand::random::(); +) -> Result { + let mut key_id = rand::random::(); while local_ids_handle.contains(&key_id) - && key_id != 0 - && key_id < constants::PSA_MAX_PERSISTENT_KEY_IDENTIFIER + || key_id == 0 + || key_id > constants::PSA_MAX_PERSISTENT_KEY_IDENTIFIER { - key_id = rand::random::(); + key_id = rand::random::(); } match store_handle.insert(key_triple.clone(), key_id.to_ne_bytes().to_vec()) { Ok(insert_option) => { @@ -131,7 +130,7 @@ fn create_key_id( fn remove_key_id( key_triple: &KeyTriple, - key_id: psa_crypto_binding::psa_key_id_t, + key_id: KeyId, store_handle: &mut dyn ManageKeyIDs, local_ids_handle: &mut LocalIdStore, ) -> Result<()> { @@ -157,6 +156,32 @@ fn key_id_exists(key_triple: &KeyTriple, store_handle: &dyn ManageKeyIDs) -> Res } } +fn open_key(key_id: KeyId, key_handle_mutex: &Mutex<()>) -> Result { + let mut key_handle: KeyHandle = Default::default(); + let open_key_status = unsafe { + let _guard = key_handle_mutex + .lock() + .expect("Grabbing key handle mutex failed"); + psa_crypto_binding::psa_open_key(key_id, &mut key_handle) + }; + + if open_key_status != constants::PSA_SUCCESS { + error!("Open key status: {}", open_key_status); + Err(utils::convert_status(open_key_status)) + } else { + Ok(key_handle) + } +} + +fn release_key(key_handle: KeyHandle, key_handle_mutex: &Mutex<()>) { + unsafe { + let _guard = key_handle_mutex + .lock() + .expect("Grabbing key handle mutex failed"); + psa_crypto_binding::psa_close_key(key_handle); + } +} + impl MbedProvider { /// Creates and initialise a new instance of MbedProvider. /// Checks if there are not more keys stored in the Key ID Manager than in the MbedProvider and @@ -199,15 +224,9 @@ impl MbedProvider { continue; } }; - // Use psa_open_key to check if the key ID actually exists or not. - let mut key_handle: psa_crypto_binding::psa_key_handle_t = 0; - let open_key_status = unsafe { - psa_crypto_binding::psa_open_key( - constants::PSA_KEY_LIFETIME_PERSISTENT, - key_id, - &mut key_handle, - ) - }; + let mut key_handle: KeyHandle = Default::default(); + let open_key_status = + unsafe { psa_crypto_binding::psa_open_key(key_id, &mut key_handle) }; if open_key_status == constants::PSA_ERROR_DOES_NOT_EXIST { to_remove.push(key_triple.clone()); } else if open_key_status != constants::PSA_SUCCESS { @@ -278,83 +297,31 @@ impl Provide for MbedProvider { &mut local_ids_handle, )?; - let key_attrs = conversion_utils::convert_key_attributes(&key_attributes); - let mut key_handle: psa_crypto_binding::psa_key_handle_t = 0; + let key_attrs = utils::convert_key_attributes(&key_attributes, key_id); + let mut key_handle: KeyHandle = Default::default(); - let create_key_status = unsafe { + let generate_key_status = unsafe { let _guard = self .key_handle_mutex .lock() .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_create_key( - constants::PSA_KEY_LIFETIME_PERSISTENT, - key_id, - &mut key_handle, - ) + psa_crypto_binding::psa_generate_key(&key_attrs, &mut key_handle) }; - let ret_val: Result; - - if create_key_status == constants::PSA_SUCCESS { - let mut policy = psa_crypto_binding::psa_key_policy_t { - alg: 0, - alg2: 0, - usage: 0, - }; - - let set_policy_status = unsafe { - psa_crypto_binding::psa_key_policy_set_usage( - &mut policy, - key_attrs.key_usage, - key_attrs.algorithm, - ); - psa_crypto_binding::psa_set_key_policy(key_handle, &policy) - }; - - if set_policy_status == constants::PSA_SUCCESS { - let generate_key_status = unsafe { - psa_crypto_binding::psa_generate_key( - key_handle, - key_attrs.key_type, - key_attrs.key_size, - std::ptr::null(), - 0, - ) - }; - - if generate_key_status == constants::PSA_SUCCESS { - ret_val = Ok(ResultCreateKey {}); - } else { - ret_val = Err(conversion_utils::convert_status(generate_key_status)); - error!("Generate key status: {}", generate_key_status); - } - } else { - ret_val = Err(conversion_utils::convert_status(set_policy_status)); - error!("Set policy status: {}", set_policy_status); - } - - unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_close_key(key_handle); - } - } else { - ret_val = Err(conversion_utils::convert_status(create_key_status)); - error!("Create key status: {}", create_key_status); - } - - if ret_val.is_err() { + if generate_key_status != constants::PSA_SUCCESS { remove_key_id( &key_triple, key_id, &mut *store_handle, &mut local_ids_handle, )?; + error!("Generate key status: {}", generate_key_status); + return Err(utils::convert_status(generate_key_status)); } - ret_val + release_key(key_handle, &self.key_handle_mutex); + + Ok(ResultCreateKey {}) } fn import_key(&self, app_name: ApplicationName, op: OpImportKey) -> Result { @@ -375,82 +342,36 @@ impl Provide for MbedProvider { &mut local_ids_handle, )?; - let key_attrs = conversion_utils::convert_key_attributes(&key_attributes); - let mut key_handle: psa_crypto_binding::psa_key_handle_t = 0; + let key_attrs = utils::convert_key_attributes(&key_attributes, key_id); + let mut key_handle: KeyHandle = Default::default(); - let create_key_status = unsafe { + let import_key_status = unsafe { let _guard = self .key_handle_mutex .lock() .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_create_key( - constants::PSA_KEY_LIFETIME_PERSISTENT, - key_id, + psa_crypto_binding::psa_import_key( + &key_attrs, + key_data.as_ptr(), + key_data.len(), &mut key_handle, ) }; - let ret_val: Result; - - if create_key_status == constants::PSA_SUCCESS { - let mut policy = psa_crypto_binding::psa_key_policy_t { - alg: 0, - alg2: 0, - usage: 0, - }; - - let set_policy_status = unsafe { - psa_crypto_binding::psa_key_policy_set_usage( - &mut policy, - key_attrs.key_usage, - key_attrs.algorithm, - ); - psa_crypto_binding::psa_set_key_policy(key_handle, &policy) - }; - - if set_policy_status == constants::PSA_SUCCESS { - let import_key_status = unsafe { - psa_crypto_binding::psa_import_key( - key_handle, - key_attrs.key_type, - key_data.as_ptr(), - key_attrs.key_size, - ) - }; - - if import_key_status == constants::PSA_SUCCESS { - ret_val = Ok(ResultImportKey {}); - } else { - ret_val = Err(conversion_utils::convert_status(import_key_status)); - error!("Import key status: {}", import_key_status); - } - } else { - ret_val = Err(conversion_utils::convert_status(set_policy_status)); - error!("Set policy status: {}", set_policy_status); - } - - unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_close_key(key_handle); - } - } else { - ret_val = Err(conversion_utils::convert_status(create_key_status)); - error!("Create key status: {}", create_key_status); - } - - if ret_val.is_err() { + if import_key_status != constants::PSA_SUCCESS { remove_key_id( &key_triple, key_id, &mut *store_handle, &mut local_ids_handle, )?; + error!("Import key status: {}", import_key_status); + return Err(utils::convert_status(import_key_status)); } - ret_val + release_key(key_handle, &self.key_handle_mutex); + + Ok(ResultImportKey {}) } fn export_public_key( @@ -464,60 +385,33 @@ impl Provide for MbedProvider { let key_triple = KeyTriple::new(app_name, ProviderID::MbedProvider, key_name); let store_handle = self.key_id_store.read().expect("Key store lock poisoned"); let key_id = get_key_id(&key_triple, &*store_handle)?; - - let mut key_handle: psa_crypto_binding::psa_key_handle_t = 0; - + let key_handle: KeyHandle = open_key(key_id, &self.key_handle_mutex)?; let ret_val: Result; - - let open_key_status = unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_open_key( - constants::PSA_KEY_LIFETIME_PERSISTENT, - key_id, - &mut key_handle, + // TODO: There's no calculation of the buffer size here, nor is there any handling of the + // PSA_ERROR_BUFFER_TOO_SMALL condition. Just allocating a "big" buffer and assuming/hoping it is + // enough. + let mut buffer = vec![0u8; 1024]; + let mut actual_size = 0; + + let export_status = unsafe { + psa_crypto_binding::psa_export_public_key( + key_handle, + buffer.as_mut_ptr(), + 1024, + &mut actual_size, ) }; - if open_key_status == constants::PSA_SUCCESS { - // TODO: There's no calculation of the buffer size here, nor is there any handling of the - // PSA_ERROR_BUFFER_TOO_SMALL condition. Just allocating a "big" buffer and assuming/hoping it is - // enough. - - let mut buffer = vec![0u8; 1024]; - let mut actual_size = 0; - - let export_status = unsafe { - psa_crypto_binding::psa_export_public_key( - key_handle, - buffer.as_mut_ptr(), - 1024, - &mut actual_size, - ) - }; - - if export_status == constants::PSA_SUCCESS { - buffer.resize(actual_size, 0); - ret_val = Ok(ResultExportPublicKey { key_data: buffer }); - } else { - error!("Export status: {}", export_status); - ret_val = Err(conversion_utils::convert_status(export_status)); - } - - unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_close_key(key_handle); - } + if export_status == constants::PSA_SUCCESS { + buffer.resize(actual_size, 0); + ret_val = Ok(ResultExportPublicKey { key_data: buffer }); } else { - error!("Open key status: {}", open_key_status); - ret_val = Err(conversion_utils::convert_status(open_key_status)); + error!("Export status: {}", export_status); + ret_val = Err(utils::convert_status(export_status)); } + release_key(key_handle, &self.key_handle_mutex); + ret_val } @@ -529,37 +423,21 @@ impl Provide for MbedProvider { let mut store_handle = self.key_id_store.write().expect("Key store lock poisoned"); let mut local_ids_handle = self.local_ids.write().expect("Local ID lock poisoned"); let key_id = get_key_id(&key_triple, &*store_handle)?; + let key_handle: KeyHandle = open_key(key_id, &self.key_handle_mutex)?; - let mut key_handle: psa_crypto_binding::psa_key_handle_t = 0; + let destroy_key_status = unsafe { psa_crypto_binding::psa_destroy_key(key_handle) }; - let open_key_status = unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_open_key( - constants::PSA_KEY_LIFETIME_PERSISTENT, + if destroy_key_status == constants::PSA_SUCCESS { + remove_key_id( + &key_triple, key_id, - &mut key_handle, - ) - }; - - if open_key_status == constants::PSA_SUCCESS { - let destroy_key_status = unsafe { psa_crypto_binding::psa_destroy_key(key_handle) }; - - if destroy_key_status == constants::PSA_SUCCESS { - remove_key_id( - &key_triple, - key_id, - &mut *store_handle, - &mut local_ids_handle, - )?; - Ok(ResultDestroyKey {}) - } else { - Err(conversion_utils::convert_status(destroy_key_status)) - } + &mut *store_handle, + &mut local_ids_handle, + )?; + Ok(ResultDestroyKey {}) } else { - Err(conversion_utils::convert_status(open_key_status)) + error!("Destroy key status: {}", destroy_key_status); + Err(utils::convert_status(destroy_key_status)) } } @@ -571,70 +449,42 @@ impl Provide for MbedProvider { let key_triple = KeyTriple::new(app_name, ProviderID::MbedProvider, key_name); let store_handle = self.key_id_store.read().expect("Key store lock poisoned"); let key_id = get_key_id(&key_triple, &*store_handle)?; - - let mut key_handle: psa_crypto_binding::psa_key_handle_t = 0; - - let open_key_status = unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_open_key( - constants::PSA_KEY_LIFETIME_PERSISTENT, - key_id, - &mut key_handle, + let key_handle: KeyHandle = open_key(key_id, &self.key_handle_mutex)?; + let mut key_attrs = utils::get_empty_key_attributes(); + // Allocate a "big enough" buffer. (No handling of PSA_STATUS_BUFFER_TOO_SMALL here.) + let mut signature = [0u8; 1024]; + let mut signature_size: usize = 0; + + let sign_status = unsafe { + // Determine the algorithm by getting the key policy, and then getting + // the algorithm from the policy. No handling of failing status here. The key is open, + // and the policy is just data, so this shouldn't really fail. + psa_crypto_binding::psa_get_key_attributes(key_handle, &mut key_attrs); + + psa_crypto_binding::psa_asymmetric_sign( + key_handle, + key_attrs.core.policy.alg, + hash.as_ptr(), + hash.len(), + signature.as_mut_ptr(), + 1024, + &mut signature_size, ) }; - if open_key_status == constants::PSA_SUCCESS { - let mut policy = psa_crypto_binding::psa_key_policy_t { - alg: 0, - alg2: 0, - usage: 0, - }; + release_key(key_handle, &self.key_handle_mutex); - // Allocate a "big enough" buffer. (No handling of PSA_STATUS_BUFFER_TOO_SMALL here.) - let mut signature = [0u8; 1024]; - let mut signature_size: usize = 0; - - let sign_status = unsafe { - // Determine the algorithm by getting the key policy, and then getting - // the algorithm from the policy. No handling of failing status here. The key is open, - // and the policy is just data, so this shouldn't really fail. - psa_crypto_binding::psa_get_key_policy(key_handle, &mut policy); - - psa_crypto_binding::psa_asymmetric_sign( - key_handle, - psa_crypto_binding::psa_key_policy_get_algorithm(&policy), - hash.as_ptr(), - hash.len(), - signature.as_mut_ptr(), - 1024, - &mut signature_size, - ) + if sign_status == constants::PSA_SUCCESS { + let mut res = ResultAsymSign { + signature: Vec::new(), }; + res.signature.resize(signature_size, 0); + res.signature.copy_from_slice(&signature[0..signature_size]); - unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_close_key(key_handle); - } - - if sign_status == constants::PSA_SUCCESS { - let mut res = ResultAsymSign { - signature: Vec::new(), - }; - res.signature.resize(signature_size, 0); - res.signature.copy_from_slice(&signature[0..signature_size]); - - Ok(res) - } else { - Err(conversion_utils::convert_status(sign_status)) - } + Ok(res) } else { - Err(conversion_utils::convert_status(open_key_status)) + error!("Sign status: {}", sign_status); + Err(utils::convert_status(sign_status)) } } @@ -647,62 +497,31 @@ impl Provide for MbedProvider { let key_triple = KeyTriple::new(app_name, ProviderID::MbedProvider, key_name); let store_handle = self.key_id_store.read().expect("Key store lock poisoned"); let key_id = get_key_id(&key_triple, &*store_handle)?; - - let mut key_handle: psa_crypto_binding::psa_key_handle_t = 0; - - let open_key_status = unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_open_key( - constants::PSA_KEY_LIFETIME_PERSISTENT, - key_id, - &mut key_handle, + let key_handle: KeyHandle = open_key(key_id, &self.key_handle_mutex)?; + let mut key_attrs = utils::get_empty_key_attributes(); + + let verify_status = unsafe { + // Determine the algorithm by getting the key policy, and then getting + // the algorithm from the policy. No handling of failing status here. The key is open, + // and the policy is just data, so this shouldn't really fail. + psa_crypto_binding::psa_get_key_attributes(key_handle, &mut key_attrs); + + psa_crypto_binding::psa_asymmetric_verify( + key_handle, + key_attrs.core.policy.alg, + hash.as_ptr(), + hash.len(), + signature.as_ptr(), + signature.len(), ) }; - if open_key_status == constants::PSA_SUCCESS { - let mut policy = psa_crypto_binding::psa_key_policy_t { - alg: 0, - alg2: 0, - usage: 0, - }; - - let algorithm: psa_crypto_binding::psa_algorithm_t; - - let verify_status = unsafe { - // Determine the algorithm by getting the key policy, and then getting - // the algorithm from the policy. No handling of failing status here. The key is open, - // and the policy is just data, so this shouldn't really fail. - psa_crypto_binding::psa_get_key_policy(key_handle, &mut policy); - algorithm = psa_crypto_binding::psa_key_policy_get_algorithm(&policy); - - psa_crypto_binding::psa_asymmetric_verify( - key_handle, - algorithm, - hash.as_ptr(), - hash.len(), - signature.as_ptr(), - signature.len(), - ) - }; - - unsafe { - let _guard = self - .key_handle_mutex - .lock() - .expect("Grabbing key handle mutex failed"); - psa_crypto_binding::psa_close_key(key_handle); - } + release_key(key_handle, &self.key_handle_mutex); - if verify_status == constants::PSA_SUCCESS { - Ok(ResultAsymVerify {}) - } else { - Err(conversion_utils::convert_status(verify_status)) - } + if verify_status == constants::PSA_SUCCESS { + Ok(ResultAsymVerify {}) } else { - Err(conversion_utils::convert_status(open_key_status)) + Err(utils::convert_status(verify_status)) } } } diff --git a/src/providers/mbed_provider/conversion_utils.rs b/src/providers/mbed_provider/utils.rs similarity index 70% rename from src/providers/mbed_provider/conversion_utils.rs rename to src/providers/mbed_provider/utils.rs index 8d763e94..22fdad3c 100644 --- a/src/providers/mbed_provider/conversion_utils.rs +++ b/src/providers/mbed_provider/utils.rs @@ -13,29 +13,66 @@ // See the License for the specific language governing permissions and // limitations under the License. use super::constants::*; -use super::psa_crypto_binding::{psa_algorithm_t, psa_key_type_t, psa_key_usage_t, psa_status_t}; +use super::psa_crypto_binding::{ + psa_algorithm_t, psa_core_key_attributes_t, psa_key_attributes_t, psa_key_bits_t, psa_key_id_t, + psa_key_policy_s, psa_key_type_t, psa_key_usage_t, psa_status_t, +}; use parsec_interface::operations::key_attributes::*; use parsec_interface::requests::ResponseStatus; use std::convert::TryFrom; -/// This structure holds key attribute values to be used by the Mbed Crypto library. -pub struct MbedKeyAttributes { - pub key_type: psa_key_type_t, - pub algorithm: psa_algorithm_t, - pub key_size: usize, - pub key_usage: psa_key_usage_t, +/// Converts between native PARSEC key attributes and ID and the +/// `psa_key_attributes_t` structure required by Mbed Crypto. +/// +/// # Panics +/// +/// If either algorithm or key type conversion fails. See docs for +/// `convert_key_type` and `convert_algorithm` for more details. +pub fn convert_key_attributes(attrs: &KeyAttributes, key_id: psa_key_id_t) -> psa_key_attributes_t { + psa_key_attributes_t { + core: psa_core_key_attributes_t { + type_: convert_key_type(attrs.key_type), + lifetime: PSA_KEY_LIFETIME_PERSISTENT, + id: key_id, + policy: psa_key_policy_s { + usage: convert_key_usage(&attrs), + alg: convert_algorithm(&attrs.algorithm), + alg2: 0, + }, + bits: convert_key_bits(attrs.key_size), + flags: 0, + }, + domain_parameters: ::std::ptr::null_mut(), + domain_parameters_size: 0, + } } -/// Converts between native and Mbed Crypto key attributes values. -pub fn convert_key_attributes(attrs: &KeyAttributes) -> MbedKeyAttributes { - MbedKeyAttributes { - key_type: convert_key_type(attrs.key_type), - algorithm: convert_algorithm(&attrs.algorithm), - key_size: usize::try_from(attrs.key_size).expect("Key size cannot be represented as usize"), - key_usage: convert_key_usage(attrs), +/// Generates a blank `psa_key_attributes_t` object. +pub fn get_empty_key_attributes() -> psa_key_attributes_t { + psa_key_attributes_t { + core: psa_core_key_attributes_t { + type_: 0, + lifetime: 0, + id: 0, + policy: psa_key_policy_s { + usage: 0, + alg: 0, + alg2: 0, + }, + bits: 0, + flags: 0, + }, + domain_parameters: ::std::ptr::null_mut(), + domain_parameters_size: 0, } } +/// Convert down from a `u32` value to a `u16` (`psa_key_bits_t`), capping the +/// result at `PSA_KEY_BITS_TOO_LARGE`. +pub fn convert_key_bits(key_size: u32) -> psa_key_bits_t { + psa_key_bits_t::try_from(key_size).unwrap_or(PSA_KEY_BITS_TOO_LARGE) +} + /// Converts between native and Mbed Crypto type values. /// /// # Panics