ASCON Suite
ascon-prf.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 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 
23 #include <ascon/prf.h>
24 #include <ascon/utility.h>
25 #include "core/ascon-util-snp.h"
26 #include "aead/ascon-aead-common.h"
27 
31 #define ASCON_PRF_RATE_IN 32
32 
36 #define ASCON_PRF_RATE_OUT 16
37 
39  (unsigned char *out, size_t outlen,
40  const unsigned char *in, size_t inlen,
41  const unsigned char *key)
42 {
44  ascon_prf_fixed_init(&state, key, 0);
45  ascon_prf_absorb(&state, in, inlen);
46  ascon_prf_squeeze(&state, out, outlen);
48 }
49 
51  (unsigned char *out, size_t outlen,
52  const unsigned char *in, size_t inlen,
53  const unsigned char *key)
54 {
56  ascon_prf_fixed_init(&state, key, outlen);
57  ascon_prf_absorb(&state, in, inlen);
58  ascon_prf_squeeze(&state, out, outlen);
60 }
61 
63  (unsigned char *out, size_t outlen,
64  const unsigned char *in, size_t inlen,
65  const unsigned char *key)
66 {
68  unsigned char iv[8] = {0x80, 0x00, 0x4c, 0x80, 0x00, 0x00, 0x00, 0x00};
70  return -1;
72  return -1;
73  iv[1] = (unsigned char)(inlen * 8U);
74  ascon_init(&state);
75  ascon_overwrite_bytes(&state, iv, 0, 8);
77  ascon_overwrite_bytes(&state, in, 24, inlen);
78  ascon_permute(&state, 0);
79  ascon_absorb_16(&state, key, 24);
80  ascon_squeeze_partial(&state, out, 24, outlen);
81  ascon_free(&state);
82  return 0;
83 }
84 
86  (unsigned char *tag,
87  const unsigned char *in, size_t inlen,
88  const unsigned char *key)
89 {
92  ascon_prf_absorb(&state, in, inlen);
95 }
96 
98  (const unsigned char *tag,
99  const unsigned char *in, size_t inlen,
100  const unsigned char *key)
101 {
102  unsigned char tag2[ASCON_MAC_TAG_SIZE];
103  int result;
104  ascon_mac(tag2, in, inlen, key);
105  result = ascon_aead_check_tag(0, 0, tag, tag2, sizeof(tag2));
106  ascon_clean(tag2, sizeof(tag2));
107  return result;
108 }
109 
110 void ascon_prf_init(ascon_prf_state_t *state, const unsigned char *key)
111 {
112  ascon_prf_fixed_init(state, key, 0);
113 }
114 
116  (ascon_prf_state_t *state, const unsigned char *key, size_t outlen)
117 {
118  unsigned char iv[8] = {0x80, 0x80, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00};
119 #if !defined(__SIZEOF_SIZE_T__) || __SIZEOF_SIZE_T__ >= 4
120  if (outlen >= (((size_t)1) << 29))
121  outlen = 0; /* Too large, so switch to arbitrary-length output */
122 #endif
123  be_store_word32(iv + 4, (uint32_t)(outlen * 8U));
124  ascon_init(&(state->state));
125  ascon_overwrite_bytes(&(state->state), iv, 0, 8);
126  ascon_overwrite_bytes(&(state->state), key, 8, ASCON_PRF_KEY_SIZE);
127  ascon_permute(&(state->state), 0);
128  ascon_release(&(state->state));
129  state->count = 0;
130  state->mode = 0;
131 }
132 
133 void ascon_prf_reinit(ascon_prf_state_t *state, const unsigned char *key)
134 {
136  ascon_prf_fixed_init(state, key, 0);
137 }
138 
140  (ascon_prf_state_t *state, const unsigned char *key, size_t outlen)
141 {
143  ascon_prf_fixed_init(state, key, outlen);
144 }
145 
147 {
148  if (state) {
149  ascon_acquire(&(state->state));
150  ascon_free(&(state->state));
151  state->count = 0;
152  state->mode = 0;
153  }
154 }
155 
157  (ascon_prf_state_t *state, const unsigned char *in, size_t inlen)
158 {
159  unsigned temp;
160 
161  /* Acquire access to shared hardware if necessary */
162  ascon_acquire(&(state->state));
163 
164  /* If we were squeezing output, then go back to the absorb phase */
165  if (state->mode) {
166  state->mode = 0;
167  state->count = 0;
168  ascon_permute(&(state->state), 0);
169  }
170 
171  /* Handle the partial left-over block from last time */
172  if (state->count) {
173  temp = ASCON_PRF_RATE_IN - state->count;
174  if (temp > inlen) {
175  temp = (unsigned)inlen;
176  ascon_absorb_partial(&(state->state), in, state->count, temp);
177  state->count += temp;
178  ascon_release(&(state->state));
179  return;
180  }
181  ascon_absorb_partial(&(state->state), in, state->count, temp);
182  state->count = 0;
183  in += temp;
184  inlen -= temp;
185  ascon_permute(&(state->state), 0);
186  }
187 
188  /* Process full blocks that are aligned at state->s.count == 0 */
189  while (inlen >= ASCON_PRF_RATE_IN) {
190  ascon_absorb_16(&(state->state), in, 0);
191  ascon_absorb_16(&(state->state), in + 16, 16);
192  in += ASCON_PRF_RATE_IN;
193  inlen -= ASCON_PRF_RATE_IN;
194  ascon_permute(&(state->state), 0);
195  }
196 
197  /* Process the left-over block at the end of the input */
198  temp = (unsigned)inlen;
199  if (temp > 0)
200  ascon_absorb_partial(&(state->state), in, 0, temp);
201  state->count = temp;
202 
203  /* Release access to the shared hardware */
204  ascon_release(&(state->state));
205 }
206 
208  (ascon_prf_state_t *state, unsigned char *out, size_t outlen)
209 {
210  unsigned temp;
211 
212  /* Acquire access to shared hardware if necessary */
213  ascon_acquire(&(state->state));
214 
215  /* Pad the final input block if we were still in the absorb phase */
216  if (!state->mode) {
217  ascon_pad(&(state->state), state->count);
218  ascon_separator(&(state->state));
219  state->count = 0;
220  state->mode = 1;
221  }
222 
223  /* Handle left-over partial blocks from last time */
224  if (state->count) {
225  temp = ASCON_PRF_RATE_OUT - state->count;
226  if (temp > outlen) {
227  temp = (unsigned)outlen;
228  ascon_squeeze_partial(&(state->state), out, state->count, temp);
229  state->count += temp;
230  ascon_release(&(state->state));
231  return;
232  }
233  ascon_squeeze_partial(&(state->state), out, state->count, temp);
234  out += temp;
235  outlen -= temp;
236  state->count = 0;
237  }
238 
239  /* Handle full blocks */
240  while (outlen >= ASCON_PRF_RATE_OUT) {
241  ascon_permute(&(state->state), 0);
242  ascon_squeeze_16(&(state->state), out, 0);
243  out += ASCON_PRF_RATE_OUT;
244  outlen -= ASCON_PRF_RATE_OUT;
245  }
246 
247  /* Handle the left-over block */
248  if (outlen > 0) {
249  temp = (unsigned)outlen;
250  ascon_permute(&(state->state), 0);
251  ascon_squeeze_partial(&(state->state), out, 0, temp);
252  state->count = temp;
253  }
254 
255  /* Release access to the shared hardware */
256  ascon_release(&(state->state));
257 }
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.
void ascon_prf_free(ascon_prf_state_t *state)
Frees the ASCON-Prf state and destroys any sensitive material.
Definition: ascon-prf.c:146
void ascon_prf(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen, const unsigned char *key)
Processes a key and input data with ASCON-Prf to produce a tag.
Definition: ascon-prf.c:39
void ascon_prf_fixed(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen, const unsigned char *key)
Processes a key and input data with ASCON-Prf to produce a fixed-length output tag.
Definition: ascon-prf.c:51
void ascon_prf_fixed_init(ascon_prf_state_t *state, const unsigned char *key, size_t outlen)
Initializes the state for an incremental ASCON-Prf operation with fixed-length output.
Definition: ascon-prf.c:116
void ascon_mac(unsigned char *tag, const unsigned char *in, size_t inlen, const unsigned char *key)
Processes a key and input data with ASCON-Mac to produce a tag.
Definition: ascon-prf.c:86
int ascon_prf_short(unsigned char *out, size_t outlen, const unsigned char *in, size_t inlen, const unsigned char *key)
Processes a key and input data with ASCON-PrfShort to produce a tag.
Definition: ascon-prf.c:63
void ascon_prf_init(ascon_prf_state_t *state, const unsigned char *key)
Initializes the state for an incremental ASCON-Prf operation.
Definition: ascon-prf.c:110
void ascon_prf_squeeze(ascon_prf_state_t *state, unsigned char *out, size_t outlen)
Squeezes output from an incremental ASCON-Prf operation.
Definition: ascon-prf.c:208
void ascon_prf_reinit(ascon_prf_state_t *state, const unsigned char *key)
Re-initializes the state for an incremental ASCON-Prf operation.
Definition: ascon-prf.c:133
int ascon_mac_verify(const unsigned char *tag, const unsigned char *in, size_t inlen, const unsigned char *key)
Verifies an ASCON-Mac tag value.
Definition: ascon-prf.c:98
void ascon_prf_fixed_reinit(ascon_prf_state_t *state, const unsigned char *key, size_t outlen)
Re-initializes the state for an incremental ASCON-Prf operation with fixed-length output.
Definition: ascon-prf.c:140
#define ASCON_PRF_RATE_IN
Rate of absorption for input blocks.
Definition: ascon-prf.c:31
#define ASCON_PRF_RATE_OUT
Rate of squeezing for output blocks.
Definition: ascon-prf.c:36
void ascon_prf_absorb(ascon_prf_state_t *state, const unsigned char *in, size_t inlen)
Absorbs input data into an incremental ASCON-Prf state.
Definition: ascon-prf.c:157
#define ascon_pad(state, offset)
#define ascon_absorb_16(state, data, offset)
#define ascon_squeeze_partial(state, data, offset, count)
#define ascon_absorb_partial(state, data, offset, count)
#define ascon_squeeze_16(state, data, offset)
#define ascon_separator(state)
#define be_store_word32(ptr, x)
Definition: ascon-util.h:75
void ascon_free(ascon_state_t *state)
Frees an ASCON permutation state and attempts to destroy any sensitive material.
void ascon_release(ascon_state_t *state)
Temporarily releases access to any shared hardware resources that a permutation state was using.
void ascon_overwrite_bytes(ascon_state_t *state, const uint8_t *data, unsigned offset, unsigned size)
Overwrites existing bytes in the ASCON state.
void ascon_permute(ascon_state_t *state, uint8_t first_round)
Permutes the ASCON state with a specified number of rounds.
Definition: ascon-c32.c:36
void ascon_acquire(ascon_state_t *state)
Re-acquires access to any shared hardware resources that a permutation state was using.
void ascon_init(ascon_state_t *state)
Initializes the words of the ASCON permutation state to zero.
ASCON-Prf, ASCON-PrfShort, and ASCON-Mac algorithms.
#define ASCON_PRF_KEY_SIZE
Size of the key for ASCON-Prf in bytes.
Definition: prf.h:65
#define ASCON_PRF_SHORT_MAX_OUTPUT_SIZE
Maximum number of bytes that can be output from ASCON-PrfShort.
Definition: prf.h:85
#define ASCON_MAC_TAG_SIZE
Size of the ASCON-Mac output in bytes.
Definition: prf.h:100
#define ASCON_PRF_SHORT_MAX_INPUT_SIZE
Maximum number of bytes that can be input to ASCON-PrfShort.
Definition: prf.h:80
#define ASCON_PRF_SHORT_KEY_SIZE
Size of the key for ASCON-PrfShort in bytes.
Definition: prf.h:75
ascon_state_t state
[snippet_key]
Definition: snippets.c:2
State information for the ASCON-Prf incremental mode.
Definition: prf.h:108
Structure of the internal state of the ASCON permutation.
Definition: permutation.h:63
System utilities of use to applications that use ASCON.
void ascon_clean(void *buf, unsigned size)
Cleans a buffer that contains sensitive material.
Definition: ascon-clean.c:38