Skip to content

Commit

Permalink
Merge pull request #110 from geonnave/core-ead-zeroconf
Browse files Browse the repository at this point in the history
Core functions for the lake-authz draft
  • Loading branch information
malishav authored Nov 3, 2023
2 parents ae225d4 + d07c5ee commit 8fc2763
Show file tree
Hide file tree
Showing 10 changed files with 1,701 additions and 116 deletions.
103 changes: 98 additions & 5 deletions consts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#![no_std]

pub use consts::*;
pub use helpers::*;
pub use structs::*;

mod consts {
use super::structs::*;

pub const MAX_MESSAGE_SIZE_LEN: usize = 64;
pub const MAX_EAD_SIZE_LEN: usize = 64;
// TODO: find a way to configure the buffer size
// need 128 to handle EAD fields, and 192 for the EAD_1 voucher
pub const MAX_MESSAGE_SIZE_LEN: usize = 128 + 64;
pub type EADMessageBuffer = EdhocMessageBuffer; // TODO: make it of size MAX_EAD_SIZE_LEN
pub const EAD_ZEROCONF_LABEL: u8 = 0x1; // NOTE: in lake-authz-draft-02 it is still TBD1

pub const ID_CRED_LEN: usize = 4;
pub const SUITES_LEN: usize = 9;
Expand All @@ -20,14 +21,17 @@ mod consts {
pub const AES_CCM_KEY_LEN: usize = 16;
pub const AES_CCM_IV_LEN: usize = 13;
pub const AES_CCM_TAG_LEN: usize = 8;
pub const MAC_LENGTH_2: usize = 8;
pub const MAC_LENGTH: usize = 8; // used for EAD Zeroconf
pub const MAC_LENGTH_2: usize = MAC_LENGTH;
pub const MAC_LENGTH_3: usize = MAC_LENGTH_2;
pub const ENCODED_VOUCHER_LEN: usize = 1 + MAC_LENGTH; // 1 byte for the length of the bstr-encoded voucher

// maximum supported length of connection identifier for R
pub const MAX_KDF_CONTEXT_LEN: usize = 150;
pub const MAX_KDF_LABEL_LEN: usize = 15; // for "KEYSTREAM_2"
pub const MAX_BUFFER_LEN: usize = 220;
pub const CBOR_BYTE_STRING: u8 = 0x58u8;
pub const CBOR_TEXT_STRING: u8 = 0x78u8;
pub const CBOR_UINT_1BYTE: u8 = 0x18u8;
pub const CBOR_NEG_INT_1BYTE_START: u8 = 0x20u8;
pub const CBOR_NEG_INT_1BYTE_END: u8 = 0x37u8;
Expand All @@ -47,6 +51,12 @@ mod consts {

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];

pub const MAX_EAD_SIZE_LEN: usize = 64;
pub const EAD_ZEROCONF_LABEL: u8 = 0x1; // NOTE: in lake-authz-draft-02 it is still TBD1
pub const EAD_ZEROCONF_INFO_K_1_LABEL: u8 = 0x0;
pub const EAD_ZEROCONF_INFO_IV_1_LABEL: u8 = 0x1;
pub const EAD_ZEROCONF_ENC_STRUCTURE_LEN: usize = 2 + 8 + 3;
}

mod structs {
Expand Down Expand Up @@ -76,6 +86,9 @@ mod structs {
pub type BytesMaxLabelBuffeer = [u8; MAX_KDF_LABEL_LEN];
pub type BytesEncStructureLen = [u8; ENC_STRUCTURE_LEN];

pub type BytesMac = [u8; MAC_LENGTH];
pub type BytesEncodedVoucher = [u8; ENCODED_VOUCHER_LEN];

#[repr(C)]
#[derive(Default, PartialEq, Copy, Clone, Debug)]
pub enum EDHOCState {
Expand Down Expand Up @@ -118,7 +131,7 @@ mod structs {
);

#[repr(C)]
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct EdhocMessageBuffer {
pub content: [u8; MAX_MESSAGE_SIZE_LEN],
pub len: usize,
Expand Down Expand Up @@ -189,3 +202,83 @@ mod structs {
}
}
}

mod helpers {
use super::consts::*;
use super::structs::*;

/// Check for: an unsigned integer encoded as a single byte
#[inline(always)]
pub fn is_cbor_uint_1byte(byte: u8) -> bool {
return byte >= CBOR_UINT_1BYTE_START && byte <= CBOR_UINT_1BYTE_END;
}

/// Check for: an unsigned integer encoded as two bytes
#[inline(always)]
pub fn is_cbor_uint_2bytes(byte: u8) -> bool {
return byte == CBOR_UINT_1BYTE;
}

/// Check for: a negative integer encoded as a single byte
#[inline(always)]
pub fn is_cbor_neg_int_1byte(byte: u8) -> bool {
return byte >= CBOR_NEG_INT_1BYTE_START && byte <= CBOR_NEG_INT_1BYTE_END;
}

/// Check for: a bstr denoted by a single byte which encodes both type and content length
#[inline(always)]
pub fn is_cbor_bstr_1byte_prefix(byte: u8) -> bool {
return byte >= CBOR_MAJOR_BYTE_STRING && byte <= CBOR_MAJOR_BYTE_STRING_MAX;
}

/// Check for: a bstr denoted by two bytes, one for type the other for content length
#[inline(always)]
pub fn is_cbor_bstr_2bytes_prefix(byte: u8) -> bool {
return byte == CBOR_BYTE_STRING;
}

/// Check for: a tstr denoted by two bytes, one for type the other for content length
#[inline(always)]
pub fn is_cbor_tstr_2bytes_prefix(byte: u8) -> bool {
return byte == CBOR_TEXT_STRING;
}

/// Check for: an array denoted by a single byte which encodes both type and content length
#[inline(always)]
pub fn is_cbor_array_1byte_prefix(byte: u8) -> bool {
return byte >= CBOR_MAJOR_ARRAY && byte <= CBOR_MAJOR_ARRAY_MAX;
}

pub fn encode_info(
label: u8,
context: &BytesMaxContextBuffer,
context_len: usize,
length: usize,
) -> (BytesMaxInfoBuffer, usize) {
let mut info: BytesMaxInfoBuffer = [0x00; MAX_INFO_LEN];

// construct info with inline cbor encoding
info[0] = label;
let mut info_len = if context_len < 24 {
info[1] = context_len as u8 | CBOR_MAJOR_BYTE_STRING;
info[2..2 + context_len].copy_from_slice(&context[..context_len]);
2 + context_len
} else {
info[1] = CBOR_BYTE_STRING;
info[2] = context_len as u8;
info[3..3 + context_len].copy_from_slice(&context[..context_len]);
3 + context_len
};

info_len = if length < 24 {
info[info_len] = length as u8;
info_len + 1
} else {
info[info_len] = CBOR_UINT_1BYTE;
info[info_len + 1] = length as u8;
info_len + 2
};

(info, info_len)
}
}
6 changes: 4 additions & 2 deletions crypto/edhoc-crypto-cryptocell310-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ pub fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen
pub fn aes_ccm_encrypt_tag_8(
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
ad: &[u8],
plaintext: &BufferPlaintext3,
) -> BufferCiphertext3 {
let mut output: BufferCiphertext3 = BufferCiphertext3::new();
let mut tag: CRYS_AESCCM_Mac_Res_t = Default::default();
let mut aesccm_key: CRYS_AESCCM_Key_t = Default::default();
let mut aesccm_ad = [0x00u8; ENC_STRUCTURE_LEN];

aesccm_key[0..AES_CCM_KEY_LEN].copy_from_slice(&key[..]);
aesccm_ad[0..ad.len()].copy_from_slice(&ad[..]);

let err = unsafe {
CC_AESCCM(
Expand All @@ -86,7 +88,7 @@ pub fn aes_ccm_encrypt_tag_8(
CRYS_AESCCM_KeySize_t_CRYS_AES_Key128BitSize,
iv.clone().as_mut_ptr(),
iv.len() as u8,
ad.clone().as_mut_ptr(),
aesccm_ad.as_mut_ptr(),
ad.len() as u32,
plaintext.content.clone().as_mut_ptr(),
plaintext.len as u32,
Expand Down
8 changes: 2 additions & 6 deletions crypto/edhoc-crypto-hacspec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,13 @@ pub fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen
pub fn aes_ccm_encrypt_tag_8(
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
ad: &[u8],
plaintext: &BufferPlaintext3,
) -> BufferCiphertext3 {
let plaintext = BufferPlaintext3Hacspec::from_public_buffer(plaintext);

let output = BufferCiphertext3Hacspec::from_seq(&encrypt_ccm(
ByteSeq::from_slice(
&BytesEncStructureLenHacspec::from_public_slice(ad),
0,
ad.len(),
),
ByteSeq::from_public_slice(ad),
ByteSeq::from_slice(&BytesCcmIvLenHacspec::from_public_slice(iv), 0, iv.len()),
ByteSeq::from_slice(&plaintext.content, 0, plaintext.len),
Key128::from_slice(&BytesCcmKeyLenHacspec::from_public_slice(key), 0, key.len()),
Expand Down
2 changes: 1 addition & 1 deletion crypto/edhoc-crypto-psa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub fn hkdf_extract(salt: &BytesHashLen, ikm: &BytesP256ElemLen) -> BytesHashLen
pub fn aes_ccm_encrypt_tag_8(
key: &BytesCcmKeyLen,
iv: &BytesCcmIvLen,
ad: &BytesEncStructureLen,
ad: &[u8],
plaintext: &BufferPlaintext3,
) -> BufferCiphertext3 {
psa_crypto::init().unwrap();
Expand Down
17 changes: 12 additions & 5 deletions ead/edhoc-ead-none/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@

use edhoc_consts::*;

// 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() -> Option<EADItem> {
pub fn i_prepare_ead_1(_x: &BytesP256ElemLen, _ss: u8) -> Option<EADItem> {
None
}

pub fn i_process_ead_2(ead_2: EADItem) -> Result<(), ()> {
pub fn i_process_ead_2(
_ead_2: EADItem,
_cred_v_u8: &[u8],
_h_message_1: &BytesHashLen,
) -> Result<(), ()> {
Ok(())
}

Expand All @@ -16,14 +23,14 @@ pub fn i_prepare_ead_3() -> Option<EADItem> {
}

// responder side
pub fn r_process_ead_1(ead_1: EADItem) -> Result<(), ()> {
pub fn r_process_ead_1(_ead_1: &EADItem, _message_1: &BufferMessage1) -> Result<(), ()> {
Ok(())
}

pub fn r_prepare_ead_2() -> Option<EADItem> {
pub fn r_prepare_ead_2(_voucher_response: &Option<EdhocMessageBuffer>) -> Option<EADItem> {
None
}

pub fn r_process_ead_3(ead_3: EADItem) -> Result<(), ()> {
pub fn r_process_ead_3(_ead_3: EADItem) -> Result<(), ()> {
Ok(())
}
7 changes: 7 additions & 0 deletions ead/edhoc-ead-zeroconf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@ description = "EDHOC EAD zeroconf (draf-lake-authz)"

[dependencies]
edhoc-consts = { path = "../../consts" }
edhoc-crypto = { path = "../../crypto", default-features = false }
hacspec-lib = { version = "0.1.0-beta.1", default-features = false, optional = true }
hexlit = "0.5.3"

[features]
crypto-psa = [ "edhoc-crypto/psa" ]
crypto-hacspec = ["hacspec-lib/std", "edhoc-crypto/hacspec" ]
Loading

0 comments on commit 8fc2763

Please sign in to comment.