ASCON Suite
ascon-aead-common.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 
23 #include "ascon-aead-common.h"
24 #include "core/ascon-util-snp.h"
25 
27  (unsigned char *plaintext, size_t plaintext_len,
28  const unsigned char *tag1, const unsigned char *tag2, size_t size)
29 {
30  /* Set "accum" to -1 if the tags match, or 0 if they don't match */
31  int accum = 0;
32  while (size > 0) {
33  accum |= (*tag1++ ^ *tag2++);
34  --size;
35  }
36  accum = (accum - 1) >> 8;
37 
38  /* Destroy the plaintext if the tag match failed */
39  while (plaintext_len > 0) {
40  *plaintext++ &= accum;
41  --plaintext_len;
42  }
43 
44  /* If "accum" is 0, return -1, otherwise return 0 */
45  return ~accum;
46 }
47 
49  (ascon_state_t *state, const unsigned char *data,
50  size_t len, uint8_t first_round, int last_permute)
51 {
52  while (len >= 8) {
54  ascon_permute(state, first_round);
55  data += 8;
56  len -= 8;
57  }
58  if (len > 0)
60  ascon_pad(state, len);
61  if (last_permute)
62  ascon_permute(state, first_round);
63 }
64 
66  (ascon_state_t *state, const unsigned char *data,
67  size_t len, uint8_t first_round, int last_permute)
68 {
69  while (len >= 16) {
71  ascon_permute(state, first_round);
72  data += 16;
73  len -= 16;
74  }
75  if (len > 0)
77  ascon_pad(state, len);
78  if (last_permute)
79  ascon_permute(state, first_round);
80 }
81 
82 unsigned char ascon_aead_encrypt_8
83  (ascon_state_t *state, unsigned char *dest,
84  const unsigned char *src, size_t len, uint8_t first_round,
85  unsigned char partial)
86 {
87  /* Deal with a partial left-over block from last time */
88  if (partial != 0) {
89  size_t temp = 8U - partial;
90  if (temp > len) {
91  ascon_encrypt_partial(state, dest, src, partial, len);
92  return (unsigned char)(partial + len);
93  }
94  ascon_encrypt_partial(state, dest, src, partial, temp);
95  ascon_permute(state, first_round);
96  dest += temp;
97  src += temp;
98  len -= temp;
99  }
100 
101  /* Deal with full rate blocks */
102  while (len >= 8) {
103  ascon_encrypt_8(state, dest, src, 0);
104  ascon_permute(state, first_round);
105  dest += 8;
106  src += 8;
107  len -= 8;
108  }
109 
110  /* Deal with the partial left-over block on the end */
111  if (len > 0)
112  ascon_encrypt_partial(state, dest, src, 0, len);
113  return (unsigned char)len;
114 }
115 
117  (ascon_state_t *state, unsigned char *dest,
118  const unsigned char *src, size_t len, uint8_t first_round,
119  unsigned char partial)
120 {
121  /* Deal with a partial left-over block from last time */
122  if (partial != 0) {
123  size_t temp = 16U - partial;
124  if (temp > len) {
125  ascon_encrypt_partial(state, dest, src, partial, len);
126  return (unsigned char)(partial + len);
127  }
128  ascon_encrypt_partial(state, dest, src, partial, temp);
129  ascon_permute(state, first_round);
130  dest += temp;
131  src += temp;
132  len -= temp;
133  }
134 
135  /* Deal with full rate blocks */
136  while (len >= 16) {
137  ascon_encrypt_16(state, dest, src, 0);
138  ascon_permute(state, first_round);
139  dest += 16;
140  src += 16;
141  len -= 16;
142  }
143 
144  /* Deal with the partial left-over block on the end */
145  if (len > 0)
146  ascon_encrypt_partial(state, dest, src, 0, len);
147  return (unsigned char)len;
148 }
149 
150 unsigned char ascon_aead_decrypt_8
151  (ascon_state_t *state, unsigned char *dest,
152  const unsigned char *src, size_t len, uint8_t first_round,
153  unsigned char partial)
154 {
155  /* Deal with a partial left-over block from last time */
156  if (partial != 0) {
157  size_t temp = 8U - partial;
158  if (temp > len) {
159  ascon_decrypt_partial(state, dest, src, partial, len);
160  return (unsigned char)(partial + len);
161  }
162  ascon_decrypt_partial(state, dest, src, partial, temp);
163  ascon_permute(state, first_round);
164  dest += temp;
165  src += temp;
166  len -= temp;
167  }
168 
169  /* Deal with full rate blocks */
170  while (len >= 8) {
171  ascon_decrypt_8(state, dest, src, 0);
172  ascon_permute(state, first_round);
173  dest += 8;
174  src += 8;
175  len -= 8;
176  }
177 
178  /* Deal with the partial left-over block on the end */
179  if (len > 0)
180  ascon_decrypt_partial(state, dest, src, 0, len);
181  return (unsigned char)len;
182 }
183 
185  (ascon_state_t *state, unsigned char *dest,
186  const unsigned char *src, size_t len, uint8_t first_round,
187  unsigned char partial)
188 {
189  /* Deal with a partial left-over block from last time */
190  if (partial != 0) {
191  size_t temp = 16U - partial;
192  if (temp > len) {
193  ascon_decrypt_partial(state, dest, src, partial, len);
194  return (unsigned char)(partial + len);
195  }
196  ascon_decrypt_partial(state, dest, src, partial, temp);
197  ascon_permute(state, first_round);
198  dest += temp;
199  src += temp;
200  len -= temp;
201  }
202 
203  /* Deal with full rate blocks */
204  while (len >= 16) {
205  ascon_decrypt_16(state, dest, src, 0);
206  ascon_permute(state, first_round);
207  dest += 16;
208  src += 16;
209  len -= 16;
210  }
211 
212  /* Deal with the partial left-over block on the end */
213  if (len > 0)
214  ascon_decrypt_partial(state, dest, src, 0, len);
215  return (unsigned char)len;
216 }
void ascon_aead_absorb_16(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 a 16-byte rate.
unsigned char ascon_aead_encrypt_16(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 a 16-byte rate.
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.
unsigned char ascon_aead_decrypt_16(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 a 16-byte rate.
#define ascon_decrypt_8(state, dest, src, offset)
#define ascon_decrypt_16(state, dest, src, offset)
#define ascon_absorb_8(state, data, offset)
#define ascon_pad(state, offset)
#define ascon_encrypt_8(state, dest, src, offset)
#define ascon_absorb_16(state, data, offset)
#define ascon_encrypt_16(state, dest, src, offset)
#define ascon_absorb_partial(state, data, offset, count)
#define ascon_decrypt_partial(state, dest, src, offset, count)
#define ascon_encrypt_partial(state, dest, src, offset, count)
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
ascon_state_t state
[snippet_key]
Definition: snippets.c:2
unsigned char data[8]
[snippet_key]
Definition: snippets.c:14
Structure of the internal state of the ASCON permutation.
Definition: permutation.h:63