From da2be2eabce96c3ff9334c602338f605974df871 Mon Sep 17 00:00:00 2001 From: chrysn Date: Wed, 15 Nov 2023 19:32:59 +0100 Subject: [PATCH 1/4] fix: Demand that crypto objects are Debug These are added trivially (all just say "Crypto"), and this eases their use in other objects that otherwise need manual Debug implementations. --- crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs | 1 + crypto/edhoc-crypto-hacspec/src/lib.rs | 1 + crypto/edhoc-crypto-psa/src/lib.rs | 1 + crypto/edhoc-crypto-trait/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs b/crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs index 44de1abf..16fbd39b 100644 --- a/crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs +++ b/crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs @@ -20,6 +20,7 @@ fn convert_array(input: &[u32]) -> [u8; SHA256_DIGEST_LEN] { output } +#[derive(Debug)] pub struct Crypto; impl CryptoTrait for Crypto { diff --git a/crypto/edhoc-crypto-hacspec/src/lib.rs b/crypto/edhoc-crypto-hacspec/src/lib.rs index 46c4c487..dd67288e 100644 --- a/crypto/edhoc-crypto-hacspec/src/lib.rs +++ b/crypto/edhoc-crypto-hacspec/src/lib.rs @@ -72,6 +72,7 @@ type BufferPlaintext3Hacspec = EdhocMessageBufferHacspec; // Public functions +#[derive(Debug)] pub struct Crypto; impl CryptoTrait for Crypto { diff --git a/crypto/edhoc-crypto-psa/src/lib.rs b/crypto/edhoc-crypto-psa/src/lib.rs index 95e3f553..314962a6 100644 --- a/crypto/edhoc-crypto-psa/src/lib.rs +++ b/crypto/edhoc-crypto-psa/src/lib.rs @@ -22,6 +22,7 @@ pub extern "C" fn mbedtls_hardware_poll( 0i32 } +#[derive(Debug)] pub struct Crypto; impl CryptoTrait for Crypto { diff --git a/crypto/edhoc-crypto-trait/src/lib.rs b/crypto/edhoc-crypto-trait/src/lib.rs index 8e716954..e95f7359 100644 --- a/crypto/edhoc-crypto-trait/src/lib.rs +++ b/crypto/edhoc-crypto-trait/src/lib.rs @@ -3,7 +3,7 @@ use edhoc_consts::*; -pub trait Crypto { +pub trait Crypto: core::fmt::Debug { fn sha256_digest(&mut self, message: &BytesMaxBuffer, message_len: usize) -> BytesHashLen; fn hkdf_expand( &mut self, From 66976dafb3244c385d2687357b08bad53b2f3ac9 Mon Sep 17 00:00:00 2001 From: chrysn Date: Wed, 15 Nov 2023 19:39:53 +0100 Subject: [PATCH 2/4] refactor!: Pull Crypto trait to the high-level implementation This allows pushing back the edhoc-crypto ("the default implementation that is selected statically, making all implementations possible dependencies") into the dev-dependencies. The crypto-* features are removed from edhoc-rs; testing depends on edhoc-crypto being pulled in in parallel to the test, and a feature selected on that. Follow-up-for: https://github.com/openwsn-berkeley/edhoc-rs/pull/127 --- .github/workflows/build-and-test.yml | 6 +- examples/coap/Cargo.toml | 3 +- examples/coap/src/bin/coapclient.rs | 10 +- .../coap/src/bin/coapserver-coaphandler.rs | 16 +- examples/coap/src/bin/coapserver.rs | 11 +- examples/edhoc-rs-cc2538/Cargo.toml | 3 +- examples/edhoc-rs-no_std/Cargo.toml | 4 +- examples/edhoc-rs-no_std/src/main.rs | 45 ++++- lib/Cargo.toml | 8 +- lib/src/lib.rs | 183 +++++++++++------- 10 files changed, 190 insertions(+), 99 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 1fe37cad..402a4da1 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - crypto_backend: [crypto-hacspec, crypto-psa] + crypto_backend: [edhoc-crypto/hacspec, edhoc-crypto/psa] ead: [ead-none, ead-zeroconf] steps: @@ -36,7 +36,7 @@ jobs: uses: actions/checkout@v3 - name: Run unit tests # note that we only add `--package edhoc-hacspec` when testing the hacspec version of the lib - run: RUST_BACKTRACE=1 cargo test -p edhoc-rs -p edhoc-consts -p edhoc-ead-zeroconf --no-default-features --features="${{ matrix.crypto_backend }}, ${{ matrix.ead }}" --no-fail-fast -- --test-threads 1 + run: RUST_BACKTRACE=1 cargo test -p edhoc-rs -p edhoc-crypto -p edhoc-consts -p edhoc-ead-zeroconf --no-default-features --features="${{ matrix.crypto_backend }}, ${{ matrix.ead }}" --no-fail-fast -- --test-threads 1 build-edhoc-package: @@ -46,7 +46,7 @@ jobs: strategy: fail-fast: false matrix: - crypto_backend: [crypto-hacspec, crypto-psa, crypto-psa-baremetal, crypto-cryptocell310] + crypto_backend: [edhoc-crypto/hacspec, edhoc-crypto/psa, edhoc-crypto/psa-baremetal, edhoc-crypto/cryptocell310] ead: [ead-none, ead-zeroconf] steps: diff --git a/examples/coap/Cargo.toml b/examples/coap/Cargo.toml index a7542246..4213be41 100644 --- a/examples/coap/Cargo.toml +++ b/examples/coap/Cargo.toml @@ -4,7 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] -edhoc-rs = { path = "../../lib", features = [ "crypto-hacspec" ] } +edhoc-rs = { path = "../../lib" } +edhoc-crypto = { path = "../../crypto/", features = [ "hacspec" ] } hexlit = "0.5.3" coap = { version = "0.13" } coap-lite = { version = "0.11.3" } diff --git a/examples/coap/src/bin/coapclient.rs b/examples/coap/src/bin/coapclient.rs index f8fabf1c..f80f5c7d 100644 --- a/examples/coap/src/bin/coapclient.rs +++ b/examples/coap/src/bin/coapclient.rs @@ -21,11 +21,17 @@ fn main() { println!("Client request: {}", url); let state = Default::default(); - let initiator = EdhocInitiator::new(state, &I, &CRED_I, Some(&CRED_R)); + let initiator = EdhocInitiator::new( + state, + edhoc_crypto::default_crypto(), + &I, + &CRED_I, + Some(&CRED_R), + ); // Send Message 1 over CoAP and convert the response to byte let mut msg_1_buf = Vec::from([0xf5u8]); // EDHOC message_1 when transported over CoAP is prepended with CBOR true - let c_i = generate_connection_identifier_cbor(); + let c_i = generate_connection_identifier_cbor(&mut edhoc_crypto::default_crypto()); let (initiator, message_1) = initiator.prepare_message_1(c_i).unwrap(); msg_1_buf.extend_from_slice(&message_1.content[..message_1.len]); println!("message_1 len = {}", msg_1_buf.len()); diff --git a/examples/coap/src/bin/coapserver-coaphandler.rs b/examples/coap/src/bin/coapserver-coaphandler.rs index 80f199a3..b683566c 100644 --- a/examples/coap/src/bin/coapserver-coaphandler.rs +++ b/examples/coap/src/bin/coapserver-coaphandler.rs @@ -1,3 +1,4 @@ +use edhoc_crypto::Crypto; use edhoc_rs::*; use hexlit::hex; @@ -14,11 +15,11 @@ const R: &[u8] = &hex!("72cc4761dbd4c78f758931aa589d348d1ef874a7e303ede2f140dcf3 #[derive(Default, Debug)] struct EdhocHandler { - connections: Vec<(u8, EdhocResponderWaitM3<'static>)>, + connections: Vec<(u8, EdhocResponderWaitM3<'static, Crypto>)>, } impl EdhocHandler { - fn take_connection_by_c_r(&mut self, c_r: u8) -> Option> { + fn take_connection_by_c_r(&mut self, c_r: u8) -> Option> { let index = self .connections .iter() @@ -45,7 +46,7 @@ enum EdhocResponse { // take up a slot there anyway) if we make it an enum. OkSend2 { c_r: u8, - responder: EdhocResponderBuildM2<'static>, + responder: EdhocResponderBuildM2<'static, Crypto>, }, Message3Processed, } @@ -60,7 +61,14 @@ impl coap_handler::Handler for EdhocHandler { if starts_with_true { let state = EdhocState::default(); - let responder = EdhocResponder::new(state, &R, &CRED_R, Some(&CRED_I)); + + let responder = EdhocResponder::new( + state, + edhoc_crypto::default_crypto(), + &R, + &CRED_R, + Some(&CRED_I), + ); let response = responder .process_message_1(&request.payload()[1..].try_into().expect("wrong length")); diff --git a/examples/coap/src/bin/coapserver.rs b/examples/coap/src/bin/coapserver.rs index 378a3e4d..888f1a6e 100644 --- a/examples/coap/src/bin/coapserver.rs +++ b/examples/coap/src/bin/coapserver.rs @@ -32,7 +32,13 @@ fn main() { // This is an EDHOC message if request.message.payload[0] == 0xf5 { let state = EdhocState::default(); - let responder = EdhocResponder::new(state, &R, &CRED_R, Some(&CRED_I)); + let responder = EdhocResponder::new( + state, + edhoc_crypto::default_crypto(), + &R, + &CRED_R, + Some(&CRED_I), + ); let result = responder.process_message_1( &request.message.payload[1..] @@ -41,7 +47,8 @@ fn main() { ); if let Ok(responder) = result { - let c_r = generate_connection_identifier_cbor(); + let c_r = + generate_connection_identifier_cbor(&mut edhoc_crypto::default_crypto()); let (responder, message_2) = responder.prepare_message_2(c_r).unwrap(); response.message.payload = Vec::from(&message_2.content[..message_2.len]); // save edhoc connection diff --git a/examples/edhoc-rs-cc2538/Cargo.toml b/examples/edhoc-rs-cc2538/Cargo.toml index 7a967f41..932f397f 100644 --- a/examples/edhoc-rs-cc2538/Cargo.toml +++ b/examples/edhoc-rs-cc2538/Cargo.toml @@ -8,6 +8,7 @@ description = "edhoc-rs example on CC2538 SoC" [dependencies] edhoc-rs = { path = "../../lib", default-features = false } +edhoc-crypto = { path = "../../crypto", default-features = false } # depend on an allocator embedded-alloc = "0.5.0" hexlit = "0.5.3" @@ -20,5 +21,5 @@ rtt-target = { version = "0.3.1", features = ["cortex-m"] } [features] default = [ "psa" ] -psa = [ "edhoc-rs/crypto-psa-baremetal" ] +psa = [ "edhoc-crypto/psa-baremetal" ] diff --git a/examples/edhoc-rs-no_std/Cargo.toml b/examples/edhoc-rs-no_std/Cargo.toml index eae4f8a5..852cfe50 100644 --- a/examples/edhoc-rs-no_std/Cargo.toml +++ b/examples/edhoc-rs-no_std/Cargo.toml @@ -23,7 +23,7 @@ rtt-target = { version = "0.3.1", features = ["cortex-m"] } [features] default = [ "rtt", "crypto-cryptocell310", "ead-none" ] rtt = [ ] -crypto-psa = [ "edhoc-rs/crypto-psa-baremetal" ] -crypto-cryptocell310 = [ "edhoc-rs/crypto-cryptocell310" ] +crypto-psa = [ "edhoc-crypto/psa-baremetal" ] +crypto-cryptocell310 = [ "edhoc-crypto/cryptocell310" ] ead-none = [ "edhoc-rs/ead-none" ] ead-zeroconf = [ "edhoc-rs/ead-zeroconf" ] diff --git a/examples/edhoc-rs-no_std/src/main.rs b/examples/edhoc-rs-no_std/src/main.rs index f1994a4d..c8cf3817 100644 --- a/examples/edhoc-rs-no_std/src/main.rs +++ b/examples/edhoc-rs-no_std/src/main.rs @@ -74,7 +74,13 @@ fn main() -> ! { fn test_new_initiator() { let state = Default::default(); - let _initiator = EdhocInitiator::new(state, I, CRED_I, Some(CRED_R)); + let _initiator = EdhocInitiator::new( + state, + edhoc_crypto::default_crypto(), + I, + CRED_I, + Some(CRED_R), + ); } test_new_initiator(); @@ -94,9 +100,16 @@ fn main() -> ! { fn test_prepare_message_1() { let state = Default::default(); - let mut initiator = EdhocInitiator::new(state, I, CRED_I, Some(CRED_R)); - - let c_i: u8 = generate_connection_identifier_cbor().into(); + let mut initiator = EdhocInitiator::new( + state, + edhoc_crypto::default_crypto(), + I, + CRED_I, + Some(CRED_R), + ); + + let c_i: u8 = + generate_connection_identifier_cbor(&mut edhoc_crypto::default_crypto()).into(); let message_1 = initiator.prepare_message_1(c_i); assert!(message_1.is_ok()); } @@ -106,16 +119,30 @@ fn main() -> ! { fn test_handshake() { let state_initiator = Default::default(); - let mut initiator = EdhocInitiator::new(state_initiator, I, CRED_I, Some(CRED_R)); + let mut initiator = EdhocInitiator::new( + state_initiator, + edhoc_crypto::default_crypto(), + I, + CRED_I, + Some(CRED_R), + ); let state_responder = Default::default(); - let responder = EdhocResponder::new(state_responder, R, CRED_R, Some(CRED_I)); - - let c_i: u8 = generate_connection_identifier_cbor().into(); + let responder = EdhocResponder::new( + state_responder, + edhoc_crypto::default_crypto(), + R, + CRED_R, + Some(CRED_I), + ); + + let c_i: u8 = + generate_connection_identifier_cbor(&mut edhoc_crypto::default_crypto()).into(); let (initiator, message_1) = initiator.prepare_message_1(c_i).unwrap(); // to update the state let responder = responder.process_message_1(&message_1).unwrap(); - let c_r: u8 = generate_connection_identifier_cbor().into(); + let c_r: u8 = + generate_connection_identifier_cbor(&mut edhoc_crypto::default_crypto()).into(); let (responder, message_2) = responder.prepare_message_2(c_r).unwrap(); assert!(c_r != 0xff); diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 3514bbbc..5b0ca7f6 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,7 +11,6 @@ hexlit = "0.5.3" hex = { version = "0.4.3", default-features = false } hacspec-lib = { version = "0.1.0-beta.1", default-features = false, optional = true } -edhoc-crypto = { path = "../crypto", default-features = false } edhoc-crypto-trait = { path = "../crypto/edhoc-crypto-trait" } edhoc-consts = { path = "../consts" } edhoc-ead = { path = "../ead", default-features = false } @@ -20,12 +19,11 @@ panic-semihosting = { version = "0.6.0", features = ["exit"], optional = true } [build-dependencies] cbindgen = "0.24.5" +[dev-dependencies] +edhoc-crypto = { path = "../crypto", default-features = false } + [features] default = [ "edhoc-ead/ead-none" ] -crypto-hacspec = ["hacspec-lib/std", "edhoc-crypto/hacspec" ] -crypto-psa = [ "edhoc-crypto/psa" ] -crypto-psa-baremetal = [ "edhoc-crypto/psa-baremetal", "panic-semihosting" ] -crypto-cryptocell310 = [ "edhoc-crypto/cryptocell310", "panic-semihosting" ] ead-none = [ "edhoc-ead/ead-none" ] ead-zeroconf = [ "edhoc-ead/ead-zeroconf" ] diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 26c237e7..69ba037b 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -2,8 +2,7 @@ #![allow(warnings)] pub use { - edhoc_consts::State as EdhocState, edhoc_consts::*, edhoc_crypto::default_crypto, - edhoc_crypto_trait::Crypto as CryptoTrait, + edhoc_consts::State as EdhocState, edhoc_consts::*, edhoc_crypto_trait::Crypto as CryptoTrait, }; #[cfg(any(feature = "ead-none", feature = "ead-zeroconf"))] @@ -15,70 +14,79 @@ use edhoc::*; use edhoc_consts::*; #[derive(Debug)] -pub struct EdhocInitiator<'a> { +pub struct EdhocInitiator<'a, Crypto: CryptoTrait> { state: State, // opaque state i: &'a [u8], // private authentication key of I cred_i: &'a [u8], // I's full credential cred_r: Option<&'a [u8]>, // R's full credential (if provided) + crypto: Crypto, } #[derive(Debug)] -pub struct EdhocInitiatorWaitM2<'a> { +pub struct EdhocInitiatorWaitM2<'a, Crypto: CryptoTrait> { state: State, // opaque state i: &'a [u8], // private authentication key of I cred_i: &'a [u8], // I's full credential cred_r: Option<&'a [u8]>, // R's full credential (if provided) + crypto: Crypto, } #[derive(Debug)] -pub struct EdhocInitiatorBuildM3<'a> { +pub struct EdhocInitiatorBuildM3<'a, Crypto: CryptoTrait> { state: State, // opaque state i: &'a [u8], // private authentication key of I cred_i: &'a [u8], // I's full credential cred_r: Option<&'a [u8]>, // R's full credential (if provided) + crypto: Crypto, } #[derive(Debug)] -pub struct EdhocInitiatorDone { +pub struct EdhocInitiatorDone { state: State, + crypto: Crypto, } #[derive(Debug)] -pub struct EdhocResponder<'a> { +pub struct EdhocResponder<'a, Crypto: CryptoTrait> { state: State, // opaque state r: &'a [u8], // private authentication key of R cred_r: &'a [u8], // R's full credential cred_i: Option<&'a [u8]>, // I's full credential (if provided) + crypto: Crypto, } #[derive(Debug)] -pub struct EdhocResponderBuildM2<'a> { +pub struct EdhocResponderBuildM2<'a, Crypto: CryptoTrait> { state: State, // opaque state r: &'a [u8], // private authentication key of R cred_r: &'a [u8], // R's full credential cred_i: Option<&'a [u8]>, // I's full credential (if provided) + crypto: Crypto, } #[derive(Debug)] -pub struct EdhocResponderWaitM3<'a> { +pub struct EdhocResponderWaitM3<'a, Crypto: CryptoTrait> { state: State, // opaque state r: &'a [u8], // private authentication key of R cred_r: &'a [u8], // R's full credential cred_i: Option<&'a [u8]>, // I's full credential (if provided) + crypto: Crypto, } #[derive(Debug)] -pub struct EdhocResponderDone { +pub struct EdhocResponderDone { state: State, + crypto: Crypto, } -impl<'a> EdhocResponder<'a> { +impl<'a, Crypto: CryptoTrait> EdhocResponder<'a, Crypto> { pub fn new( state: State, + crypto: Crypto, r: &'a [u8], cred_r: &'a [u8], cred_i: Option<&'a [u8]>, - ) -> EdhocResponder<'a> { + ) -> Self { assert!(r.len() == P256_ELEM_LEN); EdhocResponder { @@ -86,34 +94,36 @@ impl<'a> EdhocResponder<'a> { r, cred_r, cred_i, + crypto, } } pub fn process_message_1( - self, + mut self, message_1: &BufferMessage1, - ) -> Result, EDHOCError> { - let state = r_process_message_1(self.state, &mut default_crypto(), message_1)?; + ) -> Result, EDHOCError> { + let state = r_process_message_1(self.state, &mut self.crypto, message_1)?; Ok(EdhocResponderBuildM2 { state, r: self.r, cred_r: self.cred_r, cred_i: self.cred_i, + crypto: self.crypto, }) } } -impl<'a> EdhocResponderBuildM2<'a> { +impl<'a, Crypto: CryptoTrait> EdhocResponderBuildM2<'a, Crypto> { pub fn prepare_message_2( - self, + mut self, c_r: u8, - ) -> Result<(EdhocResponderWaitM3<'a>, BufferMessage2), EDHOCError> { - let (y, g_y) = default_crypto().p256_generate_key_pair(); + ) -> Result<(EdhocResponderWaitM3<'a, Crypto>, BufferMessage2), EDHOCError> { + let (y, g_y) = self.crypto.p256_generate_key_pair(); match r_prepare_message_2( self.state, - &mut default_crypto(), + &mut self.crypto, &self.cred_r, self.r.try_into().expect("Wrong length of private key"), y, @@ -126,6 +136,7 @@ impl<'a> EdhocResponderBuildM2<'a> { r: self.r, cred_r: self.cred_r, cred_i: self.cred_i, + crypto: self.crypto, }, message_2, )), @@ -134,19 +145,25 @@ impl<'a> EdhocResponderBuildM2<'a> { } } -impl<'a> EdhocResponderWaitM3<'a> { +impl<'a, Crypto: CryptoTrait> EdhocResponderWaitM3<'a, Crypto> { pub fn process_message_3( - self, + mut self, message_3: &BufferMessage3, - ) -> Result<(EdhocResponderDone, [u8; SHA256_DIGEST_LEN]), EDHOCError> { - match r_process_message_3(self.state, &mut default_crypto(), message_3, self.cred_i) { - Ok((state, prk_out)) => Ok((EdhocResponderDone { state }, prk_out)), + ) -> Result<(EdhocResponderDone, [u8; SHA256_DIGEST_LEN]), EDHOCError> { + match r_process_message_3(self.state, &mut self.crypto, message_3, self.cred_i) { + Ok((state, prk_out)) => Ok(( + EdhocResponderDone { + state, + crypto: self.crypto, + }, + prk_out, + )), Err(error) => Err(error), } } } -impl EdhocResponderDone { +impl EdhocResponderDone { pub fn edhoc_exporter( &mut self, label: u8, @@ -158,7 +175,7 @@ impl EdhocResponderDone { edhoc_exporter( &self.state, - &mut default_crypto(), + &mut self.crypto, label, &context_buf, context.len(), @@ -172,20 +189,21 @@ impl EdhocResponderDone { edhoc_key_update( &mut self.state, - &mut default_crypto(), + &mut self.crypto, &context_buf, context.len(), ) } } -impl<'a> EdhocInitiator<'a> { +impl<'a, Crypto: CryptoTrait> EdhocInitiator<'a, Crypto> { pub fn new( state: State, + crypto: Crypto, i: &'a [u8], cred_i: &'a [u8], cred_r: Option<&'a [u8]>, - ) -> EdhocInitiator<'a> { + ) -> Self { assert!(i.len() == P256_ELEM_LEN); EdhocInitiator { @@ -193,22 +211,24 @@ impl<'a> EdhocInitiator<'a> { i, cred_i, cred_r, + crypto, } } pub fn prepare_message_1( - self: EdhocInitiator<'a>, + mut self, c_i: u8, - ) -> Result<(EdhocInitiatorWaitM2<'a>, BufferMessage1), EDHOCError> { - let (x, g_x) = default_crypto().p256_generate_key_pair(); + ) -> Result<(EdhocInitiatorWaitM2<'a, Crypto>, BufferMessage1), EDHOCError> { + let (x, g_x) = self.crypto.p256_generate_key_pair(); - match i_prepare_message_1(self.state, &mut default_crypto(), x, g_x, c_i) { + match i_prepare_message_1(self.state, &mut self.crypto, x, g_x, c_i) { Ok((state, message_1)) => Ok(( EdhocInitiatorWaitM2 { state, i: self.i, cred_i: self.cred_i, cred_r: self.cred_r, + crypto: self.crypto, }, message_1, )), @@ -217,14 +237,14 @@ impl<'a> EdhocInitiator<'a> { } } -impl<'a> EdhocInitiatorWaitM2<'a> { +impl<'a, Crypto: CryptoTrait> EdhocInitiatorWaitM2<'a, Crypto> { pub fn process_message_2( - self, + mut self, message_2: &BufferMessage2, - ) -> Result<(EdhocInitiatorBuildM3<'a>, u8), EDHOCError> { + ) -> Result<(EdhocInitiatorBuildM3<'a, Crypto>, u8), EDHOCError> { match i_process_message_2( self.state, - &mut default_crypto(), + &mut self.crypto, message_2, self.cred_r, self.i @@ -237,6 +257,7 @@ impl<'a> EdhocInitiatorWaitM2<'a> { i: self.i, cred_i: self.cred_i, cred_r: self.cred_r, + crypto: self.crypto, }, c_r, )), @@ -245,25 +266,37 @@ impl<'a> EdhocInitiatorWaitM2<'a> { } } -impl<'a> EdhocInitiatorBuildM3<'a> { +impl<'a, Crypto: CryptoTrait> EdhocInitiatorBuildM3<'a, Crypto> { pub fn prepare_message_3( - self, - ) -> Result<(EdhocInitiatorDone, BufferMessage3, [u8; SHA256_DIGEST_LEN]), EDHOCError> { + mut self, + ) -> Result< + ( + EdhocInitiatorDone, + BufferMessage3, + [u8; SHA256_DIGEST_LEN], + ), + EDHOCError, + > { match i_prepare_message_3( self.state, - &mut default_crypto(), + &mut self.crypto, &get_id_cred(self.cred_i), self.cred_i, ) { - Ok((state, message_3, prk_out)) => { - Ok((EdhocInitiatorDone { state }, message_3, prk_out)) - } + Ok((state, message_3, prk_out)) => Ok(( + EdhocInitiatorDone { + state, + crypto: self.crypto, + }, + message_3, + prk_out, + )), Err(error) => Err(error), } } } -impl EdhocInitiatorDone { +impl EdhocInitiatorDone { pub fn edhoc_exporter( &mut self, label: u8, @@ -275,7 +308,7 @@ impl EdhocInitiatorDone { edhoc_exporter( &self.state, - &mut default_crypto(), + &mut self.crypto, label, &context_buf, context.len(), @@ -289,15 +322,15 @@ impl EdhocInitiatorDone { edhoc_key_update( &mut self.state, - &mut default_crypto(), + &mut self.crypto, &context_buf, context.len(), ) } } -pub fn generate_connection_identifier_cbor() -> u8 { - let c_i = generate_connection_identifier(); +pub fn generate_connection_identifier_cbor(crypto: &mut Crypto) -> u8 { + let c_i = generate_connection_identifier(crypto); if c_i >= 0 && c_i <= 23 { return c_i as u8; // verbatim encoding of single byte integer } else if c_i < 0 && c_i >= -24 { @@ -309,10 +342,10 @@ pub fn generate_connection_identifier_cbor() -> u8 { } /// generates an identifier that can be serialized as a single CBOR integer, i.e. -24 <= x <= 23 -pub fn generate_connection_identifier() -> i8 { - let mut conn_id = default_crypto().get_random_byte() as i8; +pub fn generate_connection_identifier(crypto: &mut Crypto) -> i8 { + let mut conn_id = crypto.get_random_byte() as i8; while conn_id < -24 || conn_id > 23 { - conn_id = default_crypto().get_random_byte() as i8; + conn_id = crypto.get_random_byte() as i8; } conn_id } @@ -324,6 +357,8 @@ mod test { use hex::FromHex; use hexlit::hex; + use edhoc_crypto::default_crypto; + const ID_CRED_I: &[u8] = &hex!("a104412b"); const ID_CRED_R: &[u8] = &hex!("a104410a"); const CRED_I: &[u8] = &hex!("A2027734322D35302D33312D46462D45462D33372D33322D333908A101A5010202412B2001215820AC75E9ECE3E50BFC8ED60399889522405C47BF16DF96660A41298CB4307F7EB62258206E5DE611388A4B8A8211334AC7D37ECB52A387D257E6DB3C2A93DF21FF3AFFC8"); @@ -344,25 +379,25 @@ mod test { #[test] fn test_new_initiator() { let state = Default::default(); - let _initiator = EdhocInitiator::new(state, I, CRED_I, Some(CRED_R)); + let _initiator = EdhocInitiator::new(state, default_crypto(), I, CRED_I, Some(CRED_R)); let state = Default::default(); - let _initiator = EdhocInitiator::new(state, I, CRED_I, None); + let _initiator = EdhocInitiator::new(state, default_crypto(), I, CRED_I, None); } #[test] fn test_new_responder() { let state = Default::default(); - let _responder = EdhocResponder::new(state, R, CRED_R, Some(CRED_I)); + let _responder = EdhocResponder::new(state, default_crypto(), R, CRED_R, Some(CRED_I)); let state = Default::default(); - let _responder = EdhocResponder::new(state, R, CRED_R, None); + let _responder = EdhocResponder::new(state, default_crypto(), R, CRED_R, None); } #[test] fn test_prepare_message_1() { let state = Default::default(); - let mut initiator = EdhocInitiator::new(state, I, CRED_I, Some(CRED_R)); + let mut initiator = EdhocInitiator::new(state, default_crypto(), I, CRED_I, Some(CRED_R)); - let c_i = generate_connection_identifier_cbor(); + let c_i = generate_connection_identifier_cbor(&mut default_crypto()); let message_1 = initiator.prepare_message_1(c_i); assert!(message_1.is_ok()); } @@ -372,7 +407,7 @@ mod test { let message_1_tv_first_time = EdhocMessageBuffer::from_hex(MESSAGE_1_TV_FIRST_TIME); let message_1_tv = EdhocMessageBuffer::from_hex(MESSAGE_1_TV); let state = Default::default(); - let responder = EdhocResponder::new(state, R, CRED_R, Some(CRED_I)); + let responder = EdhocResponder::new(state, default_crypto(), R, CRED_R, Some(CRED_I)); // process message_1 first time, when unsupported suite is selected let error = responder.process_message_1(&message_1_tv_first_time); @@ -382,7 +417,7 @@ mod test { // We need to create a new responder -- no message is supposed to be processed twice by a // responder or initiator let state = Default::default(); - let responder = EdhocResponder::new(state, R, CRED_R, Some(CRED_I)); + let responder = EdhocResponder::new(state, default_crypto(), R, CRED_R, Some(CRED_I)); // process message_1 second time let error = responder.process_message_1(&message_1_tv); @@ -391,7 +426,7 @@ mod test { #[test] fn test_generate_connection_identifier() { - let conn_id = generate_connection_identifier(); + let conn_id = generate_connection_identifier(&mut default_crypto()); assert!(conn_id >= -24 && conn_id <= 23); } @@ -399,16 +434,18 @@ mod test { #[test] fn test_handshake() { let state_initiator = Default::default(); - let mut initiator = EdhocInitiator::new(state_initiator, I, CRED_I, Some(CRED_R)); + let mut initiator = + EdhocInitiator::new(state_initiator, default_crypto(), I, CRED_I, Some(CRED_R)); let state_responder = Default::default(); - let responder = EdhocResponder::new(state_responder, R, CRED_R, Some(CRED_I)); + let responder = + EdhocResponder::new(state_responder, default_crypto(), R, CRED_R, Some(CRED_I)); - let c_i: u8 = generate_connection_identifier_cbor(); + let c_i: u8 = generate_connection_identifier_cbor(&mut default_crypto()); let (initiator, result) = initiator.prepare_message_1(c_i).unwrap(); // to update the state let responder = responder.process_message_1(&result).unwrap(); - let c_r = generate_connection_identifier_cbor(); + let c_r = generate_connection_identifier_cbor(&mut default_crypto()); let (responder, message_2) = responder.prepare_message_2(c_r).unwrap(); assert!(c_r != 0xff); @@ -461,9 +498,15 @@ mod test { #[test] fn test_ead_zeroconf() { let state_initiator = Default::default(); - let mut initiator = EdhocInitiator::new(state_initiator, I, CRED_I, None); + let mut initiator = EdhocInitiator::new(state_initiator, default_crypto(), I, CRED_I, None); let state_responder = Default::default(); - let responder = EdhocResponder::new(state_responder, R, CRED_V_TV, Some(CRED_I)); + let responder = EdhocResponder::new( + state_responder, + default_crypto(), + R, + CRED_V_TV, + Some(CRED_I), + ); let u: BytesP256ElemLen = U_TV.try_into().unwrap(); let id_u: EdhocMessageBuffer = ID_U_TV.try_into().unwrap(); @@ -490,7 +533,7 @@ mod test { W_TV.try_into().unwrap(), )); - let c_i = generate_connection_identifier_cbor(); + let c_i = generate_connection_identifier_cbor(&mut default_crypto()); let (initiator, message_1) = initiator.prepare_message_1(c_i).unwrap(); assert_eq!( ead_initiator_state.protocol_state, @@ -503,7 +546,7 @@ mod test { EADResponderProtocolState::ProcessedEAD1 ); - let c_r = generate_connection_identifier_cbor(); + let c_r = generate_connection_identifier_cbor(&mut default_crypto()); let (responder, message_2) = responder.prepare_message_2(c_r).unwrap(); assert_eq!( ead_responder_state.protocol_state, From f30d2d8297bce84455f6754825f160f75bc4e4cb Mon Sep 17 00:00:00 2001 From: chrysn Date: Wed, 15 Nov 2023 21:51:59 +0100 Subject: [PATCH 3/4] fix: Remove needless hacspec dependency in main lib --- lib/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 5b0ca7f6..df874637 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -10,7 +10,6 @@ description = "EDHOC implementation in Rust" hexlit = "0.5.3" hex = { version = "0.4.3", default-features = false } -hacspec-lib = { version = "0.1.0-beta.1", default-features = false, optional = true } edhoc-crypto-trait = { path = "../crypto/edhoc-crypto-trait" } edhoc-consts = { path = "../consts" } edhoc-ead = { path = "../ead", default-features = false } From 31ff6a0f698a0387d5df487315bbb43a4ae879bc Mon Sep 17 00:00:00 2001 From: chrysn Date: Wed, 15 Nov 2023 22:27:57 +0100 Subject: [PATCH 4/4] refactor: Use crypto trait for EAD --- ead/edhoc-ead-none/Cargo.toml | 1 + ead/edhoc-ead-none/src/lib.rs | 14 ++- ead/edhoc-ead-zeroconf/Cargo.toml | 5 +- ead/edhoc-ead-zeroconf/src/lib.rs | 154 ++++++++++++++++++++++-------- lib/src/edhoc.rs | 6 +- 5 files changed, 134 insertions(+), 46 deletions(-) diff --git a/ead/edhoc-ead-none/Cargo.toml b/ead/edhoc-ead-none/Cargo.toml index 16aa8c42..098ba8c1 100644 --- a/ead/edhoc-ead-none/Cargo.toml +++ b/ead/edhoc-ead-none/Cargo.toml @@ -8,3 +8,4 @@ description = "EDHOC EAD none (just a placeholder)" [dependencies] edhoc-consts = { path = "../../consts" } +edhoc-crypto-trait = { path = "../../crypto/edhoc-crypto-trait" } diff --git a/ead/edhoc-ead-none/src/lib.rs b/ead/edhoc-ead-none/src/lib.rs index fa332d2d..a8276d68 100644 --- a/ead/edhoc-ead-none/src/lib.rs +++ b/ead/edhoc-ead-none/src/lib.rs @@ -1,16 +1,22 @@ #![no_std] use edhoc_consts::*; +use edhoc_crypto_trait::Crypto; // TODO: the function signatures should not be necessarily the same as the zeroconf version // find a way to be generic on this part. // initiator side -pub fn i_prepare_ead_1(_x: &BytesP256ElemLen, _ss: u8) -> Option { +pub fn i_prepare_ead_1( + _crypto: &mut impl Crypto, + _x: &BytesP256ElemLen, + _ss: u8, +) -> Option { None } pub fn i_process_ead_2( + _crypto: &mut impl Crypto, _ead_2: EADItem, _cred_v_u8: &[u8], _h_message_1: &BytesHashLen, @@ -23,7 +29,11 @@ pub fn i_prepare_ead_3() -> Option { } // responder side -pub fn r_process_ead_1(_ead_1: &EADItem, _message_1: &BufferMessage1) -> Result<(), ()> { +pub fn r_process_ead_1( + _crypto: &mut impl Crypto, + _ead_1: &EADItem, + _message_1: &BufferMessage1, +) -> Result<(), ()> { Ok(()) } diff --git a/ead/edhoc-ead-zeroconf/Cargo.toml b/ead/edhoc-ead-zeroconf/Cargo.toml index 5953e68a..e33c7681 100644 --- a/ead/edhoc-ead-zeroconf/Cargo.toml +++ b/ead/edhoc-ead-zeroconf/Cargo.toml @@ -8,10 +8,13 @@ description = "EDHOC EAD zeroconf (draf-lake-authz)" [dependencies] edhoc-consts = { path = "../../consts" } -edhoc-crypto = { path = "../../crypto", default-features = false } +edhoc-crypto-trait = { path = "../../crypto/edhoc-crypto-trait" } hacspec-lib = { version = "0.1.0-beta.1", default-features = false, optional = true } hexlit = "0.5.3" +[dev-dependencies] +edhoc-crypto = { path = "../../crypto", default-features = false } + [features] crypto-psa = [ "edhoc-crypto/psa" ] crypto-hacspec = ["hacspec-lib/std", "edhoc-crypto/hacspec" ] diff --git a/ead/edhoc-ead-zeroconf/src/lib.rs b/ead/edhoc-ead-zeroconf/src/lib.rs index 3d9d4b53..6c037a63 100644 --- a/ead/edhoc-ead-zeroconf/src/lib.rs +++ b/ead/edhoc-ead-zeroconf/src/lib.rs @@ -1,7 +1,7 @@ #![no_std] use edhoc_consts::*; -use edhoc_crypto::{default_crypto, CryptoTrait}; +use edhoc_crypto_trait::Crypto as CryptoTrait; // ---- initiator side (device) @@ -68,16 +68,20 @@ pub fn ead_initiator_set_global_state(new_state: EADInitiatorState) { } } -pub fn i_prepare_ead_1(x: &BytesP256ElemLen, ss: u8) -> Option { +pub fn i_prepare_ead_1( + crypto: &mut Crypto, + x: &BytesP256ElemLen, + ss: u8, +) -> Option { let state = ead_initiator_get_global_state(); if state.protocol_state != EADInitiatorProtocolState::Start { return None; } // PRK = EDHOC-Extract(salt, IKM) - let prk = compute_prk(x, &state.g_w); + let prk = compute_prk(crypto, x, &state.g_w); - let enc_id = build_enc_id(&prk, &state.id_u, ss); + let enc_id = build_enc_id(crypto, &prk, &state.id_u, ss); let value = Some(encode_ead_1_value(&state.loc_w, &enc_id)); let ead_1 = EADItem { @@ -95,7 +99,8 @@ pub fn i_prepare_ead_1(x: &BytesP256ElemLen, ss: u8) -> Option { Some(ead_1) } -pub fn i_process_ead_2( +pub fn i_process_ead_2( + crypto: &mut Crypto, ead_2: EADItem, cred_v_u8: &[u8], h_message_1: &BytesHashLen, @@ -113,7 +118,7 @@ pub fn i_process_ead_2( cred_v.len = cred_v_u8.len(); cred_v.content[..cred_v.len].copy_from_slice(cred_v_u8); - match verify_voucher(&ead_2_value, h_message_1, &cred_v, &state.prk) { + match verify_voucher(crypto, &ead_2_value, h_message_1, &cred_v, &state.prk) { Ok(voucher) => { ead_initiator_set_global_state(EADInitiatorState { protocol_state: EADInitiatorProtocolState::Completed, @@ -136,13 +141,14 @@ pub fn i_prepare_ead_3() -> Option { Some(EADItem::new()) } -fn verify_voucher( +fn verify_voucher( + crypto: &mut Crypto, received_voucher: &BytesEncodedVoucher, h_message_1: &BytesHashLen, cred_v: &EdhocMessageBuffer, prk: &BytesHashLen, ) -> Result { - let prepared_voucher = &prepare_voucher(h_message_1, cred_v, prk); + let prepared_voucher = &prepare_voucher(crypto, h_message_1, cred_v, prk); if received_voucher == prepared_voucher { let mut voucher_mac: BytesMac = Default::default(); voucher_mac[..MAC_LENGTH].copy_from_slice(&prepared_voucher[1..1 + MAC_LENGTH]); @@ -152,8 +158,13 @@ fn verify_voucher( } } -fn build_enc_id(prk: &BytesHashLen, id_u: &EdhocMessageBuffer, ss: u8) -> EdhocMessageBuffer { - let (k_1, iv_1) = compute_k_1_iv_1(&prk); +fn build_enc_id( + crypto: &mut Crypto, + prk: &BytesHashLen, + id_u: &EdhocMessageBuffer, + ss: u8, +) -> EdhocMessageBuffer { + let (k_1, iv_1) = compute_k_1_iv_1(crypto, &prk); // plaintext = (ID_U: bstr) let mut plaintext = EdhocMessageBuffer::new(); @@ -165,21 +176,29 @@ fn build_enc_id(prk: &BytesHashLen, id_u: &EdhocMessageBuffer, ss: u8) -> EdhocM let enc_structure = encode_enc_structure(ss); // ENC_ID = 'ciphertext' of COSE_Encrypt0 - default_crypto().aes_ccm_encrypt_tag_8(&k_1, &iv_1, &enc_structure[..], &plaintext) + crypto.aes_ccm_encrypt_tag_8(&k_1, &iv_1, &enc_structure[..], &plaintext) } -fn compute_prk(a: &BytesP256ElemLen, g_b: &BytesP256ElemLen) -> BytesHashLen { +fn compute_prk( + crypto: &mut Crypto, + a: &BytesP256ElemLen, + g_b: &BytesP256ElemLen, +) -> BytesHashLen { // NOTE: salt should be h'' (the zero-length byte string), but crypto backends are hardcoded to salts of size SHA256_DIGEST_LEN (32). // nevertheless, using a salt of HashLen zeros works as well (see RFC 5869, Section 2.2). let salt: BytesHashLen = [0u8; SHA256_DIGEST_LEN]; - let g_ab = default_crypto().p256_ecdh(a, g_b); - default_crypto().hkdf_extract(&salt, &g_ab) + let g_ab = crypto.p256_ecdh(a, g_b); + crypto.hkdf_extract(&salt, &g_ab) } -fn compute_k_1_iv_1(prk: &BytesHashLen) -> (BytesCcmKeyLen, BytesCcmIvLen) { +fn compute_k_1_iv_1( + crypto: &mut Crypto, + prk: &BytesHashLen, +) -> (BytesCcmKeyLen, BytesCcmIvLen) { // K_1 = EDHOC-Expand(PRK, info = (0, h'', AES_CCM_KEY_LEN), length) let mut k_1: BytesCcmKeyLen = [0x00; AES_CCM_KEY_LEN]; let k_1_buf = edhoc_kdf_expand( + crypto, prk, EAD_ZEROCONF_INFO_K_1_LABEL, &[0x00; MAX_KDF_CONTEXT_LEN], @@ -191,6 +210,7 @@ fn compute_k_1_iv_1(prk: &BytesHashLen) -> (BytesCcmKeyLen, BytesCcmIvLen) { // IV_1 = EDHOC-Expand(PRK, info = (1, h'', AES_CCM_IV_LEN), length) let mut iv_1: BytesCcmIvLen = [0x00; AES_CCM_IV_LEN]; let iv_1_buf = edhoc_kdf_expand( + crypto, prk, EAD_ZEROCONF_INFO_IV_1_LABEL, &[0x00; MAX_KDF_CONTEXT_LEN], @@ -228,7 +248,8 @@ fn encode_enc_structure(ss: u8) -> [u8; EAD_ZEROCONF_ENC_STRUCTURE_LEN] { } // TODO: consider moving this to a new 'edhoc crypto primnitives' module -fn edhoc_kdf_expand( +fn edhoc_kdf_expand( + crypto: &mut Crypto, prk: &BytesHashLen, label: u8, context: &BytesMaxContextBuffer, @@ -236,7 +257,7 @@ fn edhoc_kdf_expand( length: usize, ) -> BytesMaxBuffer { let (info, info_len) = encode_info(label, context, context_len, length); - let output = default_crypto().hkdf_expand(prk, &info, info_len, length); + let output = crypto.hkdf_expand(prk, &info, info_len, length); output } @@ -304,7 +325,11 @@ pub fn ead_responder_set_global_state(new_state: EADResponderState) { } } -pub fn r_process_ead_1(ead_1: &EADItem, message_1: &EdhocMessageBuffer) -> Result<(), ()> { +pub fn r_process_ead_1( + crypto: &mut Crypto, + ead_1: &EADItem, + message_1: &EdhocMessageBuffer, +) -> Result<(), ()> { let opaque_state: Option = None; // TODO: receive as parameter if ead_1.label != EAD_ZEROCONF_LABEL || ead_1.value.is_none() { @@ -318,7 +343,7 @@ pub fn r_process_ead_1(ead_1: &EADItem, message_1: &EdhocMessageBuffer) -> Resul // TODO: // - implement voucher_response = send_voucher_request(&loc_w, &voucher_request); // - save voucher_response in global state - let voucher_response = mock_send_voucher_request(&loc_w, &voucher_request, message_1); + let voucher_response = mock_send_voucher_request(crypto, &loc_w, &voucher_request, message_1); if let Ok(voucher_response) = voucher_response { ead_responder_set_global_state(EADResponderState { @@ -520,7 +545,8 @@ pub fn mock_ead_server_set_global_state(new_state: MockEADServerState) { } } -fn mock_send_voucher_request( +fn mock_send_voucher_request( + crypto: &mut Crypto, _loc_w: &EdhocMessageBuffer, voucher_request: &EdhocMessageBuffer, message_1: &EdhocMessageBuffer, // only needed to get g_x @@ -530,10 +556,17 @@ fn mock_send_voucher_request( let (_method, _suites_i, _suites_i_len, g_x, _c_i, _ead_1) = parse_message_1(message_1).unwrap(); - handle_voucher_request(voucher_request, &server_state.cred_v, &server_state.w, &g_x) + handle_voucher_request( + crypto, + voucher_request, + &server_state.cred_v, + &server_state.w, + &g_x, + ) } -fn handle_voucher_request( +fn handle_voucher_request( + crypto: &mut Crypto, vreq: &EdhocMessageBuffer, cred_v: &EdhocMessageBuffer, w: &BytesP256ElemLen, // TODO: have w be in the state of W @@ -544,22 +577,23 @@ fn handle_voucher_request( // compute hash let mut message_1_buf: BytesMaxBuffer = [0x00; MAX_BUFFER_LEN]; message_1_buf[..message_1.len].copy_from_slice(&message_1.content[..message_1.len]); - let h_message_1 = default_crypto().sha256_digest(&message_1_buf, message_1.len); + let h_message_1 = crypto.sha256_digest(&message_1_buf, message_1.len); - let prk = compute_prk(w, g_x); + let prk = compute_prk(crypto, w, g_x); - let voucher = prepare_voucher(&h_message_1, cred_v, &prk); + let voucher = prepare_voucher(crypto, &h_message_1, cred_v, &prk); let voucher_response = encode_voucher_response(&message_1, &voucher, &opaque_state); Ok(voucher_response) } -fn prepare_voucher( +fn prepare_voucher( + crypto: &mut Crypto, h_message_1: &BytesHashLen, cred_v: &EdhocMessageBuffer, prk: &BytesP256ElemLen, ) -> BytesEncodedVoucher { let voucher_input = encode_voucher_input(&h_message_1, &cred_v); - let voucher_mac = compute_voucher_mac(&prk, &voucher_input); + let voucher_mac = compute_voucher_mac(crypto, &prk, &voucher_input); encode_voucher(&voucher_mac) } @@ -622,13 +656,17 @@ fn encode_voucher_input( voucher_input } -fn compute_voucher_mac(prk: &BytesHashLen, voucher_input: &EdhocMessageBuffer) -> BytesMac { +fn compute_voucher_mac( + crypto: &mut Crypto, + prk: &BytesHashLen, + voucher_input: &EdhocMessageBuffer, +) -> BytesMac { let mut voucher_mac: BytesMac = [0x00; MAC_LENGTH]; let mut context = [0x00; MAX_KDF_CONTEXT_LEN]; context[..voucher_input.len].copy_from_slice(&voucher_input.content[..voucher_input.len]); - let voucher_mac_buf = edhoc_kdf_expand(prk, 2, &context, voucher_input.len, MAC_LENGTH); + let voucher_mac_buf = edhoc_kdf_expand(crypto, prk, 2, &context, voucher_input.len, MAC_LENGTH); voucher_mac[..MAC_LENGTH].copy_from_slice(&voucher_mac_buf[..MAC_LENGTH]); voucher_mac @@ -740,18 +778,28 @@ mod test_initiator { use super::*; use test_vectors::*; + use edhoc_crypto::default_crypto; + #[test] fn test_compute_keys() { let k_1_tv: BytesCcmKeyLen = K_1_TV.try_into().unwrap(); let iv_1_tv: BytesCcmIvLen = IV_1_TV.try_into().unwrap(); let prk_tv: BytesHashLen = PRK_TV.try_into().unwrap(); - let prk_xw = compute_prk(&X_TV.try_into().unwrap(), &G_W_TV.try_into().unwrap()); - let prk_wx = compute_prk(&W_TV.try_into().unwrap(), &G_X_TV.try_into().unwrap()); + let prk_xw = compute_prk( + &mut default_crypto(), + &X_TV.try_into().unwrap(), + &G_W_TV.try_into().unwrap(), + ); + let prk_wx = compute_prk( + &mut default_crypto(), + &W_TV.try_into().unwrap(), + &G_X_TV.try_into().unwrap(), + ); assert_eq!(prk_xw, prk_tv); assert_eq!(prk_xw, prk_wx); - let (k_1, iv_1) = compute_k_1_iv_1(&prk_xw); + let (k_1, iv_1) = compute_k_1_iv_1(&mut default_crypto(), &prk_xw); assert_eq!(k_1, k_1_tv); assert_eq!(iv_1, iv_1_tv); } @@ -761,6 +809,7 @@ mod test_initiator { let enc_id_tv: EdhocMessageBuffer = ENC_ID_TV.try_into().unwrap(); let enc_id = build_enc_id( + &mut default_crypto(), &PRK_TV.try_into().unwrap(), &ID_U_TV.try_into().unwrap(), SS_TV, @@ -778,7 +827,8 @@ mod test_initiator { LOC_W_TV.try_into().unwrap(), )); - let ead_1 = i_prepare_ead_1(&X_TV.try_into().unwrap(), SS_TV).unwrap(); + let ead_1 = + i_prepare_ead_1(&mut default_crypto(), &X_TV.try_into().unwrap(), SS_TV).unwrap(); assert_eq!( ead_initiator_get_global_state().protocol_state, EADInitiatorProtocolState::WaitEAD2 @@ -796,7 +846,13 @@ mod test_initiator { let prk_tv = PRK_TV.try_into().unwrap(); let voucher_mac_tv: BytesMac = VOUCHER_MAC_TV.try_into().unwrap(); - let res = verify_voucher(&voucher_tv, &h_message_1_tv, &cred_v_tv, &prk_tv); + let res = verify_voucher( + &mut default_crypto(), + &voucher_tv, + &h_message_1_tv, + &cred_v_tv, + &prk_tv, + ); assert!(res.is_ok()); assert_eq!(res.unwrap(), voucher_mac_tv); } @@ -821,7 +877,7 @@ mod test_initiator { state.prk = PRK_TV.try_into().unwrap(); ead_initiator_set_global_state(state); - let res = i_process_ead_2(ead_2_tv, cred_v_tv, &h_message_1_tv); + let res = i_process_ead_2(&mut default_crypto(), ead_2_tv, cred_v_tv, &h_message_1_tv); assert!(res.is_ok()); assert_eq!( ead_initiator_get_global_state().protocol_state, @@ -835,6 +891,8 @@ mod test_responder { use super::*; use test_vectors::*; + use edhoc_crypto::default_crypto; + #[test] fn test_parse_ead_1_value() { let ead_1_value_tv: EdhocMessageBuffer = EAD1_VALUE_TV.try_into().unwrap(); @@ -875,7 +933,7 @@ mod test_responder { W_TV.try_into().unwrap(), )); - let res = r_process_ead_1(&ead_1, &message_1_tv); + let res = r_process_ead_1(&mut default_crypto(), &ead_1, &message_1_tv); assert!(res.is_ok()); assert_eq!( ead_responder_get_global_state().protocol_state, @@ -923,6 +981,8 @@ mod test_enrollment_server { use super::*; use test_vectors::*; + use edhoc_crypto::default_crypto; + #[test] fn test_encode_voucher_input() { let h_message_1_tv: BytesHashLen = H_MESSAGE_1_TV.try_into().unwrap(); @@ -939,7 +999,7 @@ mod test_enrollment_server { let voucher_input_tv: EdhocMessageBuffer = VOUCHER_INPUT_TV.try_into().unwrap(); let voucher_mac_tv: BytesMac = VOUCHER_MAC_TV.try_into().unwrap(); - let voucher_mac = compute_voucher_mac(&prk_tv, &voucher_input_tv); + let voucher_mac = compute_voucher_mac(&mut default_crypto(), &prk_tv, &voucher_input_tv); assert_eq!(voucher_mac, voucher_mac_tv); } @@ -950,7 +1010,7 @@ mod test_enrollment_server { let prk: BytesHashLen = PRK_TV.try_into().unwrap(); let voucher_tv: BytesEncodedVoucher = VOUCHER_TV.try_into().unwrap(); - let voucher = prepare_voucher(&h_message_1, &cred_v, &prk); + let voucher = prepare_voucher(&mut default_crypto(), &h_message_1, &cred_v, &prk); assert_eq!(voucher, voucher_tv); } @@ -986,7 +1046,13 @@ mod test_enrollment_server { let g_x_tv: BytesP256ElemLen = G_X_TV.try_into().unwrap(); let voucher_response_tv: EdhocMessageBuffer = VOUCHER_RESPONSE_TV.try_into().unwrap(); - let res = handle_voucher_request(&voucher_request_tv, &cred_v_tv, &w_tv, &g_x_tv); + let res = handle_voucher_request( + &mut default_crypto(), + &voucher_request_tv, + &cred_v_tv, + &w_tv, + &g_x_tv, + ); assert!(res.is_ok()); let voucher_response = res.unwrap(); assert_eq!(voucher_response.content, voucher_response_tv.content); @@ -998,6 +1064,8 @@ mod test_stateless_operation { use super::*; use test_vectors::*; + use edhoc_crypto::default_crypto; + #[test] fn slo_test_encode_voucher_request() { let message_1_tv: EdhocMessageBuffer = MESSAGE_1_WITH_EAD_TV.try_into().unwrap(); @@ -1044,7 +1112,13 @@ mod test_stateless_operation { let g_x_tv: BytesP256ElemLen = G_X_TV.try_into().unwrap(); let voucher_response_tv: EdhocMessageBuffer = SLO_VOUCHER_RESPONSE_TV.try_into().unwrap(); - let res = handle_voucher_request(&voucher_request_tv, &cred_v_tv, &w_tv, &g_x_tv); + let res = handle_voucher_request( + &mut default_crypto(), + &voucher_request_tv, + &cred_v_tv, + &w_tv, + &g_x_tv, + ); assert!(res.is_ok()); let voucher_response = res.unwrap(); assert_eq!(voucher_response.content, voucher_response_tv.content); diff --git a/lib/src/edhoc.rs b/lib/src/edhoc.rs index 6bd5e96f..ace71e6d 100644 --- a/lib/src/edhoc.rs +++ b/lib/src/edhoc.rs @@ -105,7 +105,7 @@ pub fn r_process_message_1( if suites_i[suites_i_len - 1] == EDHOC_SUPPORTED_SUITES[0] { // Step 3: If EAD is present make it available to the application let ead_success = if let Some(ead_1) = ead_1 { - r_process_ead_1(&ead_1, message_1).is_ok() + r_process_ead_1(crypto, &ead_1, message_1).is_ok() } else { true }; @@ -382,7 +382,7 @@ pub fn i_prepare_message_1( let mut suites_i: BytesSuites = [0x0; SUITES_LEN]; suites_i[0..EDHOC_SUPPORTED_SUITES.len()].copy_from_slice(&EDHOC_SUPPORTED_SUITES[..]); - let ead_1 = i_prepare_ead_1(&x, suites_i[suites_i.len() - 1]); + let ead_1 = i_prepare_ead_1(crypto, &x, suites_i[suites_i.len() - 1]); // Encode message_1 as a sequence of CBOR encoded data items as specified in Section 5.2.1 message_1 = encode_message_1( @@ -473,7 +473,7 @@ pub fn i_process_message_2( // at this point, in case of EAD = zeroconf, if it works it means that: // - the Voucher has been verified // - the received valid_cred_r (aka cred_v) has been authenticated - i_process_ead_2(ead_2, valid_cred_r, &h_message_1) + i_process_ead_2(crypto, ead_2, valid_cred_r, &h_message_1) } else { Ok(()) };