Skip to content

Commit

Permalink
Merge pull request openwsn-berkeley#284 from geonnave/crypto-method-a…
Browse files Browse the repository at this point in the history
…gility

Towards crypto & method agility: API updates, new buffer & credential struct
  • Loading branch information
geonnave authored Aug 2, 2024
2 parents ca4b84c + 3a4c7bc commit b82451d
Show file tree
Hide file tree
Showing 25 changed files with 1,115 additions and 496 deletions.
6 changes: 3 additions & 3 deletions ead/lakers-ead-authz/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl ZeroTouchServer {
vreq: &EdhocMessageBuffer,
) -> Result<EdhocMessageBuffer, EDHOCError> {
let (message_1, opaque_state) = parse_voucher_request(vreq)?;
let (_method, _suites_i, _suites_i_len, g_x, _c_i, ead_1) = parse_message_1(&message_1)?;
let (_method, _suites_i, g_x, _c_i, ead_1) = parse_message_1(&message_1)?;
let prk = compute_prk(crypto, &self.w, &g_x);

let (_loc_w, enc_id) = parse_ead_1_value(&ead_1.unwrap().value.unwrap())?;
Expand Down Expand Up @@ -72,7 +72,7 @@ impl ZeroTouchServerUserAcl {
vreq: &EdhocMessageBuffer,
) -> Result<EdhocMessageBuffer, EDHOCError> {
let (message_1, _opaque_state) = parse_voucher_request(vreq)?;
let (_method, _suites_i, _suites_i_len, g_x, _c_i, ead_1) = parse_message_1(&message_1)?;
let (_method, _suites_i, g_x, _c_i, ead_1) = parse_message_1(&message_1)?;
let prk = compute_prk(crypto, &self.w, &g_x);

let (_loc_w, enc_id) = parse_ead_1_value(&ead_1.unwrap().value.unwrap())?;
Expand All @@ -87,7 +87,7 @@ impl ZeroTouchServerUserAcl {
vreq: &EdhocMessageBuffer,
) -> Result<EdhocMessageBuffer, EDHOCError> {
let (message_1, opaque_state) = parse_voucher_request(vreq)?;
let (_method, _suites_i, _suites_i_len, g_x, _c_i, _ead_1) = parse_message_1(&message_1)?;
let (_method, _suites_i, g_x, _c_i, _ead_1) = parse_message_1(&message_1)?;
let prk = compute_prk(crypto, &self.w, &g_x);

// compute hash
Expand Down
15 changes: 10 additions & 5 deletions examples/coap/src/bin/coapclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ fn client_handshake() -> Result<(), EDHOCError> {
let timeout = Duration::new(5, 0);
println!("Client request: {}", url);

let cred_i = CredentialRPK::new(CRED_I.try_into().unwrap()).unwrap();
let cred_r = CredentialRPK::new(CRED_R.try_into().unwrap()).unwrap();
let cred_i: Credential = Credential::parse_ccs(CRED_I.try_into().unwrap()).unwrap();
let cred_r: Credential = Credential::parse_ccs(CRED_R.try_into().unwrap()).unwrap();

let initiator = EdhocInitiator::new(lakers_crypto::default_crypto());
let initiator = EdhocInitiator::new(
lakers_crypto::default_crypto(),
EDHOCMethod::StatStat,
EDHOCSuite::CipherSuite2,
);

// 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
Expand All @@ -50,9 +54,10 @@ fn client_handshake() -> Result<(), EDHOCError> {
println!("message_2 len = {}", response.message.payload.len());

let message_2 = EdhocMessageBuffer::new_from_slice(&response.message.payload[..]).unwrap();
let (initiator, c_r, id_cred_r, _ead_2) = initiator.parse_message_2(&message_2)?;
let (mut initiator, c_r, id_cred_r, _ead_2) = initiator.parse_message_2(&message_2)?;
let valid_cred_r = credential_check_or_fetch(Some(cred_r), id_cred_r).unwrap();
let initiator = initiator.verify_message_2(&I, cred_i, valid_cred_r)?;
initiator.set_identity(I.try_into().unwrap(), cred_i)?;
let initiator = initiator.verify_message_2(valid_cred_r)?;

let mut msg_3 = Vec::from(c_r.as_cbor());
let (mut initiator, message_3, prk_out) =
Expand Down
18 changes: 11 additions & 7 deletions examples/coap/src/bin/coapserver-coaphandler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ enum EdhocResponse {
// take up a slot there anyway) if we make it an enum.
OkSend2 {
c_r: ConnId,
responder: EdhocResponderProcessedM1<'static, Crypto>,
responder: EdhocResponderProcessedM1<Crypto>,
// FIXME: Is the ead_2 the most practical data to store here? An easy alternative is the
// voucher_response; ideal would be the voucher, bu that is only internal to prepare_ead_2.
//
Expand Down Expand Up @@ -107,16 +107,20 @@ impl coap_handler::Handler for EdhocHandler {

if starts_with_true {
let cred_r =
CredentialRPK::new(CRED_R.try_into().expect("Static credential is too large"))
Credential::parse_ccs(CRED_R.try_into().expect("Static credential is too large"))
.expect("Static credential is not processable");

let message_1 =
&EdhocMessageBuffer::new_from_slice(&request.payload()[1..]).map_err(too_small)?;

let (responder, _c_i, ead_1) =
EdhocResponder::new(lakers_crypto::default_crypto(), &R, cred_r)
.process_message_1(message_1)
.map_err(render_error)?;
let (responder, _c_i, ead_1) = EdhocResponder::new(
lakers_crypto::default_crypto(),
EDHOCMethod::StatStat,
R.try_into().expect("Wrong length of responder private key"),
cred_r,
)
.process_message_1(message_1)
.map_err(render_error)?;

let ead_2 = if let Some(ead_1) = ead_1 {
let authenticator = ZeroTouchAuthenticator::default();
Expand Down Expand Up @@ -174,7 +178,7 @@ impl coap_handler::Handler for EdhocHandler {
render_error(e)
})?;
let cred_i =
CredentialRPK::new(CRED_I.try_into().expect("Static credential is too large"))
Credential::parse_ccs(CRED_I.try_into().expect("Static credential is too large"))
.expect("Static credential is not processable");
let valid_cred_i =
credential_check_or_fetch(Some(cred_i), id_cred_i).map_err(render_error)?;
Expand Down
11 changes: 8 additions & 3 deletions examples/coap/src/bin/coapserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,13 @@ fn main() {
println!("Received message from {}", src);
// This is an EDHOC message
if request.message.payload[0] == 0xf5 {
let cred_r = CredentialRPK::new(CRED_R.try_into().unwrap()).unwrap();
let responder = EdhocResponder::new(lakers_crypto::default_crypto(), &R, cred_r);
let cred_r: Credential = Credential::parse_ccs(CRED_R.try_into().unwrap()).unwrap();
let responder = EdhocResponder::new(
lakers_crypto::default_crypto(),
EDHOCMethod::StatStat,
R.try_into().unwrap(),
cred_r,
);

let message_1: EdhocMessageBuffer = request.message.payload[1..]
.try_into()
Expand Down Expand Up @@ -101,7 +106,7 @@ fn main() {
// anyway legally
continue;
};
let cred_i = CredentialRPK::new(CRED_I.try_into().unwrap()).unwrap();
let cred_i = Credential::parse_ccs(CRED_I.try_into().unwrap()).unwrap();
let valid_cred_i = credential_check_or_fetch(Some(cred_i), id_cred_i).unwrap();
let Ok((mut responder, prk_out)) = responder.verify_message_3(valid_cred_i) else {
println!("EDHOC error at verify_message_3: {:?}", valid_cred_i);
Expand Down
15 changes: 8 additions & 7 deletions examples/lakers-c-native/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ int main(void)

// lakers init
puts("loading credentials.");
CredentialRPK cred_i = {0}, cred_r = {0};
credential_rpk_new(&cred_i, CRED_I, 107);
credential_rpk_new(&cred_r, CRED_R, 84);
CredentialC cred_i = {0}, cred_r = {0};
credential_new(&cred_i, CRED_I, 107);
credential_new(&cred_r, CRED_R, 84);
puts("creating edhoc initiator.");
EdhocInitiator initiator = {0};
initiator_new(&initiator);
Expand Down Expand Up @@ -153,7 +153,7 @@ int main(void)
memcpy(message_2.content, coap_response_payload, coap_response_payload_len);
EADItemC ead_2 = {0};
uint8_t c_r;
CredentialRPK id_cred_r = {0};
CredentialC id_cred_r = {0};
#ifdef LAKERS_EAD_AUTHZ
// res = initiator_parse_message_2(&initiator, &message_2, &cred_r, &c_r, &id_cred_r, &ead_2);
res = initiator_parse_message_2(&initiator, &message_2, &c_r, &id_cred_r, &ead_2);
Expand All @@ -166,22 +166,23 @@ int main(void)
return 1;
}
// FIXME: failing on native when cred_expected is NULL (memory allocation of 48 bytes failed)
res = credential_check_or_fetch(&cred_r, &id_cred_r);
CredentialC fetched_cred_r = {0};
res = credential_check_or_fetch(&cred_r, &id_cred_r, &fetched_cred_r);
if (res != 0) {
printf("Error handling credential: %d\n", res);
return 1;
}
#ifdef LAKERS_EAD_AUTHZ
puts("processing ead2");
res = authz_device_process_ead_2(&device, &ead_2, &id_cred_r);
res = authz_device_process_ead_2(&device, &ead_2, &fetched_cred_r);
if (res != 0) {
printf("Error process ead2 (authz): %d\n", res);
return 1;
} else {
puts("ead-authz voucher received and validated");
}
#endif
res = initiator_verify_message_2(&initiator, &I, &cred_i, &id_cred_r);
res = initiator_verify_message_2(&initiator, &I, &cred_i, &fetched_cred_r);
if (res != 0) {
printf("Error verify msg2: %d\n", res);
return 1;
Expand Down
42 changes: 33 additions & 9 deletions examples/lakers-no_std/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ fn main() -> ! {
const _C_R_TV: [u8; 1] = hex!("27");

fn test_new_initiator() {
let _initiator = EdhocInitiator::new(lakers_crypto::default_crypto());
let _initiator = EdhocInitiator::new(
lakers_crypto::default_crypto(),
EDHOCMethod::StatStat,
EDHOCSuite::CipherSuite2,
);
}

test_new_initiator();
Expand All @@ -81,7 +85,11 @@ fn main() -> ! {
println!("Test test_p256_keys passed.");

fn test_prepare_message_1() {
let mut initiator = EdhocInitiator::new(lakers_crypto::default_crypto());
let mut initiator = EdhocInitiator::new(
lakers_crypto::default_crypto(),
EDHOCMethod::StatStat,
EDHOCSuite::CipherSuite2,
);

let c_i =
generate_connection_identifier_cbor(&mut lakers_crypto::default_crypto()).as_slice();
Expand All @@ -93,11 +101,20 @@ fn main() -> ! {
println!("Test test_prepare_message_1 passed.");

fn test_handshake() {
let cred_i = CredentialRPK::new(CRED_I.try_into().unwrap()).unwrap();
let cred_r = CredentialRPK::new(CRED_R.try_into().unwrap()).unwrap();

let mut initiator = EdhocInitiator::new(lakers_crypto::default_crypto());
let responder = EdhocResponder::new(lakers_crypto::default_crypto(), R, cred_r.clone());
let cred_i = Credential::parse_ccs(CRED_I.try_into().unwrap()).unwrap();
let cred_r = Credential::parse_ccs(CRED_R.try_into().unwrap()).unwrap();

let initiator = EdhocInitiator::new(
lakers_crypto::default_crypto(),
EDHOCMethod::StatStat,
EDHOCSuite::CipherSuite2,
);
let responder = EdhocResponder::new(
lakers_crypto::default_crypto(),
EDHOCMethod::StatStat,
R.try_into().expect("Wrong length of responder private key"),
cred_r.clone(),
);

let (initiator, message_1) = initiator.prepare_message_1(None, &None).unwrap();

Expand All @@ -106,9 +123,16 @@ fn main() -> ! {
.prepare_message_2(CredentialTransfer::ByReference, None, &None)
.unwrap();

let (initiator, c_r, id_cred_r, ead_2) = initiator.parse_message_2(&message_2).unwrap();
let (mut initiator, _c_r, id_cred_r, _ead_2) =
initiator.parse_message_2(&message_2).unwrap();
let valid_cred_r = credential_check_or_fetch(Some(cred_r), id_cred_r).unwrap();
let initiator = initiator.verify_message_2(I, cred_i, valid_cred_r).unwrap();
initiator
.set_identity(
I.try_into().expect("Wrong length of initiator private key"),
cred_i.clone(),
)
.unwrap(); // exposing own identity only after validating cred_r
let initiator = initiator.verify_message_2(valid_cred_r).unwrap();

let (mut initiator, message_3, i_prk_out) = initiator
.prepare_message_3(CredentialTransfer::ByReference, &None)
Expand Down
5 changes: 5 additions & 0 deletions lakers-c/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ cpp_compat = true

[parse.expand]
all_features = true

[export]
include = [
"CredentialC"
]
5 changes: 3 additions & 2 deletions lakers-c/src/ead_authz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ pub unsafe extern "C" fn authz_device_process_ead_2(
// input parans
device_c: *mut EadAuthzDevice,
ead_2_c: *mut EADItemC,
cred_v: *mut CredentialRPK,
cred_v: *mut CredentialC,
) -> i8 {
let crypto = &mut default_crypto();
let device = &(*device_c);
let ead_2 = (*ead_2_c).to_rust();
let cred_v = (*cred_v).value.as_slice();
let cred_v = (*cred_v).to_rust();
let cred_v = cred_v.bytes.as_slice();
match device.wait_ead2.process_ead_2(crypto, ead_2, cred_v) {
Ok(device) => {
(*device_c).done = device;
Expand Down
25 changes: 12 additions & 13 deletions lakers-c/src/initiator.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use lakers::{
EdhocInitiator as EdhocInitiatorRust, // alias to conflict with the C-compatible struct
// EdhocInitiator as EdhocInitiatorRust, // alias to conflict with the C-compatible struct
*,
};
use lakers_crypto::{default_crypto, CryptoTrait};
Expand All @@ -15,23 +15,22 @@ pub struct EdhocInitiator {
pub wait_m2: WaitM2,
pub processing_m2: ProcessingM2C,
pub processed_m2: ProcessedM2,
pub cred_i: *mut CredentialRPK,
pub cred_i: *mut CredentialC,
pub completed: Completed,
}

#[no_mangle]
pub unsafe extern "C" fn initiator_new(initiator: *mut EdhocInitiator) -> i8 {
// we only support a single cipher suite which is already CBOR-encoded
let mut suites_i: BytesSuites = [0x0; SUITES_LEN];
let suites_i_len = EDHOC_SUPPORTED_SUITES.len();
suites_i[0..suites_i_len].copy_from_slice(&EDHOC_SUPPORTED_SUITES[..]);
let (x, g_x) = default_crypto().p256_generate_key_pair();
let mut crypto = default_crypto();
let suites_i =
prepare_suites_i(&crypto.supported_suites(), EDHOCSuite::CipherSuite2.into()).unwrap();
let (x, g_x) = crypto.p256_generate_key_pair();

let start = InitiatorStart {
x,
g_x,
suites_i,
suites_i_len,
method: EDHOCMethod::StatStat.into(),
};

core::ptr::write(&mut (*initiator).start, start);
Expand Down Expand Up @@ -87,7 +86,7 @@ pub unsafe extern "C" fn initiator_parse_message_2(
message_2: *const EdhocMessageBuffer,
// output params
c_r_out: *mut u8,
id_cred_r_out: *mut CredentialRPK,
id_cred_r_out: *mut IdCred,
ead_2_c_out: *mut EADItemC,
) -> i8 {
// this is a parsing function, so all output parameters are mandatory
Expand Down Expand Up @@ -130,8 +129,8 @@ pub unsafe extern "C" fn initiator_verify_message_2(
// input params
initiator_c: *mut EdhocInitiator,
i: *const BytesP256ElemLen,
mut cred_i: *mut CredentialRPK,
valid_cred_r: *mut CredentialRPK,
cred_i: *mut CredentialC,
valid_cred_r: *mut CredentialC,
) -> i8 {
if initiator_c.is_null() || i.is_null() {
return -1;
Expand All @@ -140,7 +139,7 @@ pub unsafe extern "C" fn initiator_verify_message_2(

let state = core::ptr::read(&(*initiator_c).processing_m2).to_rust();

match i_verify_message_2(&state, crypto, *valid_cred_r, &(*i)) {
match i_verify_message_2(&state, crypto, (*valid_cred_r).to_rust(), &(*i)) {
Ok(state) => {
(*initiator_c).processed_m2 = state;
(*initiator_c).cred_i = cred_i;
Expand Down Expand Up @@ -177,7 +176,7 @@ pub unsafe extern "C" fn initiator_prepare_message_3(
match i_prepare_message_3(
&state,
crypto,
*(*initiator_c).cred_i,
(*(*initiator_c).cred_i).to_rust(),
cred_transfer,
&ead_3,
) {
Expand Down
Loading

0 comments on commit b82451d

Please sign in to comment.