ASCON Suite
ascon-aead-masked-128.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2021 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
24 #include "core/ascon-util-snp.h"
25 
26 /* Initialization vector for ASCON-128 */
27 static uint8_t const ASCON128_IV[8] =
28  {0x80, 0x40, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00};
29 
30 /* Absorb the key and nonce, and then convert the state from the
31  * number of key shares into the number of data shares */
32 static void ascon128_masked_aead_init
35  ascon_state_t *state_x1,
36 #endif
38  uint64_t *preserve, const unsigned char *npub,
39  const ascon_masked_key_128_t *k)
40 {
41  /* Generate random words for use in permutation calls */
42 #if ASCON_MASKED_KEY_SHARES == 2
43  preserve[0] = ascon_trng_generate_64(trng);
44 #elif ASCON_MASKED_KEY_SHARES == 3
45  preserve[0] = ascon_trng_generate_64(trng);
46  preserve[1] = ascon_trng_generate_64(trng);
47 #else
48  preserve[0] = ascon_trng_generate_64(trng);
49  preserve[1] = ascon_trng_generate_64(trng);
50  preserve[2] = ascon_trng_generate_64(trng);
51 #endif
52 
53  /* Format the key and nonce into the initial state */
55  ascon_masked_key_randomize(state, trng);
56  ascon_masked_key_load(word, ASCON128_IV, trng);
57  ascon_masked_key_xor(&(state->M[0]), word);
58  ascon_masked_key_xor(&(state->M[1]), &(k->k[0]));
59  ascon_masked_key_xor(&(state->M[2]), &(k->k[1]));
60  ascon_masked_key_load(word, npub, trng);
61  ascon_masked_key_xor(&(state->M[3]), word);
62  ascon_masked_key_load(word, npub + 8, trng);
63  ascon_masked_key_xor(&(state->M[4]), word);
64  ascon_masked_key_permute(state, 0, preserve);
65  ascon_masked_key_xor(&(state->M[3]), &(k->k[0]));
66  ascon_masked_key_xor(&(state->M[4]), &(k->k[1]));
67 
68  /* Convert the key shares form into the data shares form */
69 #if ASCON_MASKED_DATA_SHARES == 1
70  ascon_copy_key_to_x1(state_x1, state);
71 #elif ASCON_MASKED_DATA_SHARES == 2
72  ascon_copy_key_to_x2(state, trng);
73 #elif ASCON_MASKED_DATA_SHARES == 3
74  ascon_copy_key_to_x3(state, trng);
75 #else
76  ascon_copy_key_to_x4(state, trng);
77 #endif
78 }
79 
80 /* Finalize and generate the authentication tag in the state */
81 static void ascon128_masked_aead_finalize
84  ascon_state_t *state_x1,
85 #endif
86  ascon_trng_state_t *trng, uint64_t *preserve,
87  const ascon_masked_key_128_t *k, unsigned char *tag)
88 {
89  /* Refresh the randomness for the final permutation call */
90 #if ASCON_MASKED_KEY_SHARES == 2
91  preserve[0] = ascon_trng_generate_64(trng);
92 #elif ASCON_MASKED_KEY_SHARES == 3
93  preserve[0] = ascon_trng_generate_64(trng);
94  preserve[1] = ascon_trng_generate_64(trng);
95 #else
96  preserve[0] = ascon_trng_generate_64(trng);
97  preserve[1] = ascon_trng_generate_64(trng);
98  preserve[2] = ascon_trng_generate_64(trng);
99 #endif
100 
101  /* Convert the data shares form back into the key shares form */
102 #if ASCON_MASKED_DATA_SHARES == 1
103  ascon_copy_key_from_x1(state, state_x1, trng);
104 #elif ASCON_MASKED_DATA_SHARES == 2
105  ascon_copy_key_from_x2(state, trng);
106 #elif ASCON_MASKED_DATA_SHARES == 3
107  ascon_copy_key_from_x3(state, trng);
108 #else
109  ascon_copy_key_from_x4(state, trng);
110 #endif
111 
112  /* Finalize the state and generate the tag */
113  ascon_masked_key_xor(&(state->M[1]), &(k->k[0]));
114  ascon_masked_key_xor(&(state->M[2]), &(k->k[1]));
115  ascon_masked_key_permute(state, 0, preserve);
116  ascon_masked_key_xor(&(state->M[3]), &(k->k[0]));
117  ascon_masked_key_xor(&(state->M[4]), &(k->k[1]));
118  ascon_masked_key_store(tag, &(state->M[3]));
119  ascon_masked_key_store(tag + 8, &(state->M[4]));
120 }
121 
123  (unsigned char *c, size_t *clen,
124  const unsigned char *m, size_t mlen,
125  const unsigned char *ad, size_t adlen,
126  const unsigned char *npub,
127  const ascon_masked_key_128_t *k)
128 {
130 #if ASCON_MASKED_DATA_SHARES == 1
131  ascon_state_t state_x1;
132  unsigned char partial;
133 #endif
134  ascon_trng_state_t trng;
135  ascon_masked_word_t word;
136  uint64_t preserve[ASCON_MASKED_KEY_SHARES - 1];
137 
138  /* Set the length of the returned ciphertext */
139  *clen = mlen + ASCON128_TAG_SIZE;
140 
141  /* Initialize the random number generator */
142  ascon_trng_init(&trng);
143 
144 #if ASCON_MASKED_DATA_SHARES == 1
145  /* Initialize the ASCON state */
146  ascon128_masked_aead_init
147  (&state, &state_x1, &trng, &word, preserve, npub, k);
148 
149  /* Absorb the associated data into the state */
150  if (adlen > 0)
151  ascon_aead_absorb_8(&state_x1, ad, adlen, 6, 1);
152 
153  /* Separator between the associated data and the payload */
154  ascon_separator(&state_x1);
155 
156  /* Encrypt the plaintext to create the ciphertext */
157  partial = ascon_aead_encrypt_8(&state_x1, c, m, mlen, 6, 0);
158  ascon_pad(&state_x1, partial);
159 
160  /* Convert the state back into key masked form and finalize */
161  ascon128_masked_aead_finalize
162  (&state, &state_x1, &trng, preserve, k, c + mlen);
163 #else
164  /* Initialize the ASCON state */
165  ascon128_masked_aead_init(&state, &trng, &word, preserve, npub, k);
166 
167  /* Absorb the associated data into the state */
168  if (adlen > 0) {
170  (&state, ad, adlen, 6, &word, preserve, &trng);
171  }
172 
173  /* Separator between the associated data and the payload */
175 
176  /* Encrypt the plaintext to create the ciphertext */
178  (&state, c, m, mlen, 6, &word, preserve, &trng);
179 
180  /* Convert the state back into key masked form and finalize */
181  ascon128_masked_aead_finalize(&state, &trng, preserve, k, c + mlen);
182 #endif
183 
184  /* Clean up */
185 #if ASCON_MASKED_DATA_SHARES == 1
186  ascon_free(&state_x1);
187 #endif
189  ascon_clean(&word, sizeof(word));
190  ascon_clean(preserve, sizeof(preserve));
191  ascon_trng_free(&trng);
192 }
193 
195  (unsigned char *m, size_t *mlen,
196  const unsigned char *c, size_t clen,
197  const unsigned char *ad, size_t adlen,
198  const unsigned char *npub,
199  const ascon_masked_key_128_t *k)
200 {
202 #if ASCON_MASKED_DATA_SHARES == 1
203  ascon_state_t state_x1;
204  unsigned char partial;
205 #endif
206  ascon_trng_state_t trng;
207  ascon_masked_word_t word;
208  uint64_t preserve[ASCON_MASKED_KEY_SHARES - 1];
209  unsigned char tag[ASCON128_TAG_SIZE];
210  int result;
211 
212  /* Set the length of the returned plaintext */
213  if (clen < ASCON128_TAG_SIZE)
214  return -1;
215  *mlen = clen - ASCON128_TAG_SIZE;
216 
217  /* Initialize the random number generator */
218  ascon_trng_init(&trng);
219 
220 #if ASCON_MASKED_DATA_SHARES == 1
221  /* Initialize the ASCON state */
222  ascon128_masked_aead_init
223  (&state, &state_x1, &trng, &word, preserve, npub, k);
224 
225  /* Absorb the associated data into the state */
226  if (adlen > 0)
227  ascon_aead_absorb_8(&state_x1, ad, adlen, 6, 1);
228 
229  /* Separator between the associated data and the payload */
230  ascon_separator(&state_x1);
231 
232  /* Decrypt the ciphertext to create the plaintext */
233  partial = ascon_aead_decrypt_8(&state_x1, m, c, *mlen, 6, 0);
234  ascon_pad(&state_x1, partial);
235 
236  /* Convert the state back into key masked form and finalize */
237  ascon128_masked_aead_finalize(&state, &state_x1, &trng, preserve, k, tag);
238 #else
239  /* Initialize the ASCON state */
240  ascon128_masked_aead_init(&state, &trng, &word, preserve, npub, k);
241 
242  /* Absorb the associated data into the state */
243  if (adlen > 0) {
245  (&state, ad, adlen, 6, &word, preserve, &trng);
246  }
247 
248  /* Separator between the associated data and the payload */
250 
251  /* Decrypt the ciphertext to create the plaintext */
253  (&state, m, c, *mlen, 6, &word, preserve, &trng);
254 
255  /* Convert the state back into key masked form and finalize */
256  ascon128_masked_aead_finalize(&state, &trng, preserve, k, tag);
257 #endif
258 
259  /* Check the authentication tag */
260  result = ascon_aead_check_tag(m, *mlen, tag, c + *mlen, ASCON128_TAG_SIZE);
261 
262  /* Clean up */
263 #if ASCON_MASKED_DATA_SHARES == 1
264  ascon_free(&state_x1);
265 #endif
267  ascon_clean(&word, sizeof(word));
268  ascon_clean(preserve, sizeof(preserve));
269  ascon_clean(tag, sizeof(tag));
270  ascon_trng_free(&trng);
271  return result;
272 }
#define ASCON128_TAG_SIZE
Size of the authentication tag for ASCON-128 and ASCON-128a.
Definition: aead.h:65
unsigned char ascon_aead_encrypt_8(ascon_state_t *state, unsigned char *dest, const unsigned char *src, size_t len, uint8_t first_round, unsigned char partial)
Encrypts a block of data with an ASCON state and an 8-byte rate.
int ascon_aead_check_tag(unsigned char *plaintext, size_t plaintext_len, const unsigned char *tag1, const unsigned char *tag2, size_t size)
Check an authentication tag in constant time.
unsigned char ascon_aead_decrypt_8(ascon_state_t *state, unsigned char *dest, const unsigned char *src, size_t len, uint8_t first_round, unsigned char partial)
Decrypts a block of data with an ASCON state and an 8-byte rate.
void ascon_aead_absorb_8(ascon_state_t *state, const unsigned char *data, size_t len, uint8_t first_round, int last_permute)
Absorbs data into an ASCON state with an 8-byte rate.
int ascon128_masked_aead_decrypt(unsigned char *m, size_t *mlen, const unsigned char *c, size_t clen, const unsigned char *ad, size_t adlen, const unsigned char *npub, const ascon_masked_key_128_t *k)
Decrypts and authenticates a packet with masked ASCON-128.
void ascon128_masked_aead_encrypt(unsigned char *c, size_t *clen, const unsigned char *m, size_t mlen, const unsigned char *ad, size_t adlen, const unsigned char *npub, const ascon_masked_key_128_t *k)
Encrypts and authenticates a packet with masked ASCON-128.
void ascon_masked_aead_absorb_8(ascon_masked_state_t *state, const unsigned char *data, size_t len, uint8_t first_round, ascon_masked_word_t *word, uint64_t *preserve, ascon_trng_state_t *trng)
Absorbs data into a masked ASCON state with an 8-byte rate.
void ascon_masked_aead_decrypt_8(ascon_masked_state_t *state, unsigned char *dest, const unsigned char *src, size_t len, uint8_t first_round, ascon_masked_word_t *word, uint64_t *preserve, ascon_trng_state_t *trng)
Decrypts a block of data with a masked ASCON state and an 8-byte rate.
void ascon_masked_aead_encrypt_8(ascon_masked_state_t *state, unsigned char *dest, const unsigned char *src, size_t len, uint8_t first_round, ascon_masked_word_t *word, uint64_t *preserve, ascon_trng_state_t *trng)
Encrypts a block of data with a masked ASCON state and an 8-byte rate.
#define ASCON_MASKED_DATA_SHARES
Number of shares to use for plaintext data and associated data, between 1 and ASCON_MASKED_KEY_SHARES...
#define ASCON_MASKED_KEY_SHARES
Number of shares to use for key material, between 2 and 4 with the default being 4.
void ascon_masked_state_free(ascon_masked_state_t *state)
Frees an ASCON-x2 permutation state and attempts to destroy any sensitive material.
void ascon_masked_state_init(ascon_masked_state_t *state)
Initializes the words of a masked ASCON permutation state.
void ascon_masked_word_separator(ascon_masked_word_t *word)
Adds a separator marker to a masked word.
uint64_t ascon_trng_generate_64(ascon_trng_state_t *state)
Generates a 64-bit random value for masking operations.
int ascon_trng_init(ascon_trng_state_t *state)
Initializes the random number source for generating a sequence of masking material at high speed.
void ascon_trng_free(ascon_trng_state_t *state)
Frees the random number source and destroys any sensitive material.
#define ascon_pad(state, offset)
#define ascon_separator(state)
void ascon_free(ascon_state_t *state)
Frees an ASCON permutation state and attempts to destroy any sensitive material.
ascon_state_t state
[snippet_key]
Definition: snippets.c:2
128-bit key that has been masked to hide its value when the code is operating on it.
Definition: masking.h:63
ascon_masked_key_word_t k[2]
Definition: masking.h:64
State of the ASCON permutation which has been masked with up to 4 shares.
State of the random number source.
Definition: ascon-trng.h:64
Masked 64-bit word with up to ASCON_MASKED_MAX_SHARES shares.
Structure of the internal state of the ASCON permutation.
Definition: permutation.h:63
void ascon_clean(void *buf, unsigned size)
Cleans a buffer that contains sensitive material.
Definition: ascon-clean.c:38