-
Notifications
You must be signed in to change notification settings - Fork 67
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
Move Parsec over to psa-crypto #186
Conversation
@@ -13,14 +11,16 @@ use parsec_interface::operations::{ | |||
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, | |||
}; | |||
use parsec_interface::requests::{ProviderID, ResponseStatus, Result}; | |||
use psa_crypto::operations::key_management as new_key_management; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure what to do about this rename. I thought leaving it as use psa_crypto::operations::key_management;
might get confusing as it is already in a file called key_management.rs
. Thoughts? Maybe psa_crypto_key_management
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
psa_crypto_key_management
That seems good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks promising! Lots of gone code 🧹
|
||
Ok(()) | ||
} | ||
fn main() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this file is empty we might as well delete it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the reason we still have that file is that the OUT_DIR
environment variable will only exist if that file exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
use super::psa_crypto_binding::*; | ||
pub use super::key::{psa_key_id_t, PSA_KEY_ID_USER_MAX, PSA_KEY_ID_USER_MIN}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this file can go away too!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's 🧹 it!
{ | ||
key_id = rand::random::<psa_key_id_t>(); | ||
key_id = rand::random::<key::psa_key_id_t>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also make use of Mbed Crypto and psa_generate_random
🤡 But I would ay it is better to use RNG as the entropy source should be better I believe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it matters, the handle value on its own doesn't really represent a crypto liability, we could even use a counter
&mut local_ids_handle, | ||
)?; | ||
let error = ResponseStatus::from(error); | ||
error!("Generate key status: {}", error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can/should probably use the new macro we have, format_error!
when attempting to log errors from dependency crates - this way the admin can control whether potentially sensitive data is logged or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks for the heads up. I stuck with error!
because that's what was there before but I'll switch it to format_error!
.
src/providers/mbed_provider/mod.rs
Outdated
if let Err(error) = psa_crypto::init() { | ||
error!("Error {} when initialising Mbed Crypto library.", error); | ||
return None; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of this init if the one on line 77 happens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why or how that got there! It definitely shouldn't be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the changes!! It looks really nice and clean using the psa-crypto
provider!!
I am thinking of a few things as next steps to simplify the provider further:
- I think it would be possible to remove the
local_ids
field and replace it with aAtomicU32
counter? - The
key_handle_mutex
might not be needed anymore if updating Mbed Crypto solved the thread-safety issues. If it is still needed (Parsec stress tests fail without it), it might be better suited in thepsa-crypto
crate. - I am not sure if the
key_slot_semaphore
is needed at all. It limits the number of open key slots at a time but if that is a constraint of Mbed Crypto we might just return the error
Cargo.toml
Outdated
@@ -40,6 +40,7 @@ derivative = "2.1.1" | |||
version = "3.0.0" | |||
hex = "0.4.2" | |||
picky = "5.0.0" | |||
psa-crypto = { path = "../rust-psa-crypto/psa-crypto", default-features = false, features = ["with-mbed-crypto"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be an optional
feature (like tss-esapi
for example), that is only activated if the mbed-crypto-provider
feature is selected.
|
||
Ok(()) | ||
} | ||
fn main() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the reason we still have that file is that the OUT_DIR
environment variable will only exist if that file exist.
@@ -28,17 +26,13 @@ use uuid::Uuid; | |||
trivial_casts | |||
)] | |||
#[allow(clippy::all)] | |||
mod psa_crypto_binding { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can also remove all the allow
above that were targeting this psa_crypto_binding
mod specifically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And even the one above, at line 21 😋 If we keep it, I am afraid it will apply on to the next mod
, which might hides somes lints for that module!
@@ -120,13 +119,12 @@ impl MbedProvider { | |||
// Safety: safe because: | |||
// * the Mbed Crypto library has been initialized | |||
// * this code is executed only by the main thread | |||
match unsafe { KeyHandle::open(key_id) } { | |||
let pc_key_id = key::Id::from_persistent_key_id(key_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove the // Safety
comments above as the call is now safe 💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same everywhere an unsafe
block is removed!
pub fn psa_asymmetric_sign_output_size(key_attrs: &key::Attributes) -> Result<usize> { | ||
match key_attrs.key_type { | ||
Type::RsaKeyPair => Ok(bits_to_bytes!(key_attrs.bits)), | ||
Type::EccKeyPair { .. } => Ok(bits_to_bytes!(key_attrs.bits) * 2), | ||
_ => Err(ResponseStatus::PsaErrorNotSupported), | ||
} | ||
} | ||
|
||
/// Compute the size of the public key material to be exported, given the attributes of the key. | ||
/// Implementing `PSA_KEY_EXPORT_MAX_SIZE` for public keys only, as defined in `crypto_sizes.h` (Mbed Crypto). | ||
pub fn psa_export_public_key_size(key_attrs: &psa_key_attributes_t) -> Result<usize> { | ||
pub fn psa_export_public_key_size(key_attrs: &key::Attributes) -> Result<usize> { | ||
macro_rules! export_asn1_int_max_size { | ||
($size:expr) => { | ||
($size) / 8 + 5 | ||
}; | ||
}; | ||
|
||
match key_attrs.core.type_ { | ||
PSA_KEY_TYPE_RSA_PUBLIC_KEY | PSA_KEY_TYPE_RSA_KEYPAIR => Ok(usize::from( | ||
export_asn1_int_max_size!(key_attrs.core.bits) + 11, | ||
)), | ||
match key_attrs.key_type { | ||
Type::RsaPublicKey | Type::RsaKeyPair => Ok(export_asn1_int_max_size!(key_attrs.bits) + 11), | ||
_ => Err(ResponseStatus::PsaErrorNotSupported), | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is fine like this at the moment for this PR but I think it would be really good to implement an abstraction in psa-crypto
for the macros: PSA_SIGN_OUTPUT_SIZE
and PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE
and use it instead of redifining them here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case after that, this file can be deleted!
|
||
use super::psa_crypto_binding::*; | ||
pub use super::key::{psa_key_id_t, PSA_KEY_ID_USER_MAX, PSA_KEY_ID_USER_MIN}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's 🧹 it!
let mut res = psa_sign_hash::Result { | ||
signature: Vec::new(), | ||
}; | ||
res.signature.resize(size, 0); | ||
res.signature.copy_from_slice(&signature[0..size]); | ||
Ok(res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can also just move signature
into the Result
structure:
signature.resize(size, 0);
Ok(psa_sign_hash::Result {
signature,
})
A bit more efficient as well as you don't need the copy!
@@ -13,14 +11,16 @@ use parsec_interface::operations::{ | |||
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_import_key, | |||
}; | |||
use parsec_interface::requests::{ProviderID, ResponseStatus, Result}; | |||
use psa_crypto::operations::key_management as new_key_management; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
psa_crypto_key_management
That seems good to me!
{ | ||
key_id = rand::random::<psa_key_id_t>(); | ||
key_id = rand::random::<key::psa_key_id_t>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also make use of Mbed Crypto and psa_generate_random
🤡 But I would ay it is better to use RNG as the entropy source should be better I believe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks good to me! A few things I think you forgot (maybe a few Safety
as well) but it is all ok. I will publish the 0.2.0
version of psa-crypto
so that the PR can pass.
key_id = rand::random::<psa_key_id_t>(); | ||
) -> Result<key::psa_key_id_t> { | ||
let mut rng = SmallRng::from_entropy(); | ||
let mut key_id = rng.gen_range(key::PSA_KEY_ID_USER_MIN, key::PSA_KEY_ID_USER_MAX); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gen_range
might be exclusive of its high
parameter whereas (to be confirmed) PSA_KEY_ID_USER_MAX
is inclusive. It might then need to be key::PSA_KEY_ID_USER_MAX + 1
for the second parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yes, my bad. I'd expect PSA_KEY_ID_USER_MAX
to be inclusive.
@@ -28,17 +26,13 @@ use uuid::Uuid; | |||
trivial_casts | |||
)] | |||
#[allow(clippy::all)] | |||
mod psa_crypto_binding { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And even the one above, at line 21 😋 If we keep it, I am afraid it will apply on to the next mod
, which might hides somes lints for that module!
I did find one more Safety comment that shouldn't be there but I've left the |
Oh, my bad then, if it is only on |
Versions |
We could do. How would we deal with holes when keys are destroyed? E.g. Allocate keys 1 to 100, then destroy 34, 67, 78 and 91.
This is the issue for that and its still open so I think we'll hit issues. I can try testing it without though, and if it causes a problem, look into moving it to
|
I would prefer to keep the changes of this PR as they are and tackle those different simplifications in future issues/PR.s, if you do not mind. I can open a new issue for those points and we can move the dicsussion there? |
Sound good! |
…test Signed-off-by: Samuel Bailey <[email protected]>
Parsec no longer calls mbedtls directly, it goes through the psa-crypto Rust interface to the library Signed-off-by: Samuel Bailey <[email protected]>
…o psa_crypto_binding Now Parsec calls psa-crypto when initialising and dropping an mbedcrypto provider. Also Parsec no longer has references for the bdinging to the mbedtls C lib. Signed-off-by: Samuel Bailey <[email protected]>
Parsec now uses psa-crypto instead of interfacing directly with the C library. Therefore, the build files are no longer needed in Parsec. Signed-off-by: Samuel Bailey <[email protected]>
Signed-off-by: Samuel Bailey <[email protected]>
Rename use statement in key_management Removed mbed_crypto constants and relocated contents Modified random number generation for key IDs Moved from error! to format_error! for dependency crate errors Removed redundant init psa-crypto crate optional Removed uneccessary safety comment Signed-off-by: Samuel Bailey <[email protected]>
Remove redundant comments Fix index MAX_ID for key ID gen Signed-off-by: Samuel Bailey <[email protected]>
Signed-off-by: Samuel Bailey <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the changes!
#177
Note: It currently won't build due to local dependencies. Once
psa-crypto
andparsec-interface
are updated on crates.io, we can update the dependencies in this PR to make it build. Currently this PR is for everyone to see and discuss the changes.