Skip to content

Commit

Permalink
Improve support for big/little-endian arrays (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
justsmth authored Dec 18, 2023
1 parent fe3e2d3 commit 28dc103
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 13 deletions.
13 changes: 8 additions & 5 deletions aws-lc-rs/src/aead/chacha20_poly1305_openssh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ mod tests {
};
use crate::aead::Nonce;
use crate::cipher::chacha::ChaCha20Key;
use crate::endian::LittleEndian;
use crate::endian::{BigEndian, FromArray, LittleEndian};
use crate::test;

#[test]
Expand All @@ -229,13 +229,16 @@ mod tests {
}

{
let x = LittleEndian::from(45u32);
let y = LittleEndian::from(897);
let z = LittleEndian::from(4567);
let iv = Nonce::from(&[x, y, z]);
let iv = Nonce::from(&LittleEndian::<u32>::from_array(&[45u32, 897, 4567]));
let poly1305_key = derive_poly1305_key(&chacha_key, iv);
assert_eq!(&expected_poly1305_key, &poly1305_key.key_and_nonce);
}

{
let iv = Nonce::from(&BigEndian::<u32>::from_array(&[45u32, 897, 4567]));
let poly1305_key = derive_poly1305_key(&chacha_key, iv);
assert_ne!(&expected_poly1305_key, &poly1305_key.key_and_nonce);
}
}

#[test]
Expand Down
8 changes: 2 additions & 6 deletions aws-lc-rs/src/aead/nonce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

use crate::endian::{ArrayEncoding, BigEndian, Encoding, LittleEndian};
use crate::endian::{ArrayEncoding, BigEndian, Encoding, FromArray, LittleEndian};
use crate::error;
use crate::iv::FixedLength;

Expand Down Expand Up @@ -55,11 +55,7 @@ impl From<&[u8; NONCE_LEN]> for Nonce {
impl From<&[u32; NONCE_LEN / 4]> for Nonce {
#[inline]
fn from(values: &[u32; NONCE_LEN / 4]) -> Self {
let mut nonce = [LittleEndian::ZERO; NONCE_LEN / 4];
for i in 0..(NONCE_LEN / 4) {
nonce[i] = LittleEndian::from(values[i]);
}
Nonce::from(&nonce)
Nonce::from(&LittleEndian::<u32>::from_array(values))
}
}

Expand Down
36 changes: 34 additions & 2 deletions aws-lc-rs/src/endian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ pub trait ArrayEncoding<T> {

/// Work around the inability to implement `from` for arrays of `Encoding`s
/// due to the coherence rules.
pub trait FromByteArray<T> {
fn from_byte_array(a: &T) -> Self;
pub trait FromArray<const N: usize, T>
where
Self: Sized,
{
fn from_array(a: &[T; N]) -> [Self; N];
}

macro_rules! define_endian {
Expand All @@ -39,6 +42,8 @@ macro_rules! define_endian {
}

macro_rules! impl_array_encoding {
// This may be converted to use const generics once generic_const_exprs is stable.
// https://github.com/rust-lang/rust/issues/76560
($endian:ident, $base:ident, $elems:expr) => {
impl ArrayEncoding<[u8; $elems * core::mem::size_of::<$base>()]>
for [$endian<$base>; $elems]
Expand Down Expand Up @@ -70,6 +75,16 @@ macro_rules! impl_endian {
}
}

impl<const N: usize> FromArray<N, $base> for $endian<$base> {
fn from_array(value: &[$base; N]) -> [Self; N] {
let mut result: [$endian<$base>; N] = [$endian::ZERO; N];
for i in 0..N {
result[i] = $endian::from(value[i]);
}
return result;
}
}

impl_array_encoding!($endian, $base, 1);
impl_array_encoding!($endian, $base, 2);
impl_array_encoding!($endian, $base, 3);
Expand All @@ -96,4 +111,21 @@ mod tests {
assert_eq!(u32::from(x), 1);
assert_eq!(u32::from(x2), 1);
}

#[test]
fn test_endian_from_array() {
let be: [BigEndian<u32>; 2] =
BigEndian::<u32>::from_array(&[0x_AABB_CCDD_u32, 0x_2233_4455_u32]);
let le: [LittleEndian<u32>; 2] =
LittleEndian::<u32>::from_array(&[0x_DDCC_BBAA_u32, 0x_5544_3322_u32]);
assert_eq!(be.as_byte_array(), le.as_byte_array());

let be: [BigEndian<u64>; 2] =
BigEndian::<u64>::from_array(&[0x_AABB_CCDD_EEFF_0011_u64, 0x_2233_4455_6677_8899_u64]);
let le: [LittleEndian<u64>; 2] = LittleEndian::<u64>::from_array(&[
0x_1100_FFEE_DDCC_BBAA_u64,
0x_9988_7766_5544_3322_u64,
]);
assert_eq!(be.as_byte_array(), le.as_byte_array());
}
}

0 comments on commit 28dc103

Please sign in to comment.