diff options
| author | Kévin Le Gouguec <kevin.legouguec@airbus.com> | 2019-02-05 08:00:53 +0100 |
|---|---|---|
| committer | Kévin Le Gouguec <kevin.legouguec@airbus.com> | 2019-02-05 08:00:53 +0100 |
| commit | a5cd17702c6a8178c228f10372637fa376d018c8 (patch) | |
| tree | 938cdd49f5cb483df48927366a1ecd3049b59567 /src/add_tweakeysequences/lilliput-ae-ii.c | |
| parent | af531ef71e68e98d1eee4fdefb30b3f2e8cd83c4 (diff) | |
| download | lilliput-ae-implem-a5cd17702c6a8178c228f10372637fa376d018c8.tar.xz | |
Changement de l'implémentation de référence
Diffstat (limited to 'src/add_tweakeysequences/lilliput-ae-ii.c')
| -rw-r--r-- | src/add_tweakeysequences/lilliput-ae-ii.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/add_tweakeysequences/lilliput-ae-ii.c b/src/add_tweakeysequences/lilliput-ae-ii.c new file mode 100644 index 0000000..26885e5 --- /dev/null +++ b/src/add_tweakeysequences/lilliput-ae-ii.c @@ -0,0 +1,160 @@ +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include "ae-common.h" +#include "cipher.h" +#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 _fill_tag_tweak(const uint8_t N[NONCE_BYTES], uint8_t tweak[TWEAK_BYTES]) +{ + /* The t-bit tweak is filled as follows: + * + * - bits [ 1, t-7]: N + * - bits [t-7, t]: 0001||0^4 + */ + + memcpy(tweak, N, TWEAK_BYTES-1); + tweak[TWEAK_BYTES-1] = 0x10; +} + +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 tag_tmp[TAG_BYTES]; + uint8_t tweak[TWEAK_BYTES]; + + memset(tweak, 0, TWEAK_BYTES); + memcpy(tag_tmp, 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_tmp, 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_tmp, Ek_Mj); + } + + _fill_tag_tweak(N, tweak); + encrypt(key, tweak, tag_tmp, tag); +} + +static void _encrypt_message( + 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 tag[TAG_BYTES], + uint8_t C[M_len] +) +{ + uint8_t Ek_N[BLOCK_BYTES]; + + 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, + const uint8_t message[message_len], + size_t auth_data_len, + const uint8_t auth_data[auth_data_len], + const uint8_t key[KEY_BYTES], + const uint8_t nonce[NONCE_BYTES], + uint8_t ciphertext[message_len], + uint8_t tag[TAG_BYTES] +) +{ + uint8_t auth[BLOCK_BYTES]; + process_associated_data(key, auth_data_len, auth_data, auth); + + _generate_tag(key, message_len, message, nonce, auth, tag); + + _encrypt_message(key, message_len, message, nonce, tag, ciphertext); +} + +bool lilliput_ae_decrypt( + size_t ciphertext_len, + const uint8_t ciphertext[ciphertext_len], + size_t auth_data_len, + const uint8_t auth_data[auth_data_len], + const uint8_t key[KEY_BYTES], + const uint8_t nonce[NONCE_BYTES], + const uint8_t tag[TAG_BYTES], + uint8_t message[ciphertext_len] +) +{ + _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); + + return memcmp(tag, effective_tag, TAG_BYTES) == 0; +} |
