ASCON Suite
ascon-aead-masked-80pq.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-80pq, expanded to 8 bytes */
27 static uint8_t const ASCON80PQ_IV[8] =
28  {0xa0, 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 ascon80pq_masked_aead_init
35  ascon_state_t *state_x1,
36 #endif
38  uint64_t *preserve, const unsigned char *npub,
39  const ascon_masked_key_160_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, ASCON80PQ_IV, trng);
57  ascon_masked_key_xor(&(state->M[0]), word);
58  ascon_masked_key_xor(&(state->M[0]), &(k->k[3]));
59  ascon_masked_key_xor(&(state->M[1]), &(k->k[4]));
60  ascon_masked_key_xor(&(state->M[2]), &(k->k[5]));
61  ascon_masked_key_load(word, npub, trng);
62  ascon_masked_key_xor(&(state->M[3]), word);
63  ascon_masked_key_load(word, npub + 8, trng);
64  ascon_masked_key_xor(&(state->M[4]), word);
65  ascon_masked_key_permute(state, 0, preserve);
66  ascon_masked_key_xor(&(state->M[2]), &(k->k[3]));
67  ascon_masked_key_xor(&(state->M[3]), &(k->k[4]));
68  ascon_masked_key_xor(&(state->M[4]), &(k->k[5]));
69 
70  /* Convert the key shares form into the data shares form */
71 #if ASCON_MASKED_DATA_SHARES == 1
72  ascon_copy_key_to_x1(state_x1, state);
73 #elif ASCON_MASKED_DATA_SHARES == 2
74  ascon_copy_key_to_x2(state, trng);
75 #elif ASCON_MASKED_DATA_SHARES == 3
76  ascon_copy_key_to_x3(state, trng);
77 #else
78  ascon_copy_key_to_x4(state, trng);
79 #endif
80 }
81 
82 /* Finalize and generate the authentication tag in the state */
83 static void ascon80pq_masked_aead_finalize
86  ascon_state_t *state_x1,
87 #endif
88  ascon_trng_state_t *trng, uint64_t *preserve,
89  const ascon_masked_key_160_t *k, unsigned char *tag)
90 {
91  /* Refresh the randomness for the final permutation call */
92 #if ASCON_MASKED_KEY_SHARES == 2
93  preserve[0] = ascon_trng_generate_64(trng);
94 #elif ASCON_MASKED_KEY_SHARES == 3
95  preserve[0] = ascon_trng_generate_64(trng);
96  preserve[1] = ascon_trng_generate_64(trng);
97 #else
98  preserve[0] = ascon_trng_generate_64(trng);
99  preserve[1] = ascon_trng_generate_64(trng);
100  preserve[2] = ascon_trng_generate_64(trng);
101 #endif
102 
103  /* Convert the data shares form back into the key shares form */
104 #if ASCON_MASKED_DATA_SHARES == 1
105  ascon_copy_key_from_x1(state, state_x1, trng);
106 #elif ASCON_MASKED_DATA_SHARES == 2
107  ascon_copy_key_from_x2(state, trng);
108 #elif ASCON_MASKED_DATA_SHARES == 3
109  ascon_copy_key_from_x3(state, trng);
110 #else
111  ascon_copy_key_from_x4(state, trng);
112 #endif
113 
114  /* Finalize the state and generate the tag */
115  ascon_masked_key_xor(&(state->M[1]), &(k->k[0]));
116  ascon_masked_key_xor(&(state->M[2]), &(k->k[1]));
117  ascon_masked_key_xor(&(state->M[3]), &(k->k[2]));
118  ascon_masked_key_permute(state, 0, preserve);
119  ascon_masked_key_xor(&(state->M[3]), &(k->k[4]));
120  ascon_masked_key_xor(&(state->M[4]), &(k->k[5]));
121  ascon_masked_key_store(tag, &(state->M[3]));
122  ascon_masked_key_store(tag + 8, &(state->M[4]));
123 }
124 
126  (unsigned char *c, size_t *clen,
127  const unsigned char *m, size_t mlen,
128  const unsigned char *ad, size_t adlen,
129  const unsigned char *npub,
130  const ascon_masked_key_160_t *k)
131 {
133 #if ASCON_MASKED_DATA_SHARES == 1
134  ascon_state_t state_x1;
135  unsigned char partial;
136 #endif
137  ascon_trng_state_t trng;
138  ascon_masked_word_t word;
139  uint64_t preserve[ASCON_MASKED_KEY_SHARES - 1];
140 
141  /* Set the length of the returned ciphertext */
142  *clen = mlen + ASCON80PQ_TAG_SIZE;
143 
144  /* Initialize the random number generator */
145  ascon_trng_init(&trng);
146 
147 #if ASCON_MASKED_DATA_SHARES == 1
148  /* Initialize the ASCON state */
149  ascon80pq_masked_aead_init
150  (&state, &state_x1, &trng, &word, preserve, npub, k);
151 
152  /* Absorb the associated data into the state */
153  if (adlen > 0)
154  ascon_aead_absorb_8(&state_x1, ad, adlen, 6, 1);
155 
156  /* Separator between the associated data and the payload */
157  ascon_separator(&state_x1);
158 
159  /* Encrypt the plaintext to create the ciphertext */
160  partial = ascon_aead_encrypt_8(&state_x1, c, m, mlen, 6, 0);
161  ascon_pad(&state_x1, partial);
162 
163  /* Convert the state back into key masked form and finalize */
164  ascon80pq_masked_aead_finalize
165  (&state, &state_x1, &trng, preserve, k, c + mlen);
166 #else
167  /* Initialize the ASCON state */
168  ascon80pq_masked_aead_init(&state, &trng, &word, preserve, npub, k);
169 
170  /* Absorb the associated data into the state */
171  if (adlen > 0) {
173  (&state, ad, adlen, 6, &word, preserve, &trng);
174  }
175 
176  /* Separator between the associated data and the payload */
178 
179  /* Encrypt the plaintext to create the ciphertext */
181  (&state, c, m, mlen, 6, &word, preserve, &trng);
182 
183  /* Convert the state back into key masked form and finalize */
184  ascon80pq_masked_aead_finalize(&state, &trng, preserve, k, c + mlen);
185 #endif
186 
187  /* Clean up */
188 #if ASCON_MASKED_DATA_SHARES == 1
189  ascon_free(&state_x1);
190 #endif
192  ascon_clean(&word, sizeof(word));
193  ascon_clean(preserve, sizeof(preserve));
194  ascon_trng_free(&trng);
195 }
196 
198  (unsigned char *m, size_t *mlen,
199  const unsigned char *c, size_t clen,
200  const unsigned char *ad, size_t adlen,
201  const unsigned char *npub,
202  const ascon_masked_key_160_t *k)
203 {
205 #if ASCON_MASKED_DATA_SHARES == 1
206  ascon_state_t state_x1;
207  unsigned char partial;
208 #endif
209  ascon_trng_state_t trng;
210  ascon_masked_word_t word;
211  uint64_t preserve[ASCON_MASKED_KEY_SHARES - 1];
212  unsigned char tag[ASCON80PQ_TAG_SIZE];
213  int result;
214 
215  /* Set the length of the returned plaintext */
216  if (clen < ASCON80PQ_TAG_SIZE)
217  return -1;
218  *mlen = clen - ASCON80PQ_TAG_SIZE;
219 
220  /* Initialize the random number generator */
221  ascon_trng_init(&trng);
222 
223 #if ASCON_MASKED_DATA_SHARES == 1
224  /* Initialize the ASCON state */
225  ascon80pq_masked_aead_init
226  (&state, &state_x1, &trng, &word, preserve, npub, k);
227 
228  /* Absorb the associated data into the state */
229  if (adlen > 0)
230  ascon_aead_absorb_8(&state_x1, ad, adlen, 6, 1);
231 
232  /* Separator between the associated data and the payload */
233  ascon_separator(&state_x1);
234 
235  /* Decrypt the ciphertext to create the plaintext */
236  partial = ascon_aead_decrypt_8(&state_x1, m, c, *mlen, 6, 0);
237  ascon_pad(&state_x1, partial);
238 
239  /* Convert the state back into key masked form and finalize */
240  ascon80pq_masked_aead_finalize(&state, &state_x1, &trng, preserve, k, tag);
241 #else
242  /* Initialize the ASCON state */
243  ascon80pq_masked_aead_init(&state, &trng, &word, preserve, npub, k);
244 
245  /* Absorb the associated data into the state */
246  if (adlen > 0) {
248  (&state, ad, adlen, 6, &word, preserve, &trng);
249  }
250 
251  /* Separator between the associated data and the payload */
253 
254  /* Decrypt the ciphertext to create the plaintext */
256  (&state, m, c, *mlen, 6, &word, preserve, &trng);
257 
258  /* Convert the state back into key masked form and finalize */
259  ascon80pq_masked_aead_finalize(&state, &trng, preserve, k, tag);
260 #endif
261 
262  /* Check the authentication tag */
263  result = ascon_aead_check_tag(m, *mlen, tag, c + *mlen, ASCON80PQ_TAG_SIZE);
264 
265  /* Clean up */
266 #if ASCON_MASKED_DATA_SHARES == 1
267  ascon_free(&state_x1);
268 #endif
270  ascon_clean(&word, sizeof(word));
271  ascon_clean(preserve, sizeof(preserve));
272  ascon_clean(tag, sizeof(tag));
273  ascon_trng_free(&trng);
274  return result;
275 }
#define ASCON80PQ_TAG_SIZE
Size of the authentication tag for ASCON-80pq.
Definition: aead.h:80
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.
void ascon80pq_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_160_t *k)
Encrypts and authenticates a packet with masked ASCON-80pq.
int ascon80pq_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_160_t *k)
Decrypts and authenticates a packet with masked ASCON-80pq.
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
160-bit key that has been masked to hide its value when the code is operating on it.
Definition: masking.h:85
ascon_masked_key_word_t k[6]
Definition: masking.h:86
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