Skip to content

Commit

Permalink
Merge pull request #40 from sbailey-arm/add-export-key
Browse files Browse the repository at this point in the history
Added export_key
  • Loading branch information
ionut-arm authored Jul 13, 2020
2 parents aed8881 + dcea030 commit 49d6f75
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 10 deletions.
6 changes: 3 additions & 3 deletions psa-crypto-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ pub use types::*;
#[cfg(feature = "implementation-defined")]
pub use psa_crypto_binding::{
psa_asymmetric_decrypt, psa_asymmetric_encrypt, psa_close_key, psa_crypto_init,
psa_destroy_key, psa_export_public_key, psa_generate_key, psa_get_key_attributes,
psa_import_key, psa_key_attributes_t, psa_open_key, psa_reset_key_attributes, psa_sign_hash,
psa_verify_hash,
psa_destroy_key, psa_export_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
Expand Down
1 change: 1 addition & 0 deletions psa-crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ zeroize = { version = "1.1.0", features = ["zeroize_derive"] }
[dev-dependencies]
rsa = "0.3.0"
rand = "0.7.3"
base64 = "0.12.3"

[features]
default = ["with-mbed-crypto", "no-std"]
Expand Down
54 changes: 53 additions & 1 deletion psa-crypto/src/operations/key_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,60 @@ pub fn export_public(key: Id, data: &mut [u8]) -> Result<usize> {
)
})
.to_result();
key.close_handle(handle)?;
let handle_close_res = key.close_handle(handle);
export_res?;
handle_close_res?;
Ok(data_length)
}

/// Export a key pair in binary format
///
/// The key is written in `data`. The functions returns the number of bytes written.
/// Please check the PSA Crypto API for a more complete description on the format of `data`.
///
/// # 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,
/// # export: true,
/// # ..Default::default()
/// # },
/// # permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign {
/// # hash_alg: Hash::Sha256.into(),
/// # }.into(),
/// # },
/// # };
/// psa_crypto::init().unwrap();
/// let buffer_size = attributes.export_key_output_size().unwrap();
/// let mut data = vec![0; buffer_size];
/// let my_key = key_management::generate(attributes, None).unwrap();
/// let size = key_management::export_key(my_key, &mut data).unwrap();
/// data.resize(size, 0);
/// ```
pub fn export_key(key: Id, data: &mut [u8]) -> Result<usize> {
initialized()?;
let handle = key.handle()?;
let mut data_length = 0;

let export_res = Status::from(unsafe {
psa_crypto_sys::psa_export_key(handle, data.as_mut_ptr(), data.len(), &mut data_length)
})
.to_result();
let handle_close_res = key.close_handle(handle);
export_res?;
handle_close_res?;
Ok(data_length)
}

Expand Down
71 changes: 65 additions & 6 deletions psa-crypto/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,62 @@ fn import_integration_test() {
}
}

#[test]
fn export_key_pair_test() {
const PRIVATE_KEY: &str = "MIICWwIBAAKBgQCd+EKeRmZCKLmg7LasWqpKA9/01linY75ujilf6v/Kb8UP9r/E\
cO75Pvi2YPnYhBadmVOVxMOqS2zmKm1a9VTegT8dN9Unf2s2KbKrKXupaQTXcrGG\
SB/BmHeWeiqidEMw7i9ysjHK4KEuacmYmZpvKAnNWMyvQgjGgGNpsNzqawIDAQAB\
AoGAcHlAxXyOdnCUqpWgAtuS/5v+q06qVJRaFFE3+ElT0oj+ID2pkG5wWBqT7xbh\
DV4O1CtFLg+o2OlXIhH3RpoC0D0x3qfvDpY5nJUUhP/w7mtGOwvB08xhXBN2M9fk\
PNqGdrzisvxTry3rp9qDduZlv1rTCsx8+ww3iI4Q0coD4fECQQD4KAMgIS7Vu+Vm\
zQmJfVfzYCVdr4X3Z/JOEexb3eu9p1Qj904sLu9Ds5NO7atT+qtDYVxgH5kQIrKk\
mFNAx3NdAkEAovZ+DaorhkDiL/gFVzwoShyc1A6AWkH791sDlns2ETZ1WwE/ccYu\
uJill/5XA9RKw6whUDzzNTsv7bFkCruAZwJARP5y6ALxz5DfFfbZuPU1d7/6g5Ki\
b4fh8VzAV0ZbHa6hESLYBCbEdRE/WolvwfiGl0RBd6QxXTAYdPS46ODLLQJARrz4\
urXDbuN7S5c9ukBCvOjuqp4g2Q0LcrPvOsMBFTeueXJxN9HvNfIM741X+DGOwqFV\
VJ8gc1rd0y/NXVtGwQJAc2w23nTmZ/olcMVRia1+AFsELcCnD+JqaJ2AEF1Ng6Ix\
V/X2l32v6t3B57sw/8ce3LCheEdqLHlSOpQiaD7Qfw==";

let attributes = Attributes {
key_type: Type::RsaKeyPair,
bits: 1024,
lifetime: Lifetime::Volatile,
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: AsymmetricSignature::RsaPkcs1v15Sign {
hash_alg: Hash::Sha256.into(),
}
.into(),
},
};
psa_crypto::init().unwrap();
let mut test_client = test_tools::TestClient::new();
let decoded_pk = base64::decode(PRIVATE_KEY).unwrap();

let id = test_client.import(attributes, 201, &decoded_pk);

let buffer_size = attributes.export_key_output_size().unwrap();
let mut data = vec![0; buffer_size];
let size = test_client.export_key_pair(id, &mut data).unwrap();
data.resize(size, 0);
assert_eq!(decoded_pk, data);
}

mod test_tools {
use psa_crypto::operations::key_management;
use psa_crypto::types::key::{Attributes, Id};
use psa_crypto::types::status::Result;

pub struct TestClient {
keys: Vec<Id>,
Expand All @@ -92,14 +145,20 @@ mod test_tools {
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 generate(&mut self, attributes: Attributes, key_id: u32) -> Id {
let id = key_management::generate(attributes, Some(key_id)).unwrap();
self.keys.push(id);
id
}

pub fn import(&mut self, attributes: Attributes, key_id: u32, key_data: &[u8]) -> Id {
let id = key_management::import(attributes, Some(key_id), key_data).unwrap();
self.keys.push(id);
id
}

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());
pub fn export_key_pair(&mut self, key_id: Id, key_data: &mut [u8]) -> Result<usize> {
key_management::export_key(key_id, key_data)
}
}

Expand Down

0 comments on commit 49d6f75

Please sign in to comment.