diff options
| -rw-r--r-- | crypto_aead/lilliputaeii128v1/ref/Makefile | 2 | ||||
| -rw-r--r-- | src/ae-common.h | 19 | ||||
| -rw-r--r-- | src/lilliput-ae-ii.c | 89 |
3 files changed, 82 insertions, 28 deletions
diff --git a/crypto_aead/lilliputaeii128v1/ref/Makefile b/crypto_aead/lilliputaeii128v1/ref/Makefile index 90f2a75..ab18c62 100644 --- a/crypto_aead/lilliputaeii128v1/ref/Makefile +++ b/crypto_aead/lilliputaeii128v1/ref/Makefile @@ -39,5 +39,3 @@ results/src/tweakey.o: src/tweakey.h src/constants.h parameters.h # TODO: should add order-only prerequisites to remove mkdirs inside recipes # TODO: add valgrind, although it does not seem to play well with ASAN # TODO: should use gcc -M... to generate .o -> .h dependencies - -results/src/lilliput-ae-ii.o: CFLAGS += -Wno-unused # FIXME: remove once implemented diff --git a/src/ae-common.h b/src/ae-common.h index da5d04d..561854e 100644 --- a/src/ae-common.h +++ b/src/ae-common.h @@ -65,26 +65,23 @@ static inline void pad10(size_t X_len, const uint8_t X[X_len], uint8_t padded[BL } } -static inline void _fill_ad_tweak( +static inline void fill_index_tweak( uint8_t prefix, - uint64_t block_nb, + uint64_t block_index, uint8_t tweak[TWEAK_BYTES] ) { /* The t-bit tweak is filled as follows: * - * - bits [ 1, t-4]: block number - * [ 1, 64]: actual 64-bit block number + * - bits [ 1, t-4]: block index + * [ 1, 64]: actual 64-bit block index * [ 65, t-4]: 0-padding * - bits [t-3, t]: constant 4-bit prefix */ - for (size_t i=0; i<sizeof(block_nb); i++) + for (size_t i=0; i<sizeof(block_index); i++) { - uint64_t mask = (uint64_t)0xff << 8*i; - uint8_t b = (mask & block_nb) >> 8*i; - - tweak[i] = b; + tweak[i] = block_index >> 8*i & 0xff; } /* Assume padding bytes have already been memset to 0. */ @@ -110,7 +107,7 @@ static void process_associated_data( for (size_t i=0; i<l_a; i++) { - _fill_ad_tweak(0x2, i, tweak); + fill_index_tweak(0x2, i, tweak); encrypt(key, tweak, &A[i*BLOCK_BYTES], Ek_Ai); xor_into(Auth, Ek_Ai); } @@ -119,7 +116,7 @@ static void process_associated_data( { uint8_t A_rest[BLOCK_BYTES]; pad10(rest, &A[l_a*BLOCK_BYTES], A_rest); - _fill_ad_tweak(0x6, l_a, tweak); + fill_index_tweak(0x6, l_a, tweak); encrypt(key, tweak, A_rest, Ek_Ai); xor_into(Auth, Ek_Ai); } diff --git a/src/lilliput-ae-ii.c b/src/lilliput-ae-ii.c index fc50211..e0e268e 100644 --- a/src/lilliput-ae-ii.c +++ b/src/lilliput-ae-ii.c @@ -7,16 +7,62 @@ #include "lilliput-ae.h" +static void _init_msg_tweak(const uint8_t tag[TAG_BYTES], uint8_t tweak[TWEAK_BYTES]) +{ + /* The t-bit tweak is filled as follows: + * + * - bits [ 1, t-1]: tag + block index + * [ 1, 64]: tag[ 1.. 64] XOR block index + * [ 65, t-1]: tag[65..t-1] + * - bit t: 1 + */ + + memcpy(tweak+sizeof(uint64_t), tag+sizeof(uint64_t), TAG_BYTES-sizeof(uint64_t)); + tweak[TWEAK_BYTES-1] |= 0x80; +} + +static void _fill_msg_tweak(const uint8_t tag[TAG_BYTES], uint64_t block_index, uint8_t tweak[TWEAK_BYTES]) +{ + /* Assume bits 65 to t-1 are set. */ + for (size_t i=0; i<sizeof(block_index); i++) + { + uint8_t index_i = block_index >> i*8 & 0xff; + tweak[i] = tag[i] ^ index_i; + } +} static void _generate_tag( const uint8_t key[KEY_BYTES], size_t M_len, const uint8_t M[M_len], - const uint8_t N[NONCE_BYTES], const uint8_t Auth[BLOCK_BYTES], uint8_t tag[TAG_BYTES] ) { + uint8_t Ek_Mj[BLOCK_BYTES]; + uint8_t tweak[TWEAK_BYTES]; + memset(tweak, 0, TWEAK_BYTES); + + memcpy(tag, Auth, TAG_BYTES); + + size_t l = M_len / BLOCK_BYTES; + size_t rest = M_len % BLOCK_BYTES; + + for (size_t j=0; j<l; j++) + { + fill_index_tweak(0x0, j, tweak); + encrypt(key, tweak, &M[j*BLOCK_BYTES], Ek_Mj); + xor_into(tag, Ek_Mj); + } + + if (rest != 0) + { + uint8_t M_rest[BLOCK_BYTES]; + pad10(rest, &M[l*BLOCK_BYTES], M_rest); + fill_index_tweak(0x4, l, tweak); + encrypt(key, tweak, M_rest, Ek_Mj); + xor_into(tag, Ek_Mj); + } } static void _encrypt_message( @@ -28,19 +74,32 @@ static void _encrypt_message( uint8_t C[M_len] ) { -} + uint8_t Ek_N[BLOCK_BYTES]; -static void _decrypt_message( - const uint8_t key[KEY_BYTES], - size_t C_len, - const uint8_t C[C_len], - const uint8_t N[NONCE_BYTES], - const uint8_t tag[TAG_BYTES], - uint8_t M[C_len] -) -{ -} + uint8_t tweak[TWEAK_BYTES]; + _init_msg_tweak(tag, tweak); + + uint8_t padded_N[BLOCK_BYTES]; + memcpy(padded_N, N, NONCE_BYTES); + padded_N[BLOCK_BYTES-1] = 0; + + size_t l = M_len / BLOCK_BYTES; + size_t rest = M_len % BLOCK_BYTES; + for (size_t j=0; j<l; j++) + { + _fill_msg_tweak(tag, j, tweak); + encrypt(key, tweak, padded_N, Ek_N); + xor_arrays(BLOCK_BYTES, &C[j*BLOCK_BYTES], &M[j*BLOCK_BYTES], Ek_N); + } + + if (rest != 0) + { + _fill_msg_tweak(tag, l, tweak); + encrypt(key, tweak, padded_N, Ek_N); + xor_arrays(rest, &C[l*BLOCK_BYTES], &M[l*BLOCK_BYTES], Ek_N); + } +} void lilliput_ae_encrypt( size_t message_len, @@ -56,7 +115,7 @@ void lilliput_ae_encrypt( uint8_t auth[BLOCK_BYTES]; process_associated_data(key, auth_data_len, auth_data, auth); - _generate_tag(key, message_len, message, nonce, auth, tag); + _generate_tag(key, message_len, message, auth, tag); _encrypt_message(key, message_len, message, nonce, tag, ciphertext); } @@ -72,13 +131,13 @@ bool lilliput_ae_decrypt( uint8_t message[ciphertext_len] ) { - _decrypt_message(key, ciphertext_len, ciphertext, nonce, tag, message); + _encrypt_message(key, ciphertext_len, ciphertext, nonce, tag, message); uint8_t auth[BLOCK_BYTES]; process_associated_data(key, auth_data_len, auth_data, auth); uint8_t effective_tag[TAG_BYTES]; - _generate_tag(key, ciphertext_len, message, nonce, auth, effective_tag); + _generate_tag(key, ciphertext_len, message, auth, effective_tag); return memcmp(tag, effective_tag, TAG_BYTES) == 0; } |
