Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make psa_crypto thread-safe with a global lock. #101

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions psa-crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ repository = "https://github.com/parallaxsecond/rust-psa-crypto"
[dependencies]
psa-crypto-sys = { path = "../psa-crypto-sys", version = "0.9.0", default-features = false }
log = "0.4.11"
parking_lot = "0.11.2"
serde = { version = "1.0.115", features = ["derive"] }
# Versions 1.4.x no longer compiles with Rust version 1.46.0
zeroize = { version = "<=1.3.0", features = ["zeroize_derive"] }
Expand Down
6 changes: 6 additions & 0 deletions psa-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static INITIALISED: AtomicBool = AtomicBool::new(false);
#[cfg(feature = "operations")]
pub fn init() -> Result<()> {
// It is not a problem to call psa_crypto_init more than once.
let _lock = LOCK.write();
Status::from(unsafe { psa_crypto_sys::psa_crypto_init() }).to_result()?;
let _ = INITIALISED.store(true, Ordering::Relaxed);

Expand All @@ -96,3 +97,8 @@ pub fn initialized() -> Result<()> {
Err(Error::BadState)
}
}

#[cfg(feature = "operations")]
use parking_lot::{const_rwlock, RwLock};
#[cfg(feature = "operations")]
static LOCK: RwLock<()> = const_rwlock(());
3 changes: 3 additions & 0 deletions psa-crypto/src/operations/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::initialized;
use crate::types::algorithm::Aead;
use crate::types::key::Id;
use crate::types::status::{Result, Status};
use crate::LOCK;

/// Process an authenticated encryption operation.
/// # Example
Expand Down Expand Up @@ -51,6 +52,7 @@ pub fn encrypt(
ciphertext: &mut [u8],
) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut ciphertext_size = 0;
Status::from(unsafe {
Expand Down Expand Up @@ -113,6 +115,7 @@ pub fn decrypt(
plaintext: &mut [u8],
) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut plaintext_size = 0;

Expand Down
3 changes: 3 additions & 0 deletions psa-crypto/src/operations/asym_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::initialized;
use crate::types::algorithm::AsymmetricEncryption;
use crate::types::key::Id;
use crate::types::status::{Result, Status};
use crate::LOCK;

/// Encrypt a short message with a key pair or public key
///
Expand Down Expand Up @@ -58,6 +59,7 @@ pub fn encrypt(
ciphertext: &mut [u8],
) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut output_length = 0;
let (salt_ptr, salt_len) = match salt {
Expand Down Expand Up @@ -139,6 +141,7 @@ pub fn decrypt(
plaintext: &mut [u8],
) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut output_length = 0;
let (salt_ptr, salt_len) = match salt {
Expand Down
3 changes: 3 additions & 0 deletions psa-crypto/src/operations/asym_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::initialized;
use crate::types::algorithm::AsymmetricSignature;
use crate::types::key::Id;
use crate::types::status::{Result, Status};
use crate::LOCK;

/// Sign an already-calculated hash with a private key
///
Expand Down Expand Up @@ -59,6 +60,7 @@ pub fn sign_hash(
signature: &mut [u8],
) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut signature_length = 0;

Expand Down Expand Up @@ -119,6 +121,7 @@ pub fn sign_hash(
/// ```
pub fn verify_hash(key: Id, alg: AsymmetricSignature, hash: &[u8], signature: &[u8]) -> Result<()> {
initialized()?;
let _lock = LOCK.read();

Status::from(unsafe {
psa_crypto_sys::psa_verify_hash(
Expand Down
3 changes: 3 additions & 0 deletions psa-crypto/src/operations/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use crate::initialized;
use crate::types::algorithm::Hash;
use crate::types::status::{Result, Status};
use crate::LOCK;

/// Calculate hash of a message
///
Expand All @@ -30,6 +31,7 @@ use crate::types::status::{Result, Status};
/// ```
pub fn hash_compute(hash_alg: Hash, input: &[u8], hash: &mut [u8]) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut output_length = 0;

Expand Down Expand Up @@ -64,6 +66,7 @@ pub fn hash_compute(hash_alg: Hash, input: &[u8], hash: &mut [u8]) -> Result<usi
/// ```
pub fn hash_compare(hash_alg: Hash, input: &[u8], hash_to_compare: &[u8]) -> Result<()> {
initialized()?;
let _lock = LOCK.read();

Status::from(unsafe {
psa_crypto_sys::psa_hash_compare(
Expand Down
3 changes: 3 additions & 0 deletions psa-crypto/src/operations/key_agreement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::initialized;
use crate::types::algorithm::RawKeyAgreement;
use crate::types::key::Id;
use crate::types::status::{Result, Status};
use crate::LOCK;

/// Perform a key agreement and return the raw shared secret.
/// # Example
Expand Down Expand Up @@ -49,6 +50,8 @@ pub fn raw_key_agreement(
output: &mut [u8],
) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut output_size = 0;
Status::from(unsafe {
psa_crypto_sys::psa_raw_key_agreement(
Expand Down
2 changes: 2 additions & 0 deletions psa-crypto/src/operations/key_derivation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::types::key::Attributes;
use crate::types::key::Id;
use crate::types::key_derivation::Operation;
use crate::types::status::{Error, Result, Status};
use crate::LOCK;
use core::convert::{TryFrom, TryInto};

/// This function calculates output bytes from a key derivation algorithm and uses those bytes to generate a key deterministically.
Expand Down Expand Up @@ -65,6 +66,7 @@ use core::convert::{TryFrom, TryInto};
/// ```
pub fn output_key(operation: Operation, attributes: Attributes, id: Option<u32>) -> Result<Id> {
initialized()?;
let _lock = LOCK.read();

let mut key_attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?;
if let Some(id) = id {
Expand Down
12 changes: 10 additions & 2 deletions psa-crypto/src/operations/key_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use crate::initialized;
use crate::types::key::{Attributes, Id};
use crate::types::status::{Result, Status};
use crate::LOCK;
use core::convert::TryFrom;
#[cfg(feature = "interface")]
use log::error;
Expand Down Expand Up @@ -45,6 +46,7 @@ use log::error;
/// ```
pub fn generate(attributes: Attributes, id: Option<u32>) -> Result<Id> {
initialized()?;
let _lock = LOCK.write();
let mut key_attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?;
if let Some(id) = id {
unsafe { psa_crypto_sys::psa_set_key_id(&mut key_attributes, id) };
Expand Down Expand Up @@ -97,6 +99,7 @@ pub fn generate(attributes: Attributes, id: Option<u32>) -> Result<Id> {
/// ```
pub unsafe fn destroy(key: Id) -> Result<()> {
initialized()?;
let _lock = LOCK.write();
Status::from(psa_crypto_sys::psa_destroy_key(key.0)).to_result()
}

Expand Down Expand Up @@ -144,6 +147,7 @@ pub unsafe fn destroy(key: Id) -> Result<()> {
/// ```
pub fn import(attributes: Attributes, id: Option<u32>, data: &[u8]) -> Result<Id> {
initialized()?;
let _lock = LOCK.write();

let mut key_attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?;
if let Some(id) = id {
Expand Down Expand Up @@ -194,8 +198,9 @@ pub fn import(attributes: Attributes, id: Option<u32>, data: &[u8]) -> Result<Id
/// ```
pub fn export_public(key: Id, data: &mut [u8]) -> Result<usize> {
initialized()?;
let mut data_length = 0;
let _lock = LOCK.read();

let mut data_length = 0;
Status::from(unsafe {
psa_crypto_sys::psa_export_public_key(
key.0,
Expand Down Expand Up @@ -241,8 +246,9 @@ pub fn export_public(key: Id, data: &mut [u8]) -> Result<usize> {
/// ```
pub fn export(key: Id, data: &mut [u8]) -> Result<usize> {
initialized()?;
let mut data_length = 0;
let _lock = LOCK.read();

let mut data_length = 0;
Status::from(unsafe {
psa_crypto_sys::psa_export_key(key.0, data.as_mut_ptr(), data.len(), &mut data_length)
})
Expand Down Expand Up @@ -281,6 +287,8 @@ pub fn export(key: Id, data: &mut [u8]) -> Result<usize> {
/// ```
pub fn copy(key_id_to_copy: Id, attributes: Attributes, id: Option<u32>) -> Result<Id> {
initialized()?;
let _lock = LOCK.write();

let mut key_attributes = psa_crypto_sys::psa_key_attributes_t::try_from(attributes)?;
if let Some(id) = id {
unsafe { psa_crypto_sys::psa_set_key_id(&mut key_attributes, id) };
Expand Down
6 changes: 4 additions & 2 deletions psa-crypto/src/operations/mac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::initialized;
use crate::types::key::Id;
use crate::types::algorithm::Mac;
use crate::types::status::{Result, Status, Error};

use crate::LOCK;

/// Calculate the message authentication code (MAC) of a message
/// The key must allow `sign_message`
Expand Down Expand Up @@ -49,6 +49,7 @@ use crate::types::status::{Result, Status, Error};
/// ```
pub fn compute_mac(key_id: Id, mac_alg: Mac, input_message: &[u8], mac: &mut [u8]) -> Result<usize> {
initialized()?;
let _lock = LOCK.read();

let mut output_length = 0;
let key_handle = key_id.handle()?;
Expand Down Expand Up @@ -111,6 +112,7 @@ pub fn compute_mac(key_id: Id, mac_alg: Mac, input_message: &[u8], mac: &mut [u8
/// ```
pub fn verify_mac(key_id: Id, mac_alg: Mac, input_message: &[u8], expected_mac: &[u8]) -> Result<()> {
initialized()?;
let _lock = LOCK.read();

let key_handle = key_id.handle()?;

Expand All @@ -127,4 +129,4 @@ pub fn verify_mac(key_id: Id, mac_alg: Mac, input_message: &[u8], expected_mac:
let close_handle_res = key_id.close_handle(key_handle);
mac_verify_res?;
close_handle_res
}
}
2 changes: 2 additions & 0 deletions psa-crypto/src/operations/other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use crate::initialized;
use crate::types::status::{Result, Status};
use crate::LOCK;

/// Generate a buffer of random bytes.
///
Expand All @@ -25,6 +26,7 @@ use crate::types::status::{Result, Status};
/// ```
pub fn generate_random(output: &mut [u8]) -> Result<()> {
initialized()?;
let _lock = LOCK.read();

Status::from(unsafe { psa_crypto_sys::psa_generate_random(output.as_mut_ptr(), output.len()) })
.to_result()?;
Expand Down
3 changes: 3 additions & 0 deletions psa-crypto/src/types/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use crate::types::algorithm::{Algorithm, Cipher, KeyAgreement, RawKeyAgreement};
#[cfg(feature = "operations")]
use crate::types::status::Status;
use crate::types::status::{Error, Result};
#[cfg(feature = "operations")]
use crate::LOCK;
#[cfg(feature = "interface")]
use core::convert::{TryFrom, TryInto};
use core::fmt;
Expand Down Expand Up @@ -350,6 +352,7 @@ impl Attributes {
#[cfg(feature = "operations")]
pub fn from_key_id(key_id: Id) -> Result<Self> {
initialized()?;
let _lock = LOCK.read();
let mut key_attributes = unsafe { psa_crypto_sys::psa_key_attributes_init() };
Status::from(unsafe {
psa_crypto_sys::psa_get_key_attributes(key_id.0, &mut key_attributes)
Expand Down