Skip to content

Commit

Permalink
refactor!: Pass crypto implementation around as an argument
Browse files Browse the repository at this point in the history
This commit is not formatted to increase its readability.
  • Loading branch information
chrysn committed Nov 4, 2023
1 parent 8d278a7 commit 84e9d24
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 135 deletions.
12 changes: 8 additions & 4 deletions crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn convert_array(input: &[u32]) -> [u8; SHA256_DIGEST_LEN] {
pub struct Crypto;

impl CryptoTrait for Crypto {
fn sha256_digest(message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen {
fn sha256_digest(&mut self, message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen {
let mut buffer: [u32; 64 / 4] = [0x00; 64 / 4];

unsafe {
Expand All @@ -39,6 +39,7 @@ impl CryptoTrait for Crypto {
}

fn hkdf_expand(
&mut self,
prk: &BytesHashLen,
info: &BytesMaxInfoBuffer,
info_len: usize,
Expand All @@ -63,7 +64,7 @@ impl CryptoTrait for Crypto {
buffer
}

fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen {
fn hkdf_extract(&mut self, salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen {
// Implementation of HKDF-Extract as per RFC 5869

// TODO generalize if salt is not provided
Expand All @@ -73,6 +74,7 @@ impl CryptoTrait for Crypto {
}

fn aes_ccm_encrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
Expand Down Expand Up @@ -110,6 +112,7 @@ impl CryptoTrait for Crypto {
}

fn aes_ccm_decrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
Expand Down Expand Up @@ -148,6 +151,7 @@ impl CryptoTrait for Crypto {
}

fn p256_ecdh(
&mut self,
private_key: &BytesP256ElemLen,
public_key: &BytesP256ElemLen,
) -> BytesP256ElemLen {
Expand Down Expand Up @@ -200,7 +204,7 @@ impl CryptoTrait for Crypto {
output
}

fn get_random_byte() -> u8 {
fn get_random_byte(&mut self) -> u8 {
let mut rnd_context = CRYS_RND_State_t::default();
let mut rnd_work_buffer = CRYS_RND_WorkBuff_t::default();
unsafe {
Expand All @@ -221,7 +225,7 @@ impl CryptoTrait for Crypto {
buffer[0]
}

fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
fn p256_generate_key_pair(&mut self) -> (BytesP256ElemLen, BytesP256ElemLen) {
let mut rnd_context = CRYS_RND_State_t::default();
let mut rnd_work_buffer = CRYS_RND_WorkBuff_t::default();
unsafe {
Expand Down
20 changes: 12 additions & 8 deletions crypto/edhoc-crypto-hacspec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ type BufferPlaintext3Hacspec = EdhocMessageBufferHacspec;
pub struct Crypto;

impl CryptoTrait for Crypto {
fn sha256_digest(message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen {
fn sha256_digest(&mut self, message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen {
let message: BytesMaxBufferHacspec = BytesMaxBufferHacspec::from_public_slice(message);

let output =
Expand All @@ -85,6 +85,7 @@ impl CryptoTrait for Crypto {
}

fn hkdf_expand(
&mut self,
prk: &BytesHashLen,
info: &BytesMaxInfoBuffer,
info_len: usize,
Expand All @@ -107,7 +108,7 @@ impl CryptoTrait for Crypto {
output.to_public_array()
}

fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen {
fn hkdf_extract(&mut self, salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen {
let output = BytesHashLenHacspec::from_seq(&extract(
&ByteSeq::from_slice(&BytesHashLenHacspec::from_public_slice(salt), 0, salt.len()),
&ByteSeq::from_slice(
Expand All @@ -120,6 +121,7 @@ impl CryptoTrait for Crypto {
}

fn aes_ccm_encrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
Expand All @@ -143,6 +145,7 @@ impl CryptoTrait for Crypto {
}

fn aes_ccm_decrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
Expand All @@ -168,6 +171,7 @@ impl CryptoTrait for Crypto {
}

fn p256_ecdh(
&mut self,
private_key: &BytesP256ElemLen,
public_key: &BytesP256ElemLen,
) -> BytesP256ElemLen {
Expand All @@ -189,12 +193,12 @@ impl CryptoTrait for Crypto {
}

#[cfg(not(feature = "hacspec-pure"))]
fn get_random_byte() -> u8 {
fn get_random_byte(&mut self) -> u8 {
rand::thread_rng().gen::<u8>()
}

#[cfg(not(feature = "hacspec-pure"))]
fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
fn p256_generate_key_pair(&mut self) -> (BytesP256ElemLen, BytesP256ElemLen) {
// generate a private key
let mut private_key = BytesP256ElemLenHacspec::new();
loop {
Expand All @@ -221,14 +225,14 @@ mod tests {

#[test]
fn test_p256_keys() {
let (x, g_x) = Crypto::p256_generate_key_pair();
let (x, g_x) = Crypto.p256_generate_key_pair();
assert_eq!(x.len(), 32);
assert_eq!(g_x.len(), 32);

let (y, g_y) = p256_generate_key_pair();
let (y, g_y) = Crypto.p256_generate_key_pair();

let g_xy = p256_ecdh(&x, &g_y);
let g_yx = p256_ecdh(&y, &g_x);
let g_xy = Crypto.p256_ecdh(&x, &g_y);
let g_yx = Crypto.p256_ecdh(&y, &g_x);

assert_eq!(g_xy, g_yx);
}
Expand Down
16 changes: 10 additions & 6 deletions crypto/edhoc-crypto-psa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub extern "C" fn mbedtls_hardware_poll(
pub struct Crypto;

impl CryptoTrait for Crypto {
fn sha256_digest(message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen {
fn sha256_digest(&mut self, message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen {
let hash_alg = Hash::Sha256;
let mut hash: [u8; SHA256_DIGEST_LEN] = [0; SHA256_DIGEST_LEN];
psa_crypto::init().unwrap();
Expand All @@ -37,6 +37,7 @@ impl CryptoTrait for Crypto {
// FIXME: Together with hkdf_extract, and the hmac_sha256 helper, this could be a provided
// function.
fn hkdf_expand(
&mut self,
prk: &BytesHashLen,
info: &BytesMaxInfoBuffer,
info_len: usize,
Expand Down Expand Up @@ -76,7 +77,7 @@ impl CryptoTrait for Crypto {
output
}

fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen {
fn hkdf_extract(&mut self, salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen {
// Implementation of HKDF-Extract as per RFC 5869

// TODO generalize if salt is not provided
Expand All @@ -86,6 +87,7 @@ impl CryptoTrait for Crypto {
}

fn aes_ccm_encrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
Expand Down Expand Up @@ -127,6 +129,7 @@ impl CryptoTrait for Crypto {
}

fn aes_ccm_decrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
Expand Down Expand Up @@ -170,6 +173,7 @@ impl CryptoTrait for Crypto {
}

fn p256_ecdh(
&mut self,
private_key: &BytesP256ElemLen,
public_key: &BytesP256ElemLen,
) -> BytesP256ElemLen {
Expand Down Expand Up @@ -202,14 +206,14 @@ impl CryptoTrait for Crypto {
output_buffer
}

fn get_random_byte() -> u8 {
fn get_random_byte(&mut self) -> u8 {
psa_crypto::init().unwrap();
let mut buffer = [0u8; 1];
generate_random(&mut buffer); // TODO: check return value
buffer[0]
}

fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
fn p256_generate_key_pair(&mut self) -> (BytesP256ElemLen, BytesP256ElemLen) {
let alg = RawKeyAgreement::Ecdh;
let mut usage_flags: UsageFlags = UsageFlags::default();
usage_flags.set_export();
Expand Down Expand Up @@ -264,7 +268,7 @@ fn hmac_sha256(message: &[u8], key: &[u8; SHA256_DIGEST_LEN]) -> BytesHashLen {
s2[64..64 + message.len()].copy_from_slice(message);

// (4) apply H to the stream generated in step (3)
let ih = Crypto::sha256_digest(&s2, 64 + message.len());
let ih = Crypto.sha256_digest(&s2, 64 + message.len());

// (5) XOR (bitwise exclusive-OR) the B byte string computed in
// step (1) with opad
Expand All @@ -278,7 +282,7 @@ fn hmac_sha256(message: &[u8], key: &[u8; SHA256_DIGEST_LEN]) -> BytesHashLen {

// (7) apply H to the stream generated in step (6) and output
// the result
let oh = Crypto::sha256_digest(&s5, 3 * SHA256_DIGEST_LEN);
let oh = Crypto.sha256_digest(&s5, 3 * SHA256_DIGEST_LEN);

oh
}
Expand Down
18 changes: 12 additions & 6 deletions crypto/edhoc-crypto-trait/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,34 @@
use edhoc_consts::*;

pub trait Crypto {
fn sha256_digest(message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen;
fn sha256_digest(&mut self, message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen;
fn hkdf_expand(
&mut self,
prk: &BytesHashLen,
info: &BytesMaxInfoBuffer,
info_len: usize,
length: usize,
) -> BytesMaxBuffer;
fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen;
fn hkdf_extract(&mut self, salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen;
fn aes_ccm_encrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
plaintext: &BufferPlaintext3,
) -> BufferCiphertext3;
fn aes_ccm_decrypt_tag_8(
&mut self,
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
ciphertext: &BufferCiphertext3,
) -> Result<BufferPlaintext3, EDHOCError>;
fn p256_ecdh(private_key: &BytesP256ElemLen, public_key: &BytesP256ElemLen)
-> BytesP256ElemLen;
fn get_random_byte() -> u8;
fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen);
fn p256_ecdh(
&mut self,
private_key: &BytesP256ElemLen,
public_key: &BytesP256ElemLen,
) -> BytesP256ElemLen;
fn get_random_byte(&mut self) -> u8;
fn p256_generate_key_pair(&mut self) -> (BytesP256ElemLen, BytesP256ElemLen);
}
15 changes: 15 additions & 0 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,31 @@ pub use edhoc_crypto_trait::Crypto as CryptoTrait;
#[cfg(feature = "hacspec")]
pub type Crypto = edhoc_crypto_hacspec::Crypto;

#[cfg(feature = "hacspec")]
pub const fn default_crypto() -> Crypto {
edhoc_crypto_hacspec::Crypto
}

// FIXME: Does not work with crypto-as-trait yet
#[cfg(feature = "cc2538")]
pub use edhoc_crypto_cc2538::*;

#[cfg(any(feature = "psa", feature = "psa-rust",))]
pub type Crypto = edhoc_crypto_psa::Crypto;

#[cfg(any(feature = "psa", feature = "psa-rust",))]
pub const fn default_crypto() -> Crypto {
edhoc_crypto_psa::Crypto
}

#[cfg(any(feature = "cryptocell310", feature = "cryptocell310-rust"))]
pub type Crypto = edhoc_crypto_cryptocell310::Crypto;

#[cfg(any(feature = "cryptocell310", feature = "cryptocell310-rust"))]
pub const fn default_crypto() -> Crypto {
edhoc_crypto_cryptocell310::Crypto
}

/// See test_implements_crypto
#[allow(dead_code)]
fn test_helper<T: CryptoTrait>() {}
Expand Down
10 changes: 5 additions & 5 deletions examples/edhoc-rs-no_std/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use panic_semihosting as _;
#[cfg(feature = "rtt")]
use rtt_target::{rprintln as println, rtt_init_print};

use edhoc_crypto::{Crypto, CryptoTrait};
use edhoc_crypto::{default_crypto, CryptoTrait};
use edhoc_rs::*;

extern crate alloc;
Expand Down Expand Up @@ -81,11 +81,11 @@ fn main() -> ! {
println!("Test test_new_initiator passed.");

fn test_p256_keys() {
let (x, g_x) = Crypto::p256_generate_key_pair();
let (y, g_y) = Crypto::p256_generate_key_pair();
let (x, g_x) = default_crypto().p256_generate_key_pair();
let (y, g_y) = default_crypto().p256_generate_key_pair();

let g_xy = Crypto::p256_ecdh(&x, &g_y);
let g_yx = Crypto::p256_ecdh(&y, &g_x);
let g_xy = default_crypto().p256_ecdh(&x, &g_y);
let g_yx = default_crypto().p256_ecdh(&y, &g_x);

assert_eq!(g_xy, g_yx);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/c_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::{slice, str};
use edhoc_consts::*;
use hexlit::hex;

use edhoc_crypto::{Crypto, CryptoTrait};
use edhoc_crypto::{default_crypto, CryptoTrait};

// Panic handler for cortex-m targets
#[cfg(any(feature = "crypto-cryptocell310", feature = "crypto-psa-baremetal"))]
Expand All @@ -12,7 +12,7 @@ use panic_semihosting as _;
// This function is mainly used to test the C wrapper
#[no_mangle]
pub extern "C" fn p256_generate_key_pair_from_c(out_private_key: *mut u8, out_public_key: *mut u8) {
let (private_key, public_key) = Crypto::p256_generate_key_pair();
let (private_key, public_key) = default_crypto().p256_generate_key_pair();

unsafe {
// copy the arrays to the pointers received from C
Expand Down
Loading

0 comments on commit 84e9d24

Please sign in to comment.