Skip to content

Commit

Permalink
Update 128X4 to the new MAC API
Browse files Browse the repository at this point in the history
  • Loading branch information
jedisct1 committed Dec 9, 2024
1 parent 57ade7c commit df189b5
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 43 deletions.
20 changes: 13 additions & 7 deletions src/aegis128x4/aegis128x4.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,19 @@ aegis128x4_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, co
}

void
aegis128x4_mac_init(aegis128x4_state *st_, const uint8_t *k, const uint8_t *npub)
aegis128x4_mac_init(aegis128x4_mac_state *st_, const uint8_t *k, const uint8_t *npub)
{
implementation->state_init(st_, NULL, 0, npub, k);
implementation->state_mac_init(st_, npub, k);
}

int
aegis128x4_mac_update(aegis128x4_state *st_, const uint8_t *m, size_t mlen)
aegis128x4_mac_update(aegis128x4_mac_state *st_, const uint8_t *m, size_t mlen)
{
return implementation->state_mac_update(st_, m, mlen);
}

int
aegis128x4_mac_final(aegis128x4_state *st_, uint8_t *mac, size_t maclen)
aegis128x4_mac_final(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen)
{
if (maclen != 16 && maclen != 32) {
errno = EINVAL;
Expand All @@ -199,7 +199,7 @@ aegis128x4_mac_final(aegis128x4_state *st_, uint8_t *mac, size_t maclen)
}

int
aegis128x4_mac_verify(aegis128x4_state *st_, const uint8_t *mac, size_t maclen)
aegis128x4_mac_verify(aegis128x4_mac_state *st_, const uint8_t *mac, size_t maclen)
{
uint8_t expected_mac[32];

Expand All @@ -217,9 +217,15 @@ aegis128x4_mac_verify(aegis128x4_state *st_, const uint8_t *mac, size_t maclen)
}

void
aegis128x4_mac_state_clone(aegis128x4_state *dst, const aegis128x4_state *src)
aegis128x4_mac_reset(aegis128x4_mac_state *st_)
{
implementation->state_clone(dst, src);
implementation->state_mac_reset(st_);
}

void
aegis128x4_mac_state_clone(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src)
{
implementation->state_mac_clone(dst, src);
}

int
Expand Down
4 changes: 3 additions & 1 deletion src/aegis128x4/aegis128x4_aesni.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,11 @@ struct aegis128x4_implementation aegis128x4_aesni_implementation = {
.state_encrypt_final = state_encrypt_final,
.state_decrypt_detached_update = state_decrypt_detached_update,
.state_decrypt_detached_final = state_decrypt_detached_final,
.state_mac_init = state_mac_init,
.state_mac_update = state_mac_update,
.state_mac_final = state_mac_final,
.state_clone = state_clone,
.state_mac_reset = state_mac_reset,
.state_mac_clone = state_mac_clone,
};

# ifdef __clang__
Expand Down
4 changes: 3 additions & 1 deletion src/aegis128x4/aegis128x4_altivec.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,11 @@ struct aegis128x4_implementation aegis128x4_altivec_implementation = {
.state_encrypt_final = state_encrypt_final,
.state_decrypt_detached_update = state_decrypt_detached_update,
.state_decrypt_detached_final = state_decrypt_detached_final,
.state_mac_init = state_mac_init,
.state_mac_update = state_mac_update,
.state_mac_final = state_mac_final,
.state_clone = state_clone,
.state_mac_reset = state_mac_reset,
.state_mac_clone = state_mac_clone,
};

# ifdef __clang__
Expand Down
4 changes: 3 additions & 1 deletion src/aegis128x4/aegis128x4_armcrypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ struct aegis128x4_implementation aegis128x4_armcrypto_implementation = {
.state_encrypt_final = state_encrypt_final,
.state_decrypt_detached_update = state_decrypt_detached_update,
.state_decrypt_detached_final = state_decrypt_detached_final,
.state_mac_init = state_mac_init,
.state_mac_update = state_mac_update,
.state_mac_final = state_mac_final,
.state_clone = state_clone,
.state_mac_reset = state_mac_reset,
.state_mac_clone = state_mac_clone,
};

# ifdef __clang__
Expand Down
4 changes: 3 additions & 1 deletion src/aegis128x4/aegis128x4_avx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,11 @@ struct aegis128x4_implementation aegis128x4_avx2_implementation = {
.state_encrypt_final = state_encrypt_final,
.state_decrypt_detached_update = state_decrypt_detached_update,
.state_decrypt_detached_final = state_decrypt_detached_final,
.state_mac_init = state_mac_init,
.state_mac_update = state_mac_update,
.state_mac_final = state_mac_final,
.state_clone = state_clone,
.state_mac_reset = state_mac_reset,
.state_mac_clone = state_mac_clone,
};

# ifdef __clang__
Expand Down
4 changes: 3 additions & 1 deletion src/aegis128x4/aegis128x4_avx512.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ struct aegis128x4_implementation aegis128x4_avx512_implementation = {
.state_encrypt_final = state_encrypt_final,
.state_decrypt_detached_update = state_decrypt_detached_update,
.state_decrypt_detached_final = state_decrypt_detached_final,
.state_mac_init = state_mac_init,
.state_mac_update = state_mac_update,
.state_mac_final = state_mac_final,
.state_clone = state_clone,
.state_mac_reset = state_mac_reset,
.state_mac_clone = state_mac_clone,
};

# ifdef __clang__
Expand Down
147 changes: 128 additions & 19 deletions src/aegis128x4/aegis128x4_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,76 @@ aegis128x4_declast(uint8_t *const dst, const uint8_t *const src, size_t len,
aegis128x4_update(state, msg0, msg1);
}

static void
aegis128x4_mac_nr(uint8_t *mac, size_t maclen, uint64_t adlen, aes_block_t *state)
{
uint8_t t[2 * AES_BLOCK_LENGTH];
uint8_t r[RATE];
aes_block_t tmp;
int i;
const int d = AES_BLOCK_LENGTH / 16;

tmp = AES_BLOCK_LOAD_64x2(0, adlen << 3);
tmp = AES_BLOCK_XOR(tmp, state[2]);

for (i = 0; i < 7; i++) {
aegis128x4_update(state, tmp, tmp);
}

memset(r, 0, sizeof r);
if (maclen == 16) {
#if AES_BLOCK_LENGTH > 16
tmp = AES_BLOCK_XOR(state[6], AES_BLOCK_XOR(state[5], state[4]));
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[3], state[2]));
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[1], state[0]));
AES_BLOCK_STORE(t, tmp);
for (i = 0; i < d / 2; i++) {
memcpy(r, t + i * 32, 32);
aegis128x4_absorb(r, state);
}
tmp = AES_BLOCK_LOAD_64x2(d, maclen);
tmp = AES_BLOCK_XOR(tmp, state[2]);
for (i = 0; i < 7; i++) {
aegis128x4_update(state, tmp, tmp);
}
#endif
tmp = AES_BLOCK_XOR(state[6], AES_BLOCK_XOR(state[5], state[4]));
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[3], state[2]));
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[1], state[0]));
AES_BLOCK_STORE(t, tmp);
memcpy(mac, t, 16);
} else if (maclen == 32) {
#if AES_BLOCK_LENGTH > 16
tmp = AES_BLOCK_XOR(state[3], state[2]);
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[1], state[0]));
AES_BLOCK_STORE(t, tmp);
tmp = AES_BLOCK_XOR(state[7], state[6]);
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[5], state[4]));
AES_BLOCK_STORE(t + AES_BLOCK_LENGTH, tmp);
for (i = 1; i < d; i++) {
memcpy(r, t + i * 16, 16);
memcpy(r + 16, t + AES_BLOCK_LENGTH + i * 16, 16);
aegis128x4_absorb(r, state);
}
tmp = AES_BLOCK_LOAD_64x2(d, maclen);
tmp = AES_BLOCK_XOR(tmp, state[2]);
for (i = 0; i < 7; i++) {
aegis128x4_update(state, tmp, tmp);
}
#endif
tmp = AES_BLOCK_XOR(state[3], state[2]);
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[1], state[0]));
AES_BLOCK_STORE(t, tmp);
memcpy(mac, t, 16);
tmp = AES_BLOCK_XOR(state[7], state[6]);
tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[5], state[4]));
AES_BLOCK_STORE(t, tmp);
memcpy(mac + 16, t, 16);
} else {
memset(mac, 0, maclen);
}
}

static int
encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen,
const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k)
Expand Down Expand Up @@ -351,6 +421,14 @@ typedef struct _aegis128x4_state {
size_t pos;
} _aegis128x4_state;

typedef struct _aegis128x4_mac_state {
aegis_blocks blocks0;
aegis_blocks blocks;
uint8_t buf[RATE];
uint64_t adlen;
size_t pos;
} _aegis128x4_mac_state;

static void
state_init(aegis128x4_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub,
const uint8_t *k)
Expand Down Expand Up @@ -619,13 +697,33 @@ state_decrypt_detached_final(aegis128x4_state *st_, uint8_t *m, size_t mlen_max,
return ret;
}

static void
state_mac_init(aegis128x4_mac_state *st_, const uint8_t *npub, const uint8_t *k)
{
aegis_blocks blocks;
_aegis128x4_mac_state *const st =
(_aegis128x4_mac_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));

COMPILER_ASSERT((sizeof *st) + ALIGNMENT <= sizeof *st_);
st->pos = 0;

memcpy(blocks, st->blocks, sizeof blocks);

aegis128x4_init(k, npub, blocks);

memcpy(st->blocks0, blocks, sizeof blocks);
memcpy(st->blocks, blocks, sizeof blocks);
st->adlen = 0;
}

static int
state_mac_update(aegis128x4_state *st_, const uint8_t *ad, size_t adlen)
state_mac_update(aegis128x4_mac_state *st_, const uint8_t *ad, size_t adlen)
{
aegis_blocks blocks;
_aegis128x4_state *const st =
(_aegis128x4_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
aegis_blocks blocks;
_aegis128x4_mac_state *const st =
(_aegis128x4_mac_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
size_t i;
size_t left;

Expand Down Expand Up @@ -669,12 +767,12 @@ state_mac_update(aegis128x4_state *st_, const uint8_t *ad, size_t adlen)
}

static int
state_mac_final(aegis128x4_state *st_, uint8_t *mac, size_t maclen)
state_mac_final(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen)
{
aegis_blocks blocks;
_aegis128x4_state *const st =
(_aegis128x4_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
aegis_blocks blocks;
_aegis128x4_mac_state *const st =
(_aegis128x4_mac_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
size_t left;

memcpy(blocks, st->blocks, sizeof blocks);
Expand All @@ -684,21 +782,32 @@ state_mac_final(aegis128x4_state *st_, uint8_t *mac, size_t maclen)
memset(st->buf + left, 0, RATE - left);
aegis128x4_absorb(st->buf, blocks);
}
aegis128x4_mac(mac, maclen, st->adlen, 0, blocks);
aegis128x4_mac_nr(mac, maclen, st->adlen, blocks);

memcpy(st->blocks, blocks, sizeof blocks);

return 0;
}

static void
state_clone(aegis128x4_state *dst, const aegis128x4_state *src)
state_mac_reset(aegis128x4_mac_state *st_)
{
_aegis128x4_state *const dst_ =
(_aegis128x4_state *) ((((uintptr_t) &dst->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
const _aegis128x4_state *const src_ =
(const _aegis128x4_state *) ((((uintptr_t) &src->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
_aegis128x4_mac_state *const st =
(_aegis128x4_mac_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
st->adlen = 0;
st->pos = 0;
memcpy(st->blocks, st->blocks0, sizeof(aegis_blocks));
}

static void
state_mac_clone(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src)
{
_aegis128x4_mac_state *const dst_ =
(_aegis128x4_mac_state *) ((((uintptr_t) &dst->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
const _aegis128x4_mac_state *const src_ =
(const _aegis128x4_mac_state *) ((((uintptr_t) &src->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
*dst_ = *src_;
}
}
8 changes: 5 additions & 3 deletions src/aegis128x4/implementations.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ typedef struct aegis128x4_implementation {
size_t *written, const uint8_t *c, size_t clen);
int (*state_decrypt_detached_final)(aegis128x4_state *st_, uint8_t *m, size_t mlen_max,
size_t *written, const uint8_t *mac, size_t maclen);
int (*state_mac_update)(aegis128x4_state *st_, const uint8_t *ad, size_t adlen);
int (*state_mac_final)(aegis128x4_state *st_, uint8_t *mac, size_t maclen);
void (*state_clone)(aegis128x4_state *dst, const aegis128x4_state *src);
void (*state_mac_init)(aegis128x4_mac_state *st_, const uint8_t *npub, const uint8_t *k);
int (*state_mac_update)(aegis128x4_mac_state *st_, const uint8_t *ad, size_t adlen);
int (*state_mac_final)(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen);
void (*state_mac_reset)(aegis128x4_mac_state *st);
void (*state_mac_clone)(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src);
} aegis128x4_implementation;

#endif
21 changes: 15 additions & 6 deletions src/include/aegis128x4.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ typedef struct aegis128x4_state {
CRYPTO_ALIGN(64) uint8_t opaque[832];
} aegis128x4_state;

/* An AEGIS state, only for MAC updates */
typedef struct aegis128x4_mac_state {
CRYPTO_ALIGN(32) uint8_t opaque[1664];
} aegis128x4_mac_state;

/* The length of an AEGIS key, in bytes */
size_t aegis128x4_keybytes(void);

Expand Down Expand Up @@ -258,13 +263,12 @@ void aegis128x4_decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t cle
* k: key input buffer (16 bytes)
*
* - The same key MUST NOT be used both for MAC and encryption.
* - The nonce MUST NOT be reused with the same key.
* - If the key is secret, the MAC is secure against forgery.
* - However, if the key is known, arbitrary inputs matching a tag can be efficiently computed.
*
* The recommended way to use the MAC mode is to generate a random key and keep it secret.
*/
void aegis128x4_mac_init(aegis128x4_state *st_, const uint8_t *k, const uint8_t *npub);
void aegis128x4_mac_init(aegis128x4_mac_state *st_, const uint8_t *k, const uint8_t *npub);

/*
* Update the MAC state with input data.
Expand All @@ -277,7 +281,7 @@ void aegis128x4_mac_init(aegis128x4_state *st_, const uint8_t *k, const uint8_t
*
* Once the full input has been absorb, call either `_mac_final` or `_mac_verify`.
*/
int aegis128x4_mac_update(aegis128x4_state *st_, const uint8_t *m, size_t mlen);
int aegis128x4_mac_update(aegis128x4_mac_state *st_, const uint8_t *m, size_t mlen);

/*
* Finalize the MAC and generate the authentication tag.
Expand All @@ -286,7 +290,7 @@ int aegis128x4_mac_update(aegis128x4_state *st_, const uint8_t *m, size_t mlen);
* mac: authentication tag output buffer
* maclen: length of the authentication tag to generate (16 or 32. 32 is recommended).
*/
int aegis128x4_mac_final(aegis128x4_state *st_, uint8_t *mac, size_t maclen);
int aegis128x4_mac_final(aegis128x4_mac_state *st_, uint8_t *mac, size_t maclen);

/*
* Verify a MAC in constant time.
Expand All @@ -297,7 +301,12 @@ int aegis128x4_mac_final(aegis128x4_state *st_, uint8_t *mac, size_t maclen);
*
* Returns 0 if the tag is authentic, -1 otherwise.
*/
int aegis128x4_mac_verify(aegis128x4_state *st_, const uint8_t *mac, size_t maclen);
int aegis128x4_mac_verify(aegis128x4_mac_state *st_, const uint8_t *mac, size_t maclen);

/*
* Reset an AEGIS_MAC state.
*/
void aegis128x4_mac_reset(aegis128x4_mac_state *st_);

/*
* Clone an AEGIS-MAC state.
Expand All @@ -307,7 +316,7 @@ int aegis128x4_mac_verify(aegis128x4_state *st_, const uint8_t *mac, size_t macl
*
* This function MUST be used in order to clone states.
*/
void aegis128x4_mac_state_clone(aegis128x4_state *dst, const aegis128x4_state *src);
void aegis128x4_mac_state_clone(aegis128x4_mac_state *dst, const aegis128x4_mac_state *src);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit df189b5

Please sign in to comment.