-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Core functions for the lake-authz draft #110
Conversation
3fe2ddf
to
656dced
Compare
e677de2
to
ca45d49
Compare
ca45d49
to
e1bb540
Compare
3196c8e
to
54813d8
Compare
56c83d1
to
e756401
Compare
- includes test vectors - also updates test vectors to reuse keys from lake-traces-07
e756401
to
3a182c5
Compare
005d114
to
9b6daa6
Compare
@malishav it still needs polishing but all core functions of the draft work, so it could receive a first pass of review. Please focus on the |
Also, for reference, I used this notebook to create the traces / test vectors. |
It looks better now, but I think it will not be fully working with all features and possible configurations by the end of the day. Since I will leave for PTO until 24 Oct, I would like to merge this today (if the review goes well), even if I have to adapt the CI with feature/exclude flags. |
97e6817
to
65f73d0
Compare
Wohoo, CI passing! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for providing this PR @geonnave ! I left some inline comments, the major red flag that I see is parsing code which does not check the actual number of bytes received and may panic. Other than that, I think there is a misconception on the length of the voucher and some excessive allocations. See inline for more details.
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
} | ||
|
||
// NOTE: can we import this from the edhoc-rs main crate? | ||
fn edhoc_kdf( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, we should definitely have a way of calling the KDF function frm this code without code duplication
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps, we can do the same as with encode_enc_structure
and move this to a helper module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the time being I moved just the logic for the info
struct to a helpers
module in consts
.
Part of the reason is to avoid having consts
depend on the cryptographic backends.
Another part is that this is now only a single small duplicated function, so in my view it still does not justify changing the dependencies in consts
.
Nevertheless I added a TO-DO (🙃), that we should address as more cases like this arise.
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
(), | ||
> { | ||
let mut message_1 = EdhocMessageBuffer::new(); | ||
let mut voucher = EdhocMessageBuffer::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an excessive allocation for a voucher. Voucher is always of size MAC_LENGTH
which corresponds to the MAC length used in EDHOC. Since we only support a single cipher suite for now, this should use MAC_LENGTH
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this for consistency, but note that since we need to put the voucher in an EADItem struct, we sill need to allocate one large buffer since the EADItem.value
is an EdhocMessageBuffer
.
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
return Err(()); | ||
} | ||
|
||
message_1.len = voucher_response.content[2] as usize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that you are not checking anywhere how many bytes are actually in the received voucher_response
, i.e. the value of voucher_response.len
. This means that your code may panic when it receives a malformed Voucher Response or worse take values from the internal buffer at random. This code should be rewritten to check remaining voucher_response.len
before actually accessing voucher_response.content
array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added size verifications to all parse_*
routines.
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
ead_1_value: &Option<EdhocMessageBuffer>, | ||
) -> Result<(EdhocMessageBuffer, EdhocMessageBuffer), ()> { | ||
let value = ead_1_value.unwrap(); | ||
let loc_w: EdhocMessageBuffer = value.content[4..4 + value.content[3] as usize] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above: before accessing value.content
, we need to check how long it is...
} | ||
|
||
message_1.len = vreq.content[2] as usize; | ||
message_1.content[..message_1.len].copy_from_slice(&vreq.content[3..3 + message_1.len]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment on accessing vreq.content[]
as above
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
|
||
// IV_1 = EDHOC-Expand(PRK, info = (1, h'', AES_CCM_KEY_LEN), length) | ||
let mut iv_1: BytesCcmIvLen = [0x00; AES_CCM_IV_LEN]; | ||
// NOTE (FIXME?): here we actually generate AES_CCM_KEY_LEN bytes, but then we only use AES_CCM_IV_LEN of them (next line) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is strange. Looking at draft-ietf-lake-authz
:
The derivation of IV_1 = EDHOC-Expand(PRK, info, length) uses the following input to the info struct (see Section 4.2):
info_label = 1
context = h'' (the empty CBOR string)
length is length of nonce of the EDHOC AEAD algorithm in bytes
According to this, length should be set to AES_CCM_IV_LEN
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
} | ||
|
||
const EAD_ENC_STRUCTURE_LEN: usize = 2 + 8 + 3; | ||
fn encode_enc_structure(ss: u8) -> [u8; EAD_ENC_STRUCTURE_LEN] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the same code as in lib/src/edhoc.rs
, function encode_enc_structure
? If so, why not move it like a helper function together with CBOR-related helpers? Jsut rename the module to something more appropriate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not the same, the input in this case is just ss: u8
while in lib/src/edhoc.rs
the input is th_3: &BytesHashLen
.
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
pub fn r_process_ead_1(ead_1: &EADItem, message_1: &BufferMessage1) -> Result<(), ()> { | ||
let opaque_state: Option<EdhocMessageBuffer> = None; // TODO: receive as parameter | ||
|
||
if ead_1.label != EAD_ZEROCONF_LABEL { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this be checked somehow beforehand, i.e. in the library code invoking the EAD handler? If yes, this could be an replaced with an assertion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not checked before, since the library is agnostic of the EAD handlers. Thus I think we can keep the if
check.
c764496
to
442c774
Compare
442c774
to
439c326
Compare
d53d18d
to
bb20772
Compare
From my side, this is ready to merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial review below, as discussed offline.
ead/edhoc-ead-zeroconf/src/lib.rs
Outdated
} | ||
|
||
fn build_enc_id( | ||
prk: &BytesHashLen, // ephemeral key of U |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment here confused me. prk
is not an ephemeral key, but the ECDH secret derived from the ephemeral key of U and static key of W. The code seems correct, the comment does not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, was a reminiscent comment from before a refactoring. Removed.
let mut message_1 = EdhocMessageBuffer::new(); | ||
let mut voucher: BytesEncodedVoucher = Default::default(); | ||
|
||
let array_byte = voucher_response.content[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are accessing voucher_response.content[0]
here before checking whether the received length, voucher_response.len
, is greater than zero. Are you ensuring that the function can be called only when voucher_response.len
is >0? If yes, then you could have an assert assert!(voucher_response.len > 0)
. If not, the whole block of code lines 365-409 should be conditioned on if(voucher_reponse.len > 0)
IMO.
return Err(()); | ||
} | ||
|
||
let message_1_len = voucher_response.content[2] as usize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, you accessed voucher_response.content[2]
before having checked if there are enough bytes in the buffer according to voucher_response.len
. That may panic if voucher_response.len
is only 1 byte.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, we will address this issue in a separate PR.
This PR will implement the core functions for EAD message preparation and processing with focus on U and V:
Draft link: https://www.ietf.org/archive/id/draft-selander-lake-authz-03.html
Architecture: