Skip to content

Commit

Permalink
Update to the new MAC constructions
Browse files Browse the repository at this point in the history
  • Loading branch information
jedisct1 committed Dec 11, 2024
1 parent 91c0b86 commit c7ef050
Show file tree
Hide file tree
Showing 9 changed files with 349 additions and 63 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aegis"
version = "0.7.0"
version = "0.8.0"
edition = "2018"
authors = ["Frank Denis <[email protected]>"]
description = "AEGIS authenticated ciphers (AEGIS-128, AEGIS-256, AEGIS-128X, AEGIS-256X)"
Expand Down
65 changes: 55 additions & 10 deletions src/c/aegis128l.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,22 @@ pub type Key = [u8; 16];
/// AEGIS-128L nonce
pub type Nonce = [u8; 16];

#[allow(non_camel_case_types)]
#[allow(non_camel_case_types, dead_code)]
#[repr(C)]
#[repr(align(32))]
#[derive(Debug)]
struct aegis128l_state {
opaque: [u8; 256],
}

#[allow(non_camel_case_types)]
#[repr(C)]
#[repr(align(32))]
#[derive(Debug)]
struct aegis128l_mac_state {
opaque: [u8; 384],
}

extern "C" {
fn aegis_init() -> c_int;

Expand Down Expand Up @@ -43,15 +51,17 @@ extern "C" {
k: *const u8,
) -> c_int;

fn aegis128l_mac_init(st_: *mut aegis128l_state, k: *const u8);
fn aegis128l_mac_init(st_: *mut aegis128l_mac_state, k: *const u8, npub: *const u8);

fn aegis128l_mac_update(st_: *mut aegis128l_state, m: *const u8, mlen: usize) -> c_int;
fn aegis128l_mac_update(st_: *mut aegis128l_mac_state, m: *const u8, mlen: usize) -> c_int;

fn aegis128l_mac_final(st_: *mut aegis128l_state, mac: *mut u8, maclen: usize) -> c_int;
fn aegis128l_mac_final(st_: *mut aegis128l_mac_state, mac: *mut u8, maclen: usize) -> c_int;

fn aegis128l_mac_verify(st_: *mut aegis128l_state, mac: *const u8, maclen: usize) -> c_int;
fn aegis128l_mac_verify(st_: *mut aegis128l_mac_state, mac: *const u8, maclen: usize) -> c_int;

fn aegis128l_mac_state_clone(dst: *mut aegis128l_state, src: *const aegis128l_state);
fn aegis128l_mac_reset(st_: *mut aegis128l_mac_state);

fn aegis128l_mac_state_clone(dst: *mut aegis128l_mac_state, src: *const aegis128l_mac_state);
}

#[cfg(feature = "std")]
Expand Down Expand Up @@ -229,12 +239,12 @@ impl<const TAG_BYTES: usize> Aegis128L<TAG_BYTES> {
/// Inputs leading to a state collision can be efficiently computed if the key is known.
#[derive(Debug)]
pub struct Aegis128LMac<const TAG_BYTES: usize> {
st: aegis128l_state,
st: aegis128l_mac_state,
}

impl<const TAG_BYTES: usize> Clone for Aegis128LMac<TAG_BYTES> {
fn clone(&self) -> Self {
let mut st = MaybeUninit::<aegis128l_state>::uninit();
let mut st = MaybeUninit::<aegis128l_mac_state>::uninit();
unsafe {
aegis128l_mac_state_clone(st.as_mut_ptr(), &self.st);
}
Expand Down Expand Up @@ -279,9 +289,27 @@ impl<const TAG_BYTES: usize> Aegis128LMac<TAG_BYTES> {
"Invalid tag length, must be 16 or 32"
);
Self::ensure_init();
let mut st = MaybeUninit::<aegis128l_state>::uninit();
let mut st = MaybeUninit::<aegis128l_mac_state>::uninit();
unsafe {
aegis128l_mac_init(st.as_mut_ptr(), key.as_ptr());
aegis128l_mac_init(st.as_mut_ptr(), key.as_ptr(), [0u8; 16].as_ptr());
}
Aegis128LMac {
st: unsafe { st.assume_init() },
}
}

/// Initializes the MAC state with a key and a nonce
///
/// The state can be cloned to authenticate multiple messages with the same key.
pub fn new_with_nonce(key: &Key, npub: &Nonce) -> Self {
assert!(
TAG_BYTES == 16 || TAG_BYTES == 32,
"Invalid tag length, must be 16 or 32"
);
Self::ensure_init();
let mut st = MaybeUninit::<aegis128l_mac_state>::uninit();
unsafe {
aegis128l_mac_init(st.as_mut_ptr(), key.as_ptr(), npub.as_ptr());
}
Aegis128LMac {
st: unsafe { st.assume_init() },
Expand All @@ -306,6 +334,16 @@ impl<const TAG_BYTES: usize> Aegis128LMac<TAG_BYTES> {
tag
}

/// Finalizes the MAC, resets the state for reuse, and returns the authentication tag
pub fn finalize_and_reset(&mut self) -> Tag<TAG_BYTES> {
let mut tag = [0u8; TAG_BYTES];
unsafe {
aegis128l_mac_final(&mut self.st, tag.as_mut_ptr(), TAG_BYTES);
aegis128l_mac_reset(&mut self.st);
}
tag
}

/// Verifies the authentication tag
pub fn verify(mut self, tag: &Tag<TAG_BYTES>) -> Result<(), Error> {
let res = unsafe { aegis128l_mac_verify(&mut self.st, tag.as_ptr(), TAG_BYTES) };
Expand All @@ -314,4 +352,11 @@ impl<const TAG_BYTES: usize> Aegis128LMac<TAG_BYTES> {
}
Ok(())
}

/// Resets the MAC state
pub fn reset(&mut self) {
unsafe {
aegis128l_mac_reset(&mut self.st);
}
}
}
69 changes: 59 additions & 10 deletions src/c/aegis128x2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,22 @@ pub type Key = [u8; 16];
/// AEGIS-128X2 nonce
pub type Nonce = [u8; 16];

#[allow(non_camel_case_types)]
#[allow(non_camel_case_types, dead_code)]
#[repr(C)]
#[repr(align(64))]
#[derive(Debug)]
struct aegis128x2_state {
opaque: [u8; 448],
}

#[allow(non_camel_case_types)]
#[repr(C)]
#[repr(align(64))]
#[derive(Debug)]
struct aegis128x2_mac_state {
opaque: [u8; 704],
}

extern "C" {
fn aegis_init() -> c_int;

Expand Down Expand Up @@ -43,15 +51,21 @@ extern "C" {
k: *const u8,
) -> c_int;

fn aegis128x2_mac_init(st_: *mut aegis128x2_state, k: *const u8);
fn aegis128x2_mac_init(st_: *mut aegis128x2_mac_state, k: *const u8, npub: *const u8);

fn aegis128x2_mac_update(st_: *mut aegis128x2_state, m: *const u8, mlen: usize) -> c_int;
fn aegis128x2_mac_update(st_: *mut aegis128x2_mac_state, m: *const u8, mlen: usize) -> c_int;

fn aegis128x2_mac_final(st_: *mut aegis128x2_state, mac: *mut u8, maclen: usize) -> c_int;
fn aegis128x2_mac_final(st_: *mut aegis128x2_mac_state, mac: *mut u8, maclen: usize) -> c_int;

fn aegis128x2_mac_verify(
st_: *mut aegis128x2_mac_state,
mac: *const u8,
maclen: usize,
) -> c_int;

fn aegis128x2_mac_verify(st_: *mut aegis128x2_state, mac: *const u8, maclen: usize) -> c_int;
fn aegis128x2_mac_reset(st_: *mut aegis128x2_mac_state);

fn aegis128x2_mac_state_clone(dst: *mut aegis128x2_state, src: *const aegis128x2_state);
fn aegis128x2_mac_state_clone(dst: *mut aegis128x2_mac_state, src: *const aegis128x2_mac_state);

}

Expand Down Expand Up @@ -230,12 +244,12 @@ impl<const TAG_BYTES: usize> Aegis128X2<TAG_BYTES> {
/// Inputs leading to a state collision can be efficiently computed if the key is known.
#[derive(Debug)]
pub struct Aegis128X2Mac<const TAG_BYTES: usize> {
st: aegis128x2_state,
st: aegis128x2_mac_state,
}

impl<const TAG_BYTES: usize> Clone for Aegis128X2Mac<TAG_BYTES> {
fn clone(&self) -> Self {
let mut st = MaybeUninit::<aegis128x2_state>::uninit();
let mut st = MaybeUninit::<aegis128x2_mac_state>::uninit();
unsafe {
aegis128x2_mac_state_clone(st.as_mut_ptr(), &self.st);
}
Expand Down Expand Up @@ -280,9 +294,27 @@ impl<const TAG_BYTES: usize> Aegis128X2Mac<TAG_BYTES> {
"Invalid tag length, must be 16 or 32"
);
Self::ensure_init();
let mut st = MaybeUninit::<aegis128x2_state>::uninit();
let mut st = MaybeUninit::<aegis128x2_mac_state>::uninit();
unsafe {
aegis128x2_mac_init(st.as_mut_ptr(), key.as_ptr(), [0u8; 16].as_ptr());
}
Aegis128X2Mac {
st: unsafe { st.assume_init() },
}
}

/// Initializes the MAC state with a key and a nonce.
///
/// The state can be cloned to authenticate multiple messages with the same key.
pub fn new_with_nonce(key: &Key, npub: &Nonce) -> Self {
assert!(
TAG_BYTES == 16 || TAG_BYTES == 32,
"Invalid tag length, must be 16 or 32"
);
Self::ensure_init();
let mut st = MaybeUninit::<aegis128x2_mac_state>::uninit();
unsafe {
aegis128x2_mac_init(st.as_mut_ptr(), key.as_ptr());
aegis128x2_mac_init(st.as_mut_ptr(), key.as_ptr(), npub.as_ptr());
}
Aegis128X2Mac {
st: unsafe { st.assume_init() },
Expand All @@ -307,6 +339,16 @@ impl<const TAG_BYTES: usize> Aegis128X2Mac<TAG_BYTES> {
tag
}

/// Finalizes the MAC, resets the state for reuse, and returns the authentication tag
pub fn finalize_and_reset(&mut self) -> Tag<TAG_BYTES> {
let mut tag = [0u8; TAG_BYTES];
unsafe {
aegis128x2_mac_final(&mut self.st, tag.as_mut_ptr(), TAG_BYTES);
aegis128x2_mac_reset(&mut self.st);
}
tag
}

/// Verifies the authentication tag
pub fn verify(mut self, tag: &Tag<TAG_BYTES>) -> Result<(), Error> {
let res = unsafe { aegis128x2_mac_verify(&mut self.st, tag.as_ptr(), TAG_BYTES) };
Expand All @@ -315,4 +357,11 @@ impl<const TAG_BYTES: usize> Aegis128X2Mac<TAG_BYTES> {
}
Ok(())
}

/// Resets the MAC state
pub fn reset(&mut self) {
unsafe {
aegis128x2_mac_reset(&mut self.st);
}
}
}
69 changes: 59 additions & 10 deletions src/c/aegis128x4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,22 @@ pub type Key = [u8; 16];
/// AEGIS-128X4 nonce
pub type Nonce = [u8; 16];

#[allow(non_camel_case_types)]
#[allow(non_camel_case_types, dead_code)]
#[repr(C)]
#[repr(align(64))]
#[derive(Debug)]
struct aegis128x4_state {
opaque: [u8; 832],
}

#[allow(non_camel_case_types)]
#[repr(C)]
#[repr(align(64))]
#[derive(Debug)]
struct aegis128x4_mac_state {
opaque: [u8; 1344],
}

extern "C" {
fn aegis_init() -> c_int;

Expand Down Expand Up @@ -43,15 +51,21 @@ extern "C" {
k: *const u8,
) -> c_int;

fn aegis128x4_mac_init(st_: *mut aegis128x4_state, k: *const u8);
fn aegis128x4_mac_init(st_: *mut aegis128x4_mac_state, k: *const u8, npub: *const u8);

fn aegis128x4_mac_update(st_: *mut aegis128x4_state, m: *const u8, mlen: usize) -> c_int;
fn aegis128x4_mac_update(st_: *mut aegis128x4_mac_state, m: *const u8, mlen: usize) -> c_int;

fn aegis128x4_mac_final(st_: *mut aegis128x4_state, mac: *mut u8, maclen: usize) -> c_int;
fn aegis128x4_mac_final(st_: *mut aegis128x4_mac_state, mac: *mut u8, maclen: usize) -> c_int;

fn aegis128x4_mac_verify(
st_: *mut aegis128x4_mac_state,
mac: *const u8,
maclen: usize,
) -> c_int;

fn aegis128x4_mac_verify(st_: *mut aegis128x4_state, mac: *const u8, maclen: usize) -> c_int;
fn aegis128x4_mac_reset(st_: *mut aegis128x4_mac_state);

fn aegis128x4_mac_state_clone(dst: *mut aegis128x4_state, src: *const aegis128x4_state);
fn aegis128x4_mac_state_clone(dst: *mut aegis128x4_mac_state, src: *const aegis128x4_mac_state);
}

#[cfg(feature = "std")]
Expand Down Expand Up @@ -229,12 +243,12 @@ impl<const TAG_BYTES: usize> Aegis128X4<TAG_BYTES> {
/// Inputs leading to a state collision can be efficiently computed if the key is known.
#[derive(Debug)]
pub struct Aegis128X4Mac<const TAG_BYTES: usize> {
st: aegis128x4_state,
st: aegis128x4_mac_state,
}

impl<const TAG_BYTES: usize> Clone for Aegis128X4Mac<TAG_BYTES> {
fn clone(&self) -> Self {
let mut st = MaybeUninit::<aegis128x4_state>::uninit();
let mut st = MaybeUninit::<aegis128x4_mac_state>::uninit();
unsafe {
aegis128x4_mac_state_clone(st.as_mut_ptr(), &self.st);
}
Expand Down Expand Up @@ -279,9 +293,27 @@ impl<const TAG_BYTES: usize> Aegis128X4Mac<TAG_BYTES> {
"Invalid tag length, must be 16 or 32"
);
Self::ensure_init();
let mut st = MaybeUninit::<aegis128x4_state>::uninit();
let mut st = MaybeUninit::<aegis128x4_mac_state>::uninit();
unsafe {
aegis128x4_mac_init(st.as_mut_ptr(), key.as_ptr(), [0u8; 16].as_ptr());
}
Aegis128X4Mac {
st: unsafe { st.assume_init() },
}
}

/// Initializes the MAC state with a key and a nonce.
///
/// The state can be cloned to authenticate multiple messages with the same key.
pub fn new_with_nonce(key: &Key, npub: &Nonce) -> Self {
assert!(
TAG_BYTES == 16 || TAG_BYTES == 32,
"Invalid tag length, must be 16 or 32"
);
Self::ensure_init();
let mut st = MaybeUninit::<aegis128x4_mac_state>::uninit();
unsafe {
aegis128x4_mac_init(st.as_mut_ptr(), key.as_ptr());
aegis128x4_mac_init(st.as_mut_ptr(), key.as_ptr(), npub.as_ptr());
}
Aegis128X4Mac {
st: unsafe { st.assume_init() },
Expand All @@ -306,6 +338,16 @@ impl<const TAG_BYTES: usize> Aegis128X4Mac<TAG_BYTES> {
tag
}

/// Finalizes the MAC, resets the state for reuse, and returns the authentication tag
pub fn finalize_and_reset(&mut self) -> Tag<TAG_BYTES> {
let mut tag = [0u8; TAG_BYTES];
unsafe {
aegis128x4_mac_final(&mut self.st, tag.as_mut_ptr(), TAG_BYTES);
aegis128x4_mac_reset(&mut self.st);
}
tag
}

/// Verifies the authentication tag
pub fn verify(mut self, tag: &Tag<TAG_BYTES>) -> Result<(), Error> {
let res = unsafe { aegis128x4_mac_verify(&mut self.st, tag.as_ptr(), TAG_BYTES) };
Expand All @@ -314,4 +356,11 @@ impl<const TAG_BYTES: usize> Aegis128X4Mac<TAG_BYTES> {
}
Ok(())
}

/// Resets the MAC state
pub fn reset(&mut self) {
unsafe {
aegis128x4_mac_reset(&mut self.st);
}
}
}
Loading

0 comments on commit c7ef050

Please sign in to comment.