33 #if defined(FORKAE_ALG_NAME)
35 #define FORKAE_CONCAT_INNER(name,suffix) name##suffix
36 #define FORKAE_CONCAT(name,suffix) FORKAE_CONCAT_INNER(name,suffix)
39 #define FORKAE_PAEF_DATA_LIMIT \
40 ((unsigned long long)((1ULL << (FORKAE_COUNTER_SIZE * 8)) * \
41 (FORKAE_BLOCK_SIZE / 8)) - FORKAE_BLOCK_SIZE)
44 STATIC_INLINE
void FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)
45 (
unsigned char tweakey[FORKAE_TWEAKEY_SIZE],
46 unsigned long long counter,
unsigned char domain)
49 counter |= (((
unsigned long long)domain) << (FORKAE_COUNTER_SIZE * 8 - 3));
50 for (posn = 0; posn < FORKAE_COUNTER_SIZE; ++posn) {
51 tweakey[16 + FORKAE_NONCE_SIZE + FORKAE_COUNTER_SIZE - 1 - posn] =
52 (
unsigned char)counter;
58 STATIC_INLINE
int FORKAE_CONCAT(FORKAE_ALG_NAME,_is_padding)
59 (
const unsigned char *block,
unsigned len)
61 int check = block[0] ^ 0x80;
66 return (check - 1) >> 8;
69 int FORKAE_CONCAT(FORKAE_ALG_NAME,_aead_encrypt)
70 (
unsigned char *c,
unsigned long long *clen,
71 const unsigned char *m,
unsigned long long mlen,
72 const unsigned char *ad,
unsigned long long adlen,
73 const unsigned char *nsec,
74 const unsigned char *npub,
75 const unsigned char *k)
77 unsigned char tweakey[FORKAE_TWEAKEY_SIZE];
78 unsigned char tag[FORKAE_BLOCK_SIZE];
79 unsigned char block[FORKAE_BLOCK_SIZE];
80 unsigned long long counter;
84 *clen = mlen + FORKAE_BLOCK_SIZE;
88 if (adlen > FORKAE_PAEF_DATA_LIMIT || mlen > FORKAE_PAEF_DATA_LIMIT)
92 memcpy(tweakey, k, 16);
93 memcpy(tweakey + 16, npub, FORKAE_NONCE_SIZE);
94 memset(tweakey + 16 + FORKAE_NONCE_SIZE, 0,
95 FORKAE_TWEAKEY_SIZE - 16 - FORKAE_NONCE_SIZE);
99 memset(tag, 0,
sizeof(tag));
103 while (adlen > FORKAE_BLOCK_SIZE) {
104 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 0);
105 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, block, ad);
106 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
107 ad += FORKAE_BLOCK_SIZE;
108 adlen -= FORKAE_BLOCK_SIZE;
111 if (adlen == FORKAE_BLOCK_SIZE) {
112 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 1);
113 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, block, ad);
114 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
115 }
else if (adlen != 0 || mlen == 0) {
116 unsigned temp = (unsigned)adlen;
117 memcpy(block, ad, temp);
119 memset(block + temp + 1, 0,
sizeof(block) - temp - 1);
120 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 3);
121 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, block, block);
122 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
127 memcpy(c, tag,
sizeof(tag));
133 while (mlen > FORKAE_BLOCK_SIZE) {
134 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 4);
135 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, c, block, m);
136 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
137 c += FORKAE_BLOCK_SIZE;
138 m += FORKAE_BLOCK_SIZE;
139 mlen -= FORKAE_BLOCK_SIZE;
144 if (mlen == FORKAE_BLOCK_SIZE) {
145 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 5);
146 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, c, block, m);
147 lw_xor_block(c, tag, FORKAE_BLOCK_SIZE);
148 memcpy(c + FORKAE_BLOCK_SIZE, block, FORKAE_BLOCK_SIZE);
150 unsigned temp = (unsigned)mlen;
151 memcpy(block, m, temp);
153 memset(block + temp + 1, 0,
sizeof(block) - temp - 1);
154 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 7);
155 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, c, block, block);
156 lw_xor_block(c, tag, FORKAE_BLOCK_SIZE);
157 memcpy(c + FORKAE_BLOCK_SIZE, block, temp);
162 int FORKAE_CONCAT(FORKAE_ALG_NAME,_aead_decrypt)
163 (
unsigned char *m,
unsigned long long *mlen,
165 const unsigned char *c,
unsigned long long clen,
166 const unsigned char *ad,
unsigned long long adlen,
167 const unsigned char *npub,
168 const unsigned char *k)
170 unsigned char tweakey[FORKAE_TWEAKEY_SIZE];
171 unsigned char tag[FORKAE_BLOCK_SIZE];
172 unsigned char block[FORKAE_BLOCK_SIZE];
173 unsigned char *mtemp = m;
174 unsigned long long counter;
178 if (clen < FORKAE_BLOCK_SIZE)
180 clen -= FORKAE_BLOCK_SIZE;
185 if (adlen > FORKAE_PAEF_DATA_LIMIT || clen > FORKAE_PAEF_DATA_LIMIT)
189 memcpy(tweakey, k, 16);
190 memcpy(tweakey + 16, npub, FORKAE_NONCE_SIZE);
191 memset(tweakey + 16 + FORKAE_NONCE_SIZE, 0,
192 FORKAE_TWEAKEY_SIZE - 16 - FORKAE_NONCE_SIZE);
196 memset(tag, 0,
sizeof(tag));
200 while (adlen > FORKAE_BLOCK_SIZE) {
201 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 0);
202 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, block, ad);
203 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
204 ad += FORKAE_BLOCK_SIZE;
205 adlen -= FORKAE_BLOCK_SIZE;
208 if (adlen == FORKAE_BLOCK_SIZE) {
209 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 1);
210 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, block, ad);
211 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
212 }
else if (adlen != 0 || clen == 0) {
213 unsigned temp = (unsigned)adlen;
214 memcpy(block, ad, temp);
216 memset(block + temp + 1, 0,
sizeof(block) - temp - 1);
217 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 3);
218 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_encrypt)(tweakey, 0, block, block);
219 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
228 while (clen > FORKAE_BLOCK_SIZE) {
229 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 4);
230 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_decrypt)(tweakey, m, block, c);
231 lw_xor_block(tag, block, FORKAE_BLOCK_SIZE);
232 c += FORKAE_BLOCK_SIZE;
233 m += FORKAE_BLOCK_SIZE;
234 clen -= FORKAE_BLOCK_SIZE;
239 if (clen == FORKAE_BLOCK_SIZE) {
240 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 5);
241 lw_xor_block_2_src(m, c, tag, FORKAE_BLOCK_SIZE);
242 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_decrypt)(tweakey, m, block, m);
244 (mtemp, *mlen, block, c + FORKAE_BLOCK_SIZE,
sizeof(tag));
246 unsigned temp = (unsigned)clen;
247 unsigned char block2[FORKAE_BLOCK_SIZE];
249 FORKAE_CONCAT(FORKAE_ALG_NAME,_set_counter)(tweakey, counter, 7);
250 lw_xor_block_2_src(block2, tag, c, FORKAE_BLOCK_SIZE);
251 FORKAE_CONCAT(FORKAE_BLOCK_FUNC,_decrypt)
252 (tweakey, block2, block, block2);
253 check = FORKAE_CONCAT(FORKAE_ALG_NAME,_is_padding)
254 (block2 + temp, FORKAE_BLOCK_SIZE - temp);
255 memcpy(m, block2, temp);
257 (mtemp, *mlen, block, c + FORKAE_BLOCK_SIZE, temp, check);
265 #undef FORKAE_ALG_NAME
266 #undef FORKAE_BLOCK_SIZE
267 #undef FORKAE_NONCE_SIZE
268 #undef FORKAE_COUNTER_SIZE
269 #undef FORKAE_TWEAKEY_SIZE
270 #undef FORKAE_BLOCK_FUNC
271 #undef FORKAE_CONCAT_INNER
273 #undef FORKAE_PAEF_DATA_LIMIT
int aead_check_tag(unsigned char *plaintext, unsigned long long plaintext_len, const unsigned char *tag1, const unsigned char *tag2, unsigned tag_len)
Check an authentication tag in constant time.
Definition: aead-common.c:26
int aead_check_tag_precheck(unsigned char *plaintext, unsigned long long plaintext_len, const unsigned char *tag1, const unsigned char *tag2, unsigned tag_len, int precheck)
Check an authentication tag in constant time with a previous check.
Definition: aead-common.c:49