dualcone 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ #ifdef __SSE2__
2
+ #include "gimli-core/sse2.h"
3
+ #else
4
+ #include "gimli-core/portable.h"
5
+ #endif
6
+
7
+ static void
8
+ gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag)
9
+ {
10
+ state_u8[gimli_BLOCKBYTES - 1] ^= tag;
11
+ #ifndef NATIVE_LITTLE_ENDIAN
12
+ uint32_t state_u32[12];
13
+ int i;
14
+
15
+ for (i = 0; i < 12; i++) {
16
+ state_u32[i] = LOAD32_LE(&state_u8[i * 4]);
17
+ }
18
+ gimli_core(state_u32);
19
+ for (i = 0; i < 12; i++) {
20
+ STORE32_LE(&state_u8[i * 4], state_u32[i]);
21
+ }
22
+ #else
23
+ gimli_core((uint32_t *) (void *) state_u8); /* state_u8 must be properly aligned */
24
+ #endif
25
+ }
@@ -0,0 +1,39 @@
1
+ static void
2
+ gimli_core(uint32_t state[gimli_BLOCKBYTES / 4])
3
+ {
4
+ unsigned int round;
5
+ unsigned int column;
6
+ uint32_t x;
7
+ uint32_t y;
8
+ uint32_t z;
9
+
10
+ for (round = 24; round > 0; round--) {
11
+ for (column = 0; column < 4; column++) {
12
+ x = ROTL32(state[column], 24);
13
+ y = ROTL32(state[4 + column], 9);
14
+ z = state[8 + column];
15
+
16
+ state[8 + column] = x ^ (z << 1) ^ ((y & z) << 2);
17
+ state[4 + column] = y ^ x ^ ((x | z) << 1);
18
+ state[column] = z ^ y ^ ((x & y) << 3);
19
+ }
20
+ switch (round & 3) {
21
+ case 0:
22
+ x = state[0];
23
+ state[0] = state[1];
24
+ state[1] = x;
25
+ x = state[2];
26
+ state[2] = state[3];
27
+ state[3] = x;
28
+ state[0] ^= ((uint32_t) 0x9e377900 | round);
29
+ break;
30
+ case 2:
31
+ x = state[0];
32
+ state[0] = state[2];
33
+ state[2] = x;
34
+ x = state[1];
35
+ state[1] = state[3];
36
+ state[3] = x;
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,100 @@
1
+ #include <emmintrin.h>
2
+ #ifdef __SSSE3__
3
+ # include <tmmintrin.h>
4
+ #endif
5
+
6
+ #define S 9
7
+
8
+ static inline __m128i
9
+ shift(__m128i x, int bits)
10
+ {
11
+ return _mm_slli_epi32(x, bits);
12
+ }
13
+
14
+ static inline __m128i
15
+ rotate(__m128i x, int bits)
16
+ {
17
+ return _mm_slli_epi32(x, bits) | _mm_srli_epi32(x, 32 - bits);
18
+ }
19
+
20
+ #ifdef __SSSE3__
21
+ static inline __m128i
22
+ rotate24(__m128i x)
23
+ {
24
+ return _mm_shuffle_epi8(x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1));
25
+ }
26
+ #else
27
+ static inline __m128i
28
+ rotate24(__m128i x)
29
+ {
30
+ uint8_t _hydro_attr_aligned_(16) x8[16], y8[16];
31
+
32
+ _mm_storeu_si128((__m128i *) (void *) x8, x);
33
+
34
+ y8[ 0] = x8[ 1]; y8[ 1] = x8[ 2]; y8[ 2] = x8[ 3]; y8[ 3] = x8[ 0];
35
+ y8[ 4] = x8[ 5]; y8[ 5] = x8[ 6]; y8[ 6] = x8[ 7]; y8[ 7] = x8[ 4];
36
+ y8[ 8] = x8[ 9]; y8[ 9] = x8[10]; y8[10] = x8[11]; y8[11] = x8[ 8];
37
+ y8[12] = x8[13]; y8[13] = x8[14]; y8[14] = x8[15]; y8[15] = x8[12];
38
+
39
+ return _mm_loadu_si128((const __m128i *) (const void *) y8);
40
+ }
41
+ #endif
42
+
43
+ static const uint32_t coeffs[24] _hydro_attr_aligned_(16) = {
44
+ 0x9e377904, 0, 0, 0, 0x9e377908, 0, 0, 0, 0x9e37790c, 0, 0, 0,
45
+ 0x9e377910, 0, 0, 0, 0x9e377914, 0, 0, 0, 0x9e377918, 0, 0, 0,
46
+ };
47
+
48
+ static void
49
+ gimli_core(uint32_t state[gimli_BLOCKBYTES / 4])
50
+ {
51
+ __m128i x = _mm_loadu_si128((const __m128i *) (const void *) &state[0]);
52
+ __m128i y = _mm_loadu_si128((const __m128i *) (const void *) &state[4]);
53
+ __m128i z = _mm_loadu_si128((const __m128i *) (const void *) &state[8]);
54
+ __m128i newy;
55
+ __m128i newz;
56
+ int round;
57
+
58
+ for (round = 5; round >= 0; round--) {
59
+ x = rotate24(x);
60
+ y = rotate(y, S);
61
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
62
+ newy = y ^ x ^ shift(x | z, 1);
63
+ x = z ^ y ^ shift(x & y, 3);
64
+ y = newy;
65
+ z = newz;
66
+
67
+ x = _mm_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1));
68
+ x ^= ((const __m128i *) (const void *) coeffs)[round];
69
+
70
+ x = rotate24(x);
71
+ y = rotate(y, S);
72
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
73
+ newy = y ^ x ^ shift(x | z, 1);
74
+ x = z ^ y ^ shift(x & y, 3);
75
+ y = newy;
76
+ z = newz;
77
+
78
+ x = rotate24(x);
79
+ y = rotate(y, S);
80
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
81
+ newy = y ^ x ^ shift(x | z, 1);
82
+ x = z ^ y ^ shift(x & y, 3);
83
+ y = newy;
84
+ z = newz;
85
+
86
+ x = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2));
87
+
88
+ x = rotate24(x);
89
+ y = rotate(y, S);
90
+ newz = x ^ shift(z, 1) ^ shift(y & z, 2);
91
+ newy = y ^ x ^ shift(x | z, 1);
92
+ x = z ^ y ^ shift(x & y, 3);
93
+ y = newy;
94
+ z = newz;
95
+ }
96
+
97
+ _mm_storeu_si128((__m128i *) (void *) &state[0], x);
98
+ _mm_storeu_si128((__m128i *) (void *) &state[4], y);
99
+ _mm_storeu_si128((__m128i *) (void *) &state[8], z);
100
+ }
@@ -0,0 +1,140 @@
1
+ int
2
+ hydro_hash_update(hydro_hash_state *state, const void *in_, size_t in_len)
3
+ {
4
+ const uint8_t *in = (const uint8_t *) in_;
5
+ uint8_t * buf = (uint8_t *) (void *) state->state;
6
+ size_t left;
7
+ size_t ps;
8
+ size_t i;
9
+
10
+ while (in_len > 0) {
11
+ left = gimli_RATE - state->buf_off;
12
+ if ((ps = in_len) > left) {
13
+ ps = left;
14
+ }
15
+ for (i = 0; i < ps; i++) {
16
+ buf[state->buf_off + i] ^= in[i];
17
+ }
18
+ in += ps;
19
+ in_len -= ps;
20
+ state->buf_off += (uint8_t) ps;
21
+ if (state->buf_off == gimli_RATE) {
22
+ gimli_core_u8(buf, 0);
23
+ state->buf_off = 0;
24
+ }
25
+ }
26
+ return 0;
27
+ }
28
+
29
+ /* pad(str_enc("kmac") || str_enc(context)) || pad(str_enc(k)) ||
30
+ msg || right_enc(msg_len) || 0x00 */
31
+
32
+ int
33
+ hydro_hash_init(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES],
34
+ const uint8_t key[hydro_hash_KEYBYTES])
35
+ {
36
+ uint8_t block[64] = { 4, 'k', 'm', 'a', 'c', 8 };
37
+ size_t p;
38
+
39
+ COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - gimli_RATE - 1);
40
+ COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8);
41
+ mem_zero(block + 14, sizeof block - 14);
42
+ memcpy(block + 6, ctx, 8);
43
+ if (key != NULL) {
44
+ block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES;
45
+ memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES);
46
+ p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
47
+ } else {
48
+ block[gimli_RATE] = (uint8_t) 0;
49
+ p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
50
+ }
51
+ mem_zero(state, sizeof *state);
52
+ hydro_hash_update(state, block, p);
53
+
54
+ return 0;
55
+ }
56
+
57
+ /* pad(str_enc("tmac") || str_enc(context)) || pad(str_enc(k)) ||
58
+ pad(right_enc(tweak)) || msg || right_enc(msg_len) || 0x00 */
59
+
60
+ static int
61
+ hydro_hash_init_with_tweak(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES],
62
+ uint64_t tweak, const uint8_t key[hydro_hash_KEYBYTES])
63
+ {
64
+ uint8_t block[80] = { 4, 't', 'm', 'a', 'c', 8 };
65
+ size_t p;
66
+
67
+ COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - 2 * gimli_RATE - 1);
68
+ COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8);
69
+ mem_zero(block + 14, sizeof block - 14);
70
+ memcpy(block + 6, ctx, 8);
71
+ if (key != NULL) {
72
+ block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES;
73
+ memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES);
74
+ p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
75
+ } else {
76
+ block[gimli_RATE] = (uint8_t) 0;
77
+ p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t)(gimli_RATE - 1);
78
+ }
79
+ block[p] = (uint8_t) sizeof tweak;
80
+ STORE64_LE(&block[p + 1], tweak);
81
+ p += gimli_RATE;
82
+ mem_zero(state, sizeof *state);
83
+ hydro_hash_update(state, block, p);
84
+
85
+ return 0;
86
+ }
87
+
88
+ int
89
+ hydro_hash_final(hydro_hash_state *state, uint8_t *out, size_t out_len)
90
+ {
91
+ uint8_t lc[4];
92
+ uint8_t *buf = (uint8_t *) (void *) state->state;
93
+ size_t i;
94
+ size_t lc_len;
95
+ size_t leftover;
96
+
97
+ if (out_len < hydro_hash_BYTES_MIN || out_len > hydro_hash_BYTES_MAX) {
98
+ return -1;
99
+ }
100
+ COMPILER_ASSERT(hydro_hash_BYTES_MAX <= 0xffff);
101
+ lc[1] = (uint8_t) out_len;
102
+ lc[2] = (uint8_t)(out_len >> 8);
103
+ lc[3] = 0;
104
+ lc_len = (size_t)(1 + (lc[2] != 0));
105
+ lc[0] = (uint8_t) lc_len;
106
+ hydro_hash_update(state, lc, 1 + lc_len + 1);
107
+ gimli_pad_u8(buf, state->buf_off, gimli_DOMAIN_XOF);
108
+ for (i = 0; i < out_len / gimli_RATE; i++) {
109
+ gimli_core_u8(buf, 0);
110
+ memcpy(out + i * gimli_RATE, buf, gimli_RATE);
111
+ }
112
+ leftover = out_len % gimli_RATE;
113
+ if (leftover != 0) {
114
+ gimli_core_u8(buf, 0);
115
+ mem_cpy(out + i * gimli_RATE, buf, leftover);
116
+ }
117
+ state->buf_off = gimli_RATE;
118
+
119
+ return 0;
120
+ }
121
+
122
+ int
123
+ hydro_hash_hash(uint8_t *out, size_t out_len, const void *in_, size_t in_len,
124
+ const char ctx[hydro_hash_CONTEXTBYTES], const uint8_t key[hydro_hash_KEYBYTES])
125
+ {
126
+ hydro_hash_state st;
127
+ const uint8_t * in = (const uint8_t *) in_;
128
+
129
+ if (hydro_hash_init(&st, ctx, key) != 0 || hydro_hash_update(&st, in, in_len) != 0 ||
130
+ hydro_hash_final(&st, out, out_len) != 0) {
131
+ return -1;
132
+ }
133
+ return 0;
134
+ }
135
+
136
+ void
137
+ hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES])
138
+ {
139
+ hydro_random_buf(key, hydro_hash_KEYBYTES);
140
+ }
@@ -0,0 +1,83 @@
1
+ static int hydro_random_init(void);
2
+
3
+ /* ---------------- */
4
+
5
+ #define gimli_BLOCKBYTES 48
6
+ #define gimli_CAPACITY 32
7
+ #define gimli_RATE 16
8
+
9
+ #define gimli_TAG_HEADER 0x01
10
+ #define gimli_TAG_PAYLOAD 0x02
11
+ #define gimli_TAG_FINAL 0x08
12
+ #define gimli_TAG_FINAL0 0xf8
13
+ #define gimli_TAG_KEY0 0xfe
14
+ #define gimli_TAG_KEY 0xff
15
+
16
+ #define gimli_DOMAIN_AEAD 0x0
17
+ #define gimli_DOMAIN_XOF 0xf
18
+
19
+ static void gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag);
20
+
21
+ static inline void
22
+ gimli_pad_u8(uint8_t buf[gimli_BLOCKBYTES], size_t pos, uint8_t domain)
23
+ {
24
+ buf[pos] ^= (domain << 1) | 1;
25
+ buf[gimli_RATE - 1] ^= 0x80;
26
+ }
27
+
28
+ static inline void
29
+ hydro_mem_ct_zero_u32(uint32_t *dst_, size_t n)
30
+ {
31
+ volatile uint32_t *volatile dst = (volatile uint32_t * volatile)(void *) dst_;
32
+ size_t i;
33
+
34
+ for (i = 0; i < n; i++) {
35
+ dst[i] = 0;
36
+ }
37
+ }
38
+
39
+ static inline uint32_t hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2,
40
+ size_t n) _hydro_attr_warn_unused_result_;
41
+
42
+ static inline uint32_t
43
+ hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2, size_t n)
44
+ {
45
+ const volatile uint32_t *volatile b1 = (const volatile uint32_t *volatile)(const void *) b1_;
46
+ size_t i;
47
+ uint32_t cv = 0;
48
+
49
+ for (i = 0; i < n; i++) {
50
+ cv |= b1[i] ^ b2[i];
51
+ }
52
+ return cv;
53
+ }
54
+
55
+ /* ---------------- */
56
+
57
+ static int hydro_hash_init_with_tweak(hydro_hash_state *state,
58
+ const char ctx[hydro_hash_CONTEXTBYTES], uint64_t tweak,
59
+ const uint8_t key[hydro_hash_KEYBYTES]);
60
+
61
+ /* ---------------- */
62
+
63
+ #define hydro_secretbox_NONCEBYTES 20
64
+ #define hydro_secretbox_MACBYTES 16
65
+
66
+ /* ---------------- */
67
+
68
+ #define hydro_x25519_BYTES 32
69
+ #define hydro_x25519_PUBLICKEYBYTES 32
70
+ #define hydro_x25519_SECRETKEYBYTES 32
71
+
72
+ static int hydro_x25519_scalarmult(uint8_t out[hydro_x25519_BYTES],
73
+ const uint8_t scalar[hydro_x25519_SECRETKEYBYTES],
74
+ const uint8_t x1[hydro_x25519_PUBLICKEYBYTES],
75
+ bool clamp) _hydro_attr_warn_unused_result_;
76
+
77
+ static inline int hydro_x25519_scalarmult_base(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
78
+ const uint8_t sk[hydro_x25519_SECRETKEYBYTES])
79
+ _hydro_attr_warn_unused_result_;
80
+
81
+ static inline void
82
+ hydro_x25519_scalarmult_base_uniform(uint8_t pk[hydro_x25519_PUBLICKEYBYTES],
83
+ const uint8_t sk[hydro_x25519_SECRETKEYBYTES]);
@@ -0,0 +1,20 @@
1
+ int
2
+ hydro_kdf_derive_from_key(uint8_t *subkey, size_t subkey_len, uint64_t subkey_id,
3
+ const char ctx[hydro_kdf_CONTEXTBYTES],
4
+ const uint8_t key[hydro_kdf_KEYBYTES])
5
+ {
6
+ hydro_hash_state st;
7
+
8
+ COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES >= hydro_hash_CONTEXTBYTES);
9
+ COMPILER_ASSERT(hydro_kdf_KEYBYTES >= hydro_hash_KEYBYTES);
10
+ if (hydro_hash_init_with_tweak(&st, ctx, subkey_id, key) != 0) {
11
+ return -1;
12
+ }
13
+ return hydro_hash_final(&st, subkey, subkey_len);
14
+ }
15
+
16
+ void
17
+ hydro_kdf_keygen(uint8_t key[hydro_kdf_KEYBYTES])
18
+ {
19
+ hydro_random_buf(key, hydro_kdf_KEYBYTES);
20
+ }
@@ -0,0 +1,535 @@
1
+ #define hydro_kx_AEAD_KEYBYTES hydro_hash_KEYBYTES
2
+ #define hydro_kx_AEAD_MACBYTES 16
3
+
4
+ #define hydro_kx_CONTEXT "hydro_kx"
5
+
6
+ static void
7
+ hydro_kx_aead_init(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t k[hydro_kx_AEAD_KEYBYTES],
8
+ hydro_kx_state *state)
9
+ {
10
+ static const uint8_t prefix[] = { 6, 'k', 'x', 'x', '2', '5', '6', 0 };
11
+
12
+ hydro_hash_final(&state->h_st, k, hydro_kx_AEAD_KEYBYTES);
13
+
14
+ mem_zero(aead_state + sizeof prefix, gimli_BLOCKBYTES - sizeof prefix);
15
+ memcpy(aead_state, prefix, sizeof prefix);
16
+ gimli_core_u8(aead_state, gimli_TAG_HEADER);
17
+
18
+ COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == 2 * gimli_RATE);
19
+ mem_xor(aead_state, k, gimli_RATE);
20
+ gimli_core_u8(aead_state, gimli_TAG_KEY);
21
+ mem_xor(aead_state, k + gimli_RATE, gimli_RATE);
22
+ gimli_core_u8(aead_state, gimli_TAG_KEY);
23
+ }
24
+
25
+ static void
26
+ hydro_kx_aead_final(uint8_t *aead_state, const uint8_t key[hydro_kx_AEAD_KEYBYTES])
27
+ {
28
+ COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == gimli_CAPACITY);
29
+ mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
30
+ gimli_core_u8(aead_state, gimli_TAG_FINAL);
31
+ mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES);
32
+ gimli_core_u8(aead_state, gimli_TAG_FINAL);
33
+ }
34
+
35
+ static void
36
+ hydro_kx_aead_xor_enc(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
37
+ size_t inlen)
38
+ {
39
+ size_t i;
40
+ size_t leftover;
41
+
42
+ for (i = 0; i < inlen / gimli_RATE; i++) {
43
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE);
44
+ memcpy(aead_state, &out[i * gimli_RATE], gimli_RATE);
45
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
46
+ }
47
+ leftover = inlen % gimli_RATE;
48
+ if (leftover != 0) {
49
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover);
50
+ mem_cpy(aead_state, &out[i * gimli_RATE], leftover);
51
+ }
52
+ gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD);
53
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
54
+ }
55
+
56
+ static void
57
+ hydro_kx_aead_xor_dec(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in,
58
+ size_t inlen)
59
+ {
60
+ size_t i;
61
+ size_t leftover;
62
+
63
+ for (i = 0; i < inlen / gimli_RATE; i++) {
64
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE);
65
+ memcpy(aead_state, &in[i * gimli_RATE], gimli_RATE);
66
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
67
+ }
68
+ leftover = inlen % gimli_RATE;
69
+ if (leftover != 0) {
70
+ mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover);
71
+ mem_cpy(aead_state, &in[i * gimli_RATE], leftover);
72
+ }
73
+ gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD);
74
+ gimli_core_u8(aead_state, gimli_TAG_PAYLOAD);
75
+ }
76
+
77
+ static void
78
+ hydro_kx_aead_encrypt(hydro_kx_state *state, uint8_t *c, const uint8_t *m, size_t mlen)
79
+ {
80
+ _hydro_attr_aligned_(16) uint8_t aead_state[gimli_BLOCKBYTES];
81
+ uint8_t k[hydro_kx_AEAD_KEYBYTES];
82
+ uint8_t * mac = &c[0];
83
+ uint8_t * ct = &c[hydro_kx_AEAD_MACBYTES];
84
+
85
+ hydro_kx_aead_init(aead_state, k, state);
86
+ hydro_kx_aead_xor_enc(aead_state, ct, m, mlen);
87
+ hydro_kx_aead_final(aead_state, k);
88
+ COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
89
+ memcpy(mac, aead_state + gimli_RATE, hydro_kx_AEAD_MACBYTES);
90
+ hydro_hash_update(&state->h_st, c, mlen + hydro_kx_AEAD_MACBYTES);
91
+ }
92
+
93
+ static int hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c,
94
+ size_t clen) _hydro_attr_warn_unused_result_;
95
+
96
+ static int
97
+ hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c, size_t clen)
98
+ {
99
+ _hydro_attr_aligned_(16) uint32_t int_state[gimli_BLOCKBYTES / 4];
100
+ uint32_t pub_mac[hydro_kx_AEAD_MACBYTES / 4];
101
+ uint8_t k[hydro_kx_AEAD_KEYBYTES];
102
+ uint8_t * aead_state = (uint8_t *) (void *) int_state;
103
+ const uint8_t * mac;
104
+ const uint8_t * ct;
105
+ size_t mlen;
106
+ uint32_t cv;
107
+
108
+ if (clen < hydro_kx_AEAD_MACBYTES) {
109
+ return -1;
110
+ }
111
+ mac = &c[0];
112
+ ct = &c[hydro_kx_AEAD_MACBYTES];
113
+ mlen = clen - hydro_kx_AEAD_MACBYTES;
114
+ memcpy(pub_mac, mac, sizeof pub_mac);
115
+ hydro_kx_aead_init(aead_state, k, state);
116
+ hydro_hash_update(&state->h_st, c, clen);
117
+ hydro_kx_aead_xor_dec(aead_state, m, ct, mlen);
118
+ hydro_kx_aead_final(aead_state, k);
119
+ COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY);
120
+ COMPILER_ASSERT(gimli_RATE % 4 == 0);
121
+ cv = hydro_mem_ct_cmp_u32(int_state + gimli_RATE / 4, pub_mac, hydro_kx_AEAD_MACBYTES / 4);
122
+ hydro_mem_ct_zero_u32(int_state, gimli_BLOCKBYTES / 4);
123
+ if (cv != 0) {
124
+ mem_zero(m, mlen);
125
+ return -1;
126
+ }
127
+ return 0;
128
+ }
129
+
130
+ /* -- */
131
+
132
+ void
133
+ hydro_kx_keygen(hydro_kx_keypair *static_kp)
134
+ {
135
+ hydro_random_buf(static_kp->sk, hydro_kx_SECRETKEYBYTES);
136
+ if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
137
+ abort();
138
+ }
139
+ }
140
+
141
+ void
142
+ hydro_kx_keygen_deterministic(hydro_kx_keypair *static_kp, const uint8_t seed[hydro_kx_SEEDBYTES])
143
+ {
144
+ COMPILER_ASSERT(hydro_kx_SEEDBYTES >= hydro_random_SEEDBYTES);
145
+ hydro_random_buf_deterministic(static_kp->sk, hydro_kx_SECRETKEYBYTES, seed);
146
+ if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) {
147
+ abort();
148
+ }
149
+ }
150
+
151
+ static void
152
+ hydro_kx_init_state(hydro_kx_state *state, const char *name)
153
+ {
154
+ mem_zero(state, sizeof *state);
155
+ hydro_hash_init(&state->h_st, hydro_kx_CONTEXT, NULL);
156
+ hydro_hash_update(&state->h_st, name, strlen(name));
157
+ hydro_hash_final(&state->h_st, NULL, 0);
158
+ }
159
+
160
+ static void
161
+ hydro_kx_final(hydro_kx_state *state, uint8_t session_k1[hydro_kx_SESSIONKEYBYTES],
162
+ uint8_t session_k2[hydro_kx_SESSIONKEYBYTES])
163
+ {
164
+ uint8_t kdf_key[hydro_kdf_KEYBYTES];
165
+
166
+ hydro_hash_final(&state->h_st, kdf_key, sizeof kdf_key);
167
+ hydro_kdf_derive_from_key(session_k1, hydro_kx_SESSIONKEYBYTES, 0, hydro_kx_CONTEXT, kdf_key);
168
+ hydro_kdf_derive_from_key(session_k2, hydro_kx_SESSIONKEYBYTES, 1, hydro_kx_CONTEXT, kdf_key);
169
+ }
170
+
171
+ static int
172
+ hydro_kx_dh(hydro_kx_state *state, const uint8_t sk[hydro_x25519_SECRETKEYBYTES],
173
+ const uint8_t pk[hydro_x25519_PUBLICKEYBYTES])
174
+ {
175
+ uint8_t dh_result[hydro_x25519_BYTES];
176
+
177
+ if (hydro_x25519_scalarmult(dh_result, sk, pk, 1) != 0) {
178
+ return -1;
179
+ }
180
+ hydro_hash_update(&state->h_st, dh_result, hydro_x25519_BYTES);
181
+
182
+ return 0;
183
+ }
184
+
185
+ static void
186
+ hydro_kx_eph_keygen(hydro_kx_state *state, hydro_kx_keypair *kp)
187
+ {
188
+ hydro_kx_keygen(kp);
189
+ hydro_hash_update(&state->h_st, kp->pk, sizeof kp->pk);
190
+ }
191
+
192
+ /* NOISE_N */
193
+
194
+ int
195
+ hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET1BYTES],
196
+ const uint8_t psk[hydro_kx_PSKBYTES],
197
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
198
+ {
199
+ hydro_kx_state state;
200
+ uint8_t * packet1_eph_pk = &packet1[0];
201
+ uint8_t * packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
202
+
203
+ if (psk == NULL) {
204
+ psk = zero;
205
+ }
206
+ hydro_kx_init_state(&state, "Noise_Npsk0_hydro1");
207
+ hydro_hash_update(&state.h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES);
208
+
209
+ hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
210
+ hydro_kx_eph_keygen(&state, &state.eph_kp);
211
+ if (hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) {
212
+ return -1;
213
+ }
214
+ hydro_kx_aead_encrypt(&state, packet1_mac, NULL, 0);
215
+ memcpy(packet1_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
216
+
217
+ hydro_kx_final(&state, kp->rx, kp->tx);
218
+
219
+ return 0;
220
+ }
221
+
222
+ int
223
+ hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES],
224
+ const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp)
225
+ {
226
+ hydro_kx_state state;
227
+ const uint8_t *peer_eph_pk = &packet1[0];
228
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
229
+
230
+ if (psk == NULL) {
231
+ psk = zero;
232
+ }
233
+ hydro_kx_init_state(&state, "Noise_Npsk0_hydro1");
234
+ hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
235
+
236
+ hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
237
+ hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
238
+ if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
239
+ hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
240
+ return -1;
241
+ }
242
+ hydro_kx_final(&state, kp->tx, kp->rx);
243
+
244
+ return 0;
245
+ }
246
+
247
+ /* NOISE_KK */
248
+
249
+ int
250
+ hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
251
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
252
+ const hydro_kx_keypair *static_kp)
253
+ {
254
+ uint8_t *packet1_eph_pk = &packet1[0];
255
+ uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
256
+
257
+ hydro_kx_init_state(state, "Noise_KK_hydro1");
258
+ hydro_hash_update(&state->h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
259
+ hydro_hash_update(&state->h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES);
260
+
261
+ hydro_kx_eph_keygen(state, &state->eph_kp);
262
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 ||
263
+ hydro_kx_dh(state, static_kp->sk, peer_static_pk) != 0) {
264
+ return -1;
265
+ }
266
+ hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
267
+ memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
268
+
269
+ return 0;
270
+ }
271
+
272
+ int
273
+ hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
274
+ const uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
275
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
276
+ const hydro_kx_keypair *static_kp)
277
+ {
278
+ hydro_kx_state state;
279
+ const uint8_t *peer_eph_pk = &packet1[0];
280
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
281
+ uint8_t * packet2_eph_pk = &packet2[0];
282
+ uint8_t * packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
283
+
284
+ hydro_kx_init_state(&state, "Noise_KK_hydro1");
285
+ hydro_hash_update(&state.h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES);
286
+ hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
287
+
288
+ hydro_hash_update(&state.h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
289
+ if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
290
+ hydro_kx_dh(&state, static_kp->sk, peer_static_pk) != 0 ||
291
+ hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
292
+ return -1;
293
+ }
294
+
295
+ hydro_kx_eph_keygen(&state, &state.eph_kp);
296
+ if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0 ||
297
+ hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) {
298
+ return -1;
299
+ }
300
+ hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0);
301
+ hydro_kx_final(&state, kp->tx, kp->rx);
302
+ memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
303
+
304
+ return 0;
305
+ }
306
+
307
+ int
308
+ hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
309
+ const uint8_t packet2[hydro_kx_KK_PACKET2BYTES], const hydro_kx_keypair *static_kp)
310
+ {
311
+ const uint8_t *peer_eph_pk = packet2;
312
+ const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
313
+
314
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
315
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
316
+ hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
317
+ return -1;
318
+ }
319
+
320
+ if (hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
321
+ return -1;
322
+ }
323
+ hydro_kx_final(state, kp->rx, kp->tx);
324
+
325
+ return 0;
326
+ }
327
+
328
+ /* NOISE_XX */
329
+
330
+ int
331
+ hydro_kx_xx_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_XX_PACKET1BYTES],
332
+ const uint8_t psk[hydro_kx_PSKBYTES])
333
+ {
334
+ uint8_t *packet1_eph_pk = &packet1[0];
335
+ uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
336
+
337
+ if (psk == NULL) {
338
+ psk = zero;
339
+ }
340
+ hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1");
341
+
342
+ hydro_kx_eph_keygen(state, &state->eph_kp);
343
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
344
+ memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
345
+ hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
346
+
347
+ return 0;
348
+ }
349
+
350
+ int
351
+ hydro_kx_xx_2(hydro_kx_state *state, uint8_t packet2[hydro_kx_XX_PACKET2BYTES],
352
+ const uint8_t packet1[hydro_kx_XX_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
353
+ const hydro_kx_keypair *static_kp)
354
+ {
355
+ const uint8_t *peer_eph_pk = &packet1[0];
356
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
357
+ uint8_t * packet2_eph_pk = &packet2[0];
358
+ uint8_t * packet2_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES];
359
+ uint8_t * packet2_mac =
360
+ &packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
361
+
362
+ if (psk == NULL) {
363
+ psk = zero;
364
+ }
365
+ hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1");
366
+
367
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
368
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
369
+ if (hydro_kx_aead_decrypt(state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
370
+ return -1;
371
+ }
372
+
373
+ hydro_kx_eph_keygen(state, &state->eph_kp);
374
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0) {
375
+ return -1;
376
+ }
377
+ hydro_kx_aead_encrypt(state, packet2_enc_static_pk, static_kp->pk, sizeof static_kp->pk);
378
+ if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
379
+ return -1;
380
+ }
381
+ hydro_kx_aead_encrypt(state, packet2_mac, NULL, 0);
382
+
383
+ memcpy(packet2_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
384
+
385
+ return 0;
386
+ }
387
+
388
+ int
389
+ hydro_kx_xx_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
390
+ uint8_t packet3[hydro_kx_XX_PACKET3BYTES],
391
+ uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
392
+ const uint8_t packet2[hydro_kx_XX_PACKET2BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
393
+ const hydro_kx_keypair *static_kp)
394
+ {
395
+ uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
396
+ const uint8_t *peer_eph_pk = &packet2[0];
397
+ const uint8_t *peer_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES];
398
+ const uint8_t *packet2_mac =
399
+ &packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
400
+ uint8_t *packet3_enc_static_pk = &packet3[0];
401
+ uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
402
+
403
+ if (psk == NULL) {
404
+ psk = zero;
405
+ }
406
+ if (peer_static_pk == NULL) {
407
+ peer_static_pk = peer_static_pk_;
408
+ }
409
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES);
410
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
411
+ hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk,
412
+ hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 ||
413
+ hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 ||
414
+ hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
415
+ return -1;
416
+ }
417
+
418
+ hydro_kx_aead_encrypt(state, packet3_enc_static_pk, static_kp->pk, sizeof static_kp->pk);
419
+ if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) {
420
+ return -1;
421
+ }
422
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
423
+ hydro_kx_aead_encrypt(state, packet3_mac, NULL, 0);
424
+ hydro_kx_final(state, kp->rx, kp->tx);
425
+
426
+ return 0;
427
+ }
428
+
429
+ int
430
+ hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp,
431
+ uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES],
432
+ const uint8_t packet3[hydro_kx_XX_PACKET3BYTES], const uint8_t psk[hydro_kx_PSKBYTES])
433
+ {
434
+ uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES];
435
+ const uint8_t *peer_enc_static_pk = &packet3[0];
436
+ const uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES];
437
+
438
+ if (psk == NULL) {
439
+ psk = zero;
440
+ }
441
+ if (peer_static_pk == NULL) {
442
+ peer_static_pk = peer_static_pk_;
443
+ }
444
+ if (hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk,
445
+ hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 ||
446
+ hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) {
447
+ return -1;
448
+ }
449
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
450
+ if (hydro_kx_aead_decrypt(state, NULL, packet3_mac, hydro_kx_AEAD_MACBYTES) != 0) {
451
+ return -1;
452
+ }
453
+ hydro_kx_final(state, kp->tx, kp->rx);
454
+
455
+ return 0;
456
+ }
457
+
458
+ /* NOISE_NK */
459
+
460
+ int
461
+ hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
462
+ const uint8_t psk[hydro_kx_PSKBYTES],
463
+ const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
464
+ {
465
+ uint8_t *packet1_eph_pk = &packet1[0];
466
+ uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
467
+
468
+ if (psk == NULL) {
469
+ psk = zero;
470
+ }
471
+ hydro_kx_init_state(state, "Noise_NKpsk0_hydro1");
472
+ hydro_hash_update(&state->h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES);
473
+
474
+ hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
475
+ hydro_kx_eph_keygen(state, &state->eph_kp);
476
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) {
477
+ return -1;
478
+ }
479
+ hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
480
+ memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);
481
+
482
+ return 0;
483
+ }
484
+
485
+ int
486
+ hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES],
487
+ const uint8_t packet1[hydro_kx_NK_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
488
+ const hydro_kx_keypair *static_kp)
489
+ {
490
+ hydro_kx_state state;
491
+ const uint8_t *peer_eph_pk = &packet1[0];
492
+ const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
493
+ uint8_t * packet2_eph_pk = &packet2[0];
494
+ uint8_t * packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
495
+
496
+ if (psk == NULL) {
497
+ psk = zero;
498
+ }
499
+ hydro_kx_init_state(&state, "Noise_NKpsk0_hydro1");
500
+ hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);
501
+
502
+ hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
503
+ hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
504
+ if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
505
+ hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
506
+ return -1;
507
+ }
508
+
509
+ hydro_kx_eph_keygen(&state, &state.eph_kp);
510
+ if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0) {
511
+ return -1;
512
+ }
513
+ hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0);
514
+ hydro_kx_final(&state, kp->tx, kp->rx);
515
+ memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);
516
+
517
+ return 0;
518
+ }
519
+
520
+ int
521
+ hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
522
+ const uint8_t packet2[hydro_kx_NK_PACKET2BYTES])
523
+ {
524
+ const uint8_t *peer_eph_pk = &packet2[0];
525
+ const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];
526
+
527
+ hydro_hash_update(&state->h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
528
+ if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
529
+ hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
530
+ return -1;
531
+ }
532
+ hydro_kx_final(state, kp->rx, kp->tx);
533
+
534
+ return 0;
535
+ }