Skip to content

Commit

Permalink
refactor: using owned cred at credential fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
geonnave committed Jan 10, 2024
1 parent 0b7d5c2 commit 81f5dd0
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 38 deletions.
35 changes: 21 additions & 14 deletions lib/src/edhoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,27 +193,30 @@ pub fn r_parse_message_3(
pub fn r_verify_message_3(
state: &mut ProcessingM3,
crypto: &mut impl CryptoTrait,
valid_cred_i: &[u8],
valid_cred_i: CredentialRPK,
) -> Result<(Completed, BytesHashLen), EDHOCError> {
let (g_i, _kid_i) = parse_cred(valid_cred_i)?;

// compute salt_4e3m
let salt_4e3m = compute_salt_4e3m(crypto, &state.prk_3e2m, &state.th_3);
// TODO compute prk_4e3m
let prk_4e3m = compute_prk_4e3m(crypto, &salt_4e3m, &state.y, &g_i);
let prk_4e3m = compute_prk_4e3m(crypto, &salt_4e3m, &state.y, &valid_cred_i.public_key);

// compute mac_3
let expected_mac_3 = compute_mac_3(
crypto,
&prk_4e3m,
&state.th_3,
&get_id_cred(valid_cred_i)?,
valid_cred_i,
&valid_cred_i.get_id_cred(),
valid_cred_i.value.as_slice(),
);

// verify mac_3
if state.mac_3 == expected_mac_3 {
let th_4 = compute_th_4(crypto, &state.th_3, &state.plaintext_3, valid_cred_i);
let th_4 = compute_th_4(
crypto,
&state.th_3,
&state.plaintext_3,
valid_cred_i.value.as_slice(),
);

let mut th_4_buf: BytesMaxContextBuffer = [0x00; MAX_KDF_CONTEXT_LEN];
th_4_buf[..th_4.len()].copy_from_slice(&th_4[..]);
Expand Down Expand Up @@ -336,27 +339,31 @@ pub fn i_parse_message_2<'a>(
pub fn i_verify_message_2(
state: ProcessingM2,
crypto: &mut impl CryptoTrait,
valid_cred_r: &[u8], // TODO: have a struct to hold credentials to avoid re-computing
i: &BytesP256ElemLen, // I's static private DH key
valid_cred_r: CredentialRPK, // TODO: have a struct to hold credentials to avoid re-computing
i: &BytesP256ElemLen, // I's static private DH key
) -> Result<ProcessedM2, EDHOCError> {
// verify mac_2
let salt_3e2m = compute_salt_3e2m(crypto, &state.prk_2e, &state.th_2);

let (g_r, _) = parse_cred(valid_cred_r)?;
let prk_3e2m = compute_prk_3e2m(crypto, &salt_3e2m, &state.x, &g_r);
let prk_3e2m = compute_prk_3e2m(crypto, &salt_3e2m, &state.x, &valid_cred_r.public_key);

let expected_mac_2 = compute_mac_2(
crypto,
&prk_3e2m,
&get_id_cred(valid_cred_r)?,
valid_cred_r,
&valid_cred_r.get_id_cred(),
valid_cred_r.value.as_slice(),
&state.th_2,
);

if state.mac_2 == expected_mac_2 {
// step is actually from processing of message_3
// but we do it here to avoid storing plaintext_2 in State
let th_3 = compute_th_3(crypto, &state.th_2, &state.plaintext_2, valid_cred_r);
let th_3 = compute_th_3(
crypto,
&state.th_2,
&state.plaintext_2,
valid_cred_r.value.as_slice(),
);
// message 3 processing

let salt_4e3m = compute_salt_4e3m(crypto, &prk_3e2m, &th_3);
Expand Down
38 changes: 15 additions & 23 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<'a, Crypto: CryptoTrait> EdhocResponderWaitM3<Crypto> {
impl<'a, Crypto: CryptoTrait> EdhocResponderProcessingM3<Crypto> {
pub fn verify_message_3(
mut self,
cred_i: &[u8],
cred_i: CredentialRPK,
) -> Result<(EdhocResponderDone<Crypto>, [u8; SHA256_DIGEST_LEN]), EDHOCError> {
match r_verify_message_3(&mut self.state, &mut self.crypto, cred_i) {
Ok((state, prk_out)) => Ok((
Expand Down Expand Up @@ -315,7 +315,7 @@ impl<'a, Crypto: CryptoTrait> EdhocInitiatorProcessingM2<Crypto> {
mut self,
i: &'a [u8],
cred_i: CredentialRPK,
valid_cred_r: &[u8],
valid_cred_r: CredentialRPK,
) -> Result<EdhocInitiatorProcessedM2<Crypto>, EDHOCError> {
match i_verify_message_2(
self.state,
Expand Down Expand Up @@ -422,20 +422,18 @@ pub fn generate_connection_identifier<Crypto: CryptoTrait>(crypto: &mut Crypto)

// Implements auth credential checking according to draft-tiloca-lake-implem-cons
pub fn credential_check_or_fetch<'a>(
cred_expected: Option<EdhocMessageBuffer>,
cred_expected: Option<CredentialRPK>,
id_cred_received: IdCredOwned,
) -> Result<(EdhocMessageBuffer, BytesP256ElemLen), EDHOCError> {
) -> Result<CredentialRPK, EDHOCError> {
// Processing of auth credentials according to draft-tiloca-lake-implem-cons
// Comments tagged with a number refer to steps in Section 4.3.1. of draft-tiloca-lake-implem-cons
if let Some(cred_expected) = cred_expected {
// 1. Does ID_CRED_X point to a stored authentication credential? YES
// IMPL: compare cred_i_expected with id_cred
// IMPL: assume cred_i_expected is well formed
let (public_key_expected, kid_expected) = parse_cred(cred_expected.as_slice())?;
let public_key = public_key_expected;
let credentials_match = match id_cred_received {
IdCredOwned::CompactKid(kid_received) => kid_received == kid_expected,
IdCredOwned::FullCredential(cred_received) => cred_expected == cred_received,
IdCredOwned::CompactKid(kid_received) => kid_received == cred_expected.kid,
IdCredOwned::FullCredential(cred_received) => cred_received == cred_expected.value,
};

// 2. Is this authentication credential still valid?
Expand All @@ -445,7 +443,7 @@ pub fn credential_check_or_fetch<'a>(
// IMPL: ready to proceed, including process ead_2

if credentials_match {
Ok((cred_expected, public_key))
Ok(cred_expected)
} else {
Err(EDHOCError::UnknownPeer)
}
Expand All @@ -461,16 +459,15 @@ pub fn credential_check_or_fetch<'a>(
// 6. Validate CRED_X. Generally a CCS has to be validated only syntactically and semantically, unlike a certificate or a CWT.
// Is the validation successful?
// IMPL: parse_cred(cred_r) and check it is valid
match parse_cred(cred_received.as_slice()) {
Ok((public_key_received, _kid_received)) => {
match CredentialRPK::new(cred_received) {
Ok(cred_received) => {
// 5. Is the authentication credential authorized for use in the context of this EDHOC session?
// IMPL,TODO: we just skip this step for now

// 7. Store CRED_X as valid and trusted.
// Pair it with consistent credential identifiers, for each supported type of credential identifier.
// IMPL: cred_r = id_cred
let public_key = public_key_received;
Ok((cred_received, public_key))
Ok(cred_received)
}
Err(_) => Err(EDHOCError::UnknownPeer),
}
Expand Down Expand Up @@ -570,7 +567,7 @@ mod test {
let cred_r = CredentialRPK::new(CRED_R.try_into().unwrap()).unwrap();

let initiator = EdhocInitiator::new(default_crypto()); // can choose which identity to use after learning R's identity
let responder = EdhocResponder::new(default_crypto(), R, cred_r); // has to select an identity before learning who is I
let responder = EdhocResponder::new(default_crypto(), R, cred_r.clone()); // has to select an identity before learning who is I

// ---- begin initiator handling
// if needed: prepare ead_1
Expand All @@ -588,11 +585,8 @@ mod test {

// ---- being initiator handling
let (initiator, _c_r, id_cred_r, _ead_2) = initiator.parse_message_2(&message_2).unwrap();
let (valid_cred_r, _g_r) =
credential_check_or_fetch(Some(CRED_R.try_into().unwrap()), id_cred_r).unwrap();
let initiator = initiator
.verify_message_2(I, cred_i, valid_cred_r.as_slice())
.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();

// if needed: prepare ead_3
let (mut initiator, message_3, i_prk_out) = initiator
Expand All @@ -602,11 +596,9 @@ mod test {

// ---- begin responder handling
let (responder, id_cred_i, _ead_3) = responder.parse_message_3(&message_3).unwrap();
let (valid_cred_i, _g_i) =
credential_check_or_fetch(Some(CRED_I.try_into().unwrap()), id_cred_i).unwrap();
let valid_cred_i = credential_check_or_fetch(Some(cred_i), id_cred_i).unwrap();
// if ead_3: process ead_3
let (mut responder, r_prk_out) =
responder.verify_message_3(valid_cred_i.as_slice()).unwrap();
let (mut responder, r_prk_out) = responder.verify_message_3(valid_cred_i).unwrap();
// ---- end responder handling

// check that prk_out is equal at initiator and responder side
Expand Down
2 changes: 1 addition & 1 deletion shared/src/cred.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

#[derive(Debug)]
#[derive(Clone, Copy, Debug)]
pub struct CredentialRPK {
pub value: EdhocMessageBuffer,
pub public_key: BytesP256ElemLen, // could be a reference, but safe Rust doesn't allow self-referencing structs
Expand Down

0 comments on commit 81f5dd0

Please sign in to comment.