Skip to content

Commit

Permalink
Merge pull request #85 from geonnave/dynamic_connection_identifiers
Browse files Browse the repository at this point in the history
Generate dynamic connection identifiers
  • Loading branch information
malishav authored Aug 31, 2023
2 parents 81984f9 + 6e8d539 commit c40bd2d
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 39 deletions.
5 changes: 0 additions & 5 deletions consts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,6 @@ mod rust {
pub type BytesMaxLabelBuffeer = [u8; MAX_KDF_LABEL_LEN];
pub type BytesEncStructureLen = [u8; ENC_STRUCTURE_LEN];

pub const C_I: u8 = 0x37u8;
pub const C_R: u8 = 0x00u8;
pub const EDHOC_SUITES: BytesSuites = [0, 1, 2, 3, 4, 5, 6, 24, 25]; // all but private cipher suites
pub const EDHOC_SUPPORTED_SUITES: BytesSupportedSuites = [0x2u8];

Expand Down Expand Up @@ -330,9 +328,6 @@ mod hacspec {
array!(BytesMaxLabelBuffer, MAX_KDF_LABEL_LEN, U8);
array!(BytesEncStructureLen, ENC_STRUCTURE_LEN, U8);

pub const C_I: U8 = U8(0x37u8);
pub const C_R: U8 = U8(0x00u8);

// Currently only suite number 2 is supported,
// which corresponds to the array 10, -16, 8, 1, -7, 10, -16,
// which in turn corresponds to the following:
Expand Down
42 changes: 42 additions & 0 deletions crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,27 @@ mod hacspec {
BytesHashLen::from_public_slice(&convert_array(&buffer[..SHA256_DIGEST_LEN / 4]))
}

pub fn get_random_byte() -> U8 {
let mut rnd_context = CRYS_RND_State_t::default();
let mut rnd_work_buffer = CRYS_RND_WorkBuff_t::default();
unsafe {
SaSi_LibInit();
CRYS_RndInit(
&mut rnd_context as *mut _ as *mut c_void,
&mut rnd_work_buffer as *mut _,
);
}
let mut buffer = [0u8; 1];
unsafe {
CRYS_RND_GenerateVector(
&mut rnd_context as *mut _ as *mut c_void,
1,
buffer.as_mut_ptr(),
);
}
U8(buffer[0])
}

pub fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
let mut rnd_context = CRYS_RND_State_t::default();
let mut rnd_work_buffer = CRYS_RND_WorkBuff_t::default();
Expand Down Expand Up @@ -506,6 +527,27 @@ mod rust {
convert_array(&buffer[..SHA256_DIGEST_LEN / 4])
}

pub fn get_random_byte() -> u8 {
let mut rnd_context = CRYS_RND_State_t::default();
let mut rnd_work_buffer = CRYS_RND_WorkBuff_t::default();
unsafe {
SaSi_LibInit();
CRYS_RndInit(
&mut rnd_context as *mut _ as *mut c_void,
&mut rnd_work_buffer as *mut _,
);
}
let mut buffer = [0u8; 1];
unsafe {
CRYS_RND_GenerateVector(
&mut rnd_context as *mut _ as *mut c_void,
1,
buffer.as_mut_ptr(),
);
}
buffer[0]
}

pub fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
let mut rnd_context = CRYS_RND_State_t::default();
let mut rnd_work_buffer = CRYS_RND_WorkBuff_t::default();
Expand Down
6 changes: 6 additions & 0 deletions crypto/edhoc-crypto-hacspec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ pub fn p256_ecdh(
secret
}

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

#[cfg(not(feature = "hacspec-pure"))]
pub fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
// generate a private key
let mut private_key = BytesP256ElemLen::new();
Expand Down
16 changes: 15 additions & 1 deletion crypto/edhoc-crypto-psa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use edhoc_consts::*;
use psa_crypto::operations::hash::hash_compute;
use psa_crypto::operations::{aead, key_agreement, key_management};
use psa_crypto::operations::{aead, key_agreement, key_management, other::generate_random};
use psa_crypto::types::algorithm::Hash;
use psa_crypto::types::algorithm::{Aead, AeadWithDefaultLengthTag, KeyAgreement, RawKeyAgreement};
use psa_crypto::types::key::{Attributes, EccFamily, Lifetime, Policy, Type, UsageFlags};
Expand Down Expand Up @@ -264,6 +264,13 @@ mod hacspec {
oh
}

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

pub fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
let alg = RawKeyAgreement::Ecdh;
let mut usage_flags: UsageFlags = UsageFlags::default();
Expand Down Expand Up @@ -518,6 +525,13 @@ mod rust {
oh
}

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

pub fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
let alg = RawKeyAgreement::Ecdh;
let mut usage_flags: UsageFlags = UsageFlags::default();
Expand Down
12 changes: 0 additions & 12 deletions hacspec/adjust_features_for_hax.patch
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,6 @@ index e59a361..14f606e 100644
+[features]
+hacspec-pure = []
\ No newline at end of file
diff --git a/crypto/edhoc-crypto-hacspec/src/lib.rs b/crypto/edhoc-crypto-hacspec/src/lib.rs
index a9c7064..a9e2a7e 100644
--- a/crypto/edhoc-crypto-hacspec/src/lib.rs
+++ b/crypto/edhoc-crypto-hacspec/src/lib.rs
@@ -94,6 +94,7 @@ pub fn p256_ecdh(
secret
}

+#[cfg(not(feature = "hacspec-pure"))]
pub fn p256_generate_key_pair() -> (BytesP256ElemLen, BytesP256ElemLen) {
// generate a private key
let mut private_key = BytesP256ElemLen::new();
diff --git a/hacspec/Cargo.toml b/hacspec/Cargo.toml
index 94b80ae..51dbeb2 100644
--- a/hacspec/Cargo.toml
Expand Down
11 changes: 3 additions & 8 deletions hacspec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ pub fn r_prepare_message_2(
r: &BytesP256ElemLen, // R's static private DH key
y: BytesP256ElemLen, // R's ephemeral private DH key
g_y: BytesP256ElemLen, // R's ephemeral public DH key
c_r: U8,
) -> Result<(State, BufferMessage2, U8), EDHOCError> {
let State(
mut current_state,
Expand All @@ -211,12 +212,8 @@ pub fn r_prepare_message_2(

let mut error = EDHOCError::UnknownError;
let mut message_2 = BufferMessage2::new();
let mut c_r = U8(0xffu8); // invalid c_r

if current_state == EDHOCState::ProcessedMessage1 {
// FIXME generate a connection identifier to multiplex sessions
c_r = C_R;

// compute TH_2
let th_2 = compute_th_2(&g_y, &h_message_1);

Expand Down Expand Up @@ -424,11 +421,12 @@ pub fn i_prepare_message_1(
mut state: State,
x: BytesP256ElemLen,
g_x: BytesP256ElemLen,
c_i: U8,
) -> Result<(State, BufferMessage1), EDHOCError> {
let State(
mut current_state,
mut _x,
mut c_i,
mut _c_i,
_g_y,
_prk_3e2m,
_prk_4e3m,
Expand All @@ -447,9 +445,6 @@ pub fn i_prepare_message_1(
let suites_i =
BytesSuites::from_slice(&EDHOC_SUPPORTED_SUITES, 0, EDHOC_SUPPORTED_SUITES.len());

// Choose a connection identifier C_I and store it for the length of the protocol.
c_i = C_I;

let ead_1 = match i_prepare_ead_1() {
Some(ead_item) => Some(EADItemHacspec::from_public_item(&ead_item)),
None => None,
Expand Down
11 changes: 3 additions & 8 deletions lib/src/edhoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ pub fn r_prepare_message_2(
r: &BytesP256ElemLen, // R's static private DH key
y: BytesP256ElemLen,
g_y: BytesP256ElemLen,
c_r: U8,
) -> Result<(State, BufferMessage2, U8), EDHOCError> {
let State(
mut current_state,
Expand All @@ -194,12 +195,8 @@ pub fn r_prepare_message_2(

let mut error = EDHOCError::UnknownError;
let mut message_2: BufferMessage2 = BufferMessage2::new();
let mut c_r = 0xffu8; // invalid c_r

if current_state == EDHOCState::ProcessedMessage1 {
// FIXME generate a connection identifier to multiplex sessions
c_r = C_R;

// compute TH_2
let th_2 = compute_th_2(&g_y, &h_message_1);

Expand Down Expand Up @@ -384,11 +381,12 @@ pub fn i_prepare_message_1(
mut state: State,
x: BytesP256ElemLen,
g_x: BytesP256ElemLen,
c_i: U8,
) -> Result<(State, BufferMessage1), EDHOCError> {
let State(
mut current_state,
mut _x,
mut c_i,
mut _c_i,
_g_y,
_prk_3e2m,
_prk_4e3m,
Expand All @@ -407,9 +405,6 @@ 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[..]);

// Choose a connection identifier C_I and store it for the length of the protocol.
c_i = C_I;

let ead_1 = i_prepare_ead_1();

// Encode message_1 as a sequence of CBOR encoded data items as specified in Section 5.2.1
Expand Down
65 changes: 60 additions & 5 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
))]
pub use {
edhoc_consts::State as EdhocState, edhoc_consts::*, edhoc_crypto::*,
hacspec::HacspecEdhocInitiator as EdhocInitiator,
hacspec::generate_connection_identifier, hacspec::HacspecEdhocInitiator as EdhocInitiator,
hacspec::HacspecEdhocResponder as EdhocResponder,
};

Expand All @@ -19,7 +19,8 @@ pub use {
))]
pub use {
edhoc_consts::State as EdhocState, edhoc_consts::*, edhoc_crypto::*,
rust::RustEdhocInitiator as EdhocInitiator, rust::RustEdhocResponder as EdhocResponder,
rust::generate_connection_identifier, rust::RustEdhocInitiator as EdhocInitiator,
rust::RustEdhocResponder as EdhocResponder,
};

#[cfg(any(feature = "ead-none", feature = "ead-zeroconf"))]
Expand Down Expand Up @@ -141,8 +142,10 @@ mod hacspec {

// Generate ephemeral key pair
let (y, g_y) = edhoc_crypto::p256_generate_key_pair();
let c_r = generate_connection_identifier_cbor();

match r_prepare_message_2(self.state, &id_cred_r, &cred_r, cred_r_len, &r, y, g_y) {
match r_prepare_message_2(self.state, &id_cred_r, &cred_r, cred_r_len, &r, y, g_y, c_r)
{
Ok((state, message_2, c_r)) => {
self.state = state;
Ok((message_2.to_public_buffer(), c_r.declassify()))
Expand Down Expand Up @@ -254,8 +257,9 @@ mod hacspec {
) -> Result<EdhocMessageBuffer, EDHOCError> {
// Generate ephemeral key pair
let (x, g_x) = edhoc_crypto::p256_generate_key_pair();
let c_i = generate_connection_identifier_cbor();

match edhoc_hacspec::i_prepare_message_1(self.state, x, g_x) {
match edhoc_hacspec::i_prepare_message_1(self.state, x, g_x, c_i) {
Ok((state, message_1)) => {
self.state = state;
Ok(message_1.to_public_buffer())
Expand Down Expand Up @@ -360,6 +364,27 @@ mod hacspec {
}
}
}

pub fn generate_connection_identifier_cbor() -> U8 {
let c_i = generate_connection_identifier();
if c_i >= 0 && c_i <= 23 {
return U8(c_i as u8); // verbatim encoding of single byte integer
} else if c_i < 0 && c_i >= -24 {
// negative single byte integer encoding
return U8(CBOR_NEG_INT_1BYTE_START - 1 + (c_i.abs() as u8));
} else {
return U8(0);
}
}

/// 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 = edhoc_crypto::get_random_byte().declassify() as i8;
while conn_id < -24 || conn_id > 23 {
conn_id = edhoc_crypto::get_random_byte().declassify() as i8;
}
conn_id
}
}

#[cfg(any(
Expand Down Expand Up @@ -455,6 +480,7 @@ mod rust {
hex::decode_to_slice(self.cred_r, &mut cred_r[..self.cred_r.len() / 2])
.expect("Decoding failed");
let (y, g_y) = edhoc_crypto::p256_generate_key_pair();
let c_r = generate_connection_identifier_cbor();

match r_prepare_message_2(
self.state,
Expand All @@ -464,6 +490,7 @@ mod rust {
&<BytesP256ElemLen>::from_hex(self.r).expect("Decoding failed"),
y,
g_y,
c_r,
) {
Ok((state, message_2, c_r)) => {
self.state = state;
Expand Down Expand Up @@ -580,8 +607,9 @@ mod rust {
self: &mut RustEdhocInitiator<'a>,
) -> Result<BufferMessage1, EDHOCError> {
let (x, g_x) = edhoc_crypto::p256_generate_key_pair();
let c_i = generate_connection_identifier_cbor();

match i_prepare_message_1(self.state, x, g_x) {
match i_prepare_message_1(self.state, x, g_x, c_i) {
Ok((state, message_1)) => {
self.state = state;
Ok(message_1)
Expand Down Expand Up @@ -670,6 +698,27 @@ mod rust {
}
}
}

pub fn generate_connection_identifier_cbor() -> u8 {
let c_i = generate_connection_identifier();
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 {
// negative single byte integer encoding
return CBOR_NEG_INT_1BYTE_START - 1 + (c_i.abs() as u8);
} else {
return 0;
}
}

/// 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 = edhoc_crypto::get_random_byte() as i8;
while conn_id < -24 || conn_id > 23 {
conn_id = edhoc_crypto::get_random_byte() as i8;
}
conn_id
}
}

#[cfg(test)]
Expand Down Expand Up @@ -734,6 +783,12 @@ mod test {
assert!(error.is_ok());
}

#[test]
fn test_generate_connection_identifier() {
let conn_id = generate_connection_identifier();
assert!(conn_id >= -24 && conn_id <= 23);
}

#[test]
fn test_handshake() {
let state_initiator: EdhocState = Default::default();
Expand Down

0 comments on commit c40bd2d

Please sign in to comment.