summaryrefslogtreecommitdiff
path: root/src/add_tweakeysequences/lilliput-ae-ii.c
diff options
context:
space:
mode:
authorKévin Le Gouguec <kevin.legouguec@airbus.com>2019-02-05 08:00:53 +0100
committerKévin Le Gouguec <kevin.legouguec@airbus.com>2019-02-05 08:00:53 +0100
commita5cd17702c6a8178c228f10372637fa376d018c8 (patch)
tree938cdd49f5cb483df48927366a1ecd3049b59567 /src/add_tweakeysequences/lilliput-ae-ii.c
parentaf531ef71e68e98d1eee4fdefb30b3f2e8cd83c4 (diff)
downloadlilliput-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.c160
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;
+}