Added generic EAX and CCM implementations.
[BearSSL] / src / aead / eax.c
1 /*
2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 #include "inner.h"
26
27 /*
28 * Implementation Notes
29 * ====================
30 *
31 * The combined CTR + CBC-MAC functions can only handle full blocks,
32 * so some buffering is necessary. Moreover, EAX has a special padding
33 * rule for CBC-MAC, which implies that we cannot compute the MAC over
34 * the last received full block until we know whether we are at the
35 * end of the data or not.
36 *
37 * - 'ptr' contains a value from 1 to 16, which is the number of bytes
38 * accumulated in buf[] that still needs to be processed with the
39 * current OMAC computation. Beware that this can go to 16: a
40 * complete block cannot be processed until it is known whether it
41 * is the last block or not. However, it can never be 0, because
42 * OMAC^t works on an input that is at least one-block long.
43 *
44 * - When processing the message itself, CTR encryption/decryption is
45 * also done at the same time. The first 'ptr' bytes of buf[] then
46 * contains the encrypted bytes, while the last '16 - ptr' bytes of
47 * buf[] are the remnants of the stream block, to be used against
48 * the next input bytes, when available.
49 *
50 * - The current counter and running CBC-MAC values are kept in 'ctr'
51 * and 'cbcmac', respectively.
52 *
53 * - The derived keys for padding are kept in L2 and L4 (double and
54 * quadruple of Enc_K(0^n), in GF(2^128), respectively).
55 */
56
57 /*
58 * Start an OMAC computation; the first block is the big-endian
59 * representation of the provided value ('val' must fit on one byte).
60 * We make it a delayed block because it may also be the last one,
61 */
62 static void
63 omac_start(br_eax_context *ctx, unsigned val)
64 {
65 memset(ctx->cbcmac, 0, sizeof ctx->cbcmac);
66 memset(ctx->buf, 0, sizeof ctx->buf);
67 ctx->buf[15] = val;
68 ctx->ptr = 16;
69 }
70
71 /*
72 * Double a value in finite field GF(2^128), defined with modulus
73 * X^128+X^7+X^2+X+1.
74 */
75 static void
76 double_gf128(unsigned char *dst, const unsigned char *src)
77 {
78 unsigned cc;
79 int i;
80
81 cc = 0x87 & -((unsigned)src[0] >> 7);
82 for (i = 15; i >= 0; i --) {
83 unsigned z;
84
85 z = (src[i] << 1) ^ cc;
86 cc = z >> 8;
87 dst[i] = (unsigned char)z;
88 }
89 }
90
91 /*
92 * Apply padding to the last block, currently in ctx->buf (with
93 * ctx->ptr bytes), and finalize OMAC computation.
94 */
95 static void
96 do_pad(br_eax_context *ctx)
97 {
98 unsigned char *pad;
99 size_t ptr, u;
100
101 ptr = ctx->ptr;
102 if (ptr == 16) {
103 pad = ctx->L2;
104 } else {
105 ctx->buf[ptr ++] = 0x80;
106 memset(ctx->buf + ptr, 0x00, 16 - ptr);
107 pad = ctx->L4;
108 }
109 for (u = 0; u < sizeof ctx->buf; u ++) {
110 ctx->buf[u] ^= pad[u];
111 }
112 (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, ctx->buf, sizeof ctx->buf);
113 }
114
115 /*
116 * Apply CBC-MAC on the provided data, with buffering management. This
117 * function assumes that on input, ctx->buf contains a full block of
118 * unprocessed data.
119 */
120 static void
121 do_cbcmac_chunk(br_eax_context *ctx, const void *data, size_t len)
122 {
123 size_t ptr;
124
125 if (len == 0) {
126 return;
127 }
128 ptr = len & (size_t)15;
129 if (ptr == 0) {
130 len -= 16;
131 ptr = 16;
132 } else {
133 len -= ptr;
134 }
135 (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, ctx->buf, sizeof ctx->buf);
136 (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, data, len);
137 memcpy(ctx->buf, (const unsigned char *)data + len, ptr);
138 ctx->ptr = ptr;
139 }
140
141 /* see bearssl_aead.h */
142 void
143 br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx)
144 {
145 unsigned char tmp[16], iv[16];
146
147 ctx->vtable = &br_eax_vtable;
148 ctx->bctx = bctx;
149
150 /*
151 * Encrypt a whole-zero block to compute L2 and L4.
152 */
153 memset(tmp, 0, sizeof tmp);
154 memset(iv, 0, sizeof iv);
155 (*bctx)->ctr(bctx, iv, tmp, sizeof tmp);
156 double_gf128(ctx->L2, tmp);
157 double_gf128(ctx->L4, ctx->L2);
158 }
159
160 /* see bearssl_aead.h */
161 void
162 br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len)
163 {
164 /*
165 * Process nonce with OMAC^0.
166 */
167 omac_start(ctx, 0);
168 do_cbcmac_chunk(ctx, nonce, len);
169 do_pad(ctx);
170 memcpy(ctx->nonce, ctx->cbcmac, sizeof ctx->cbcmac);
171
172 /*
173 * Start OMAC^1 for the AAD ("header" in the EAX specification).
174 */
175 omac_start(ctx, 1);
176 }
177
178 /* see bearssl_aead.h */
179 void
180 br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len)
181 {
182 size_t ptr;
183
184 ptr = ctx->ptr;
185
186 /*
187 * If there is a partial block, first complete it.
188 */
189 if (ptr < 16) {
190 size_t clen;
191
192 clen = 16 - ptr;
193 if (len <= clen) {
194 memcpy(ctx->buf + ptr, data, len);
195 ctx->ptr = ptr + len;
196 return;
197 }
198 memcpy(ctx->buf + ptr, data, clen);
199 data = (const unsigned char *)data + clen;
200 len -= clen;
201 }
202
203 /*
204 * We now have a full block in buf[], and this is not the last
205 * block.
206 */
207 do_cbcmac_chunk(ctx, data, len);
208 }
209
210 /* see bearssl_aead.h */
211 void
212 br_eax_flip(br_eax_context *ctx)
213 {
214 /*
215 * Complete the OMAC computation on the AAD.
216 */
217 do_pad(ctx);
218 memcpy(ctx->head, ctx->cbcmac, sizeof ctx->cbcmac);
219
220 /*
221 * Start OMAC^2 for the encrypted data.
222 */
223 omac_start(ctx, 2);
224
225 /*
226 * Initial counter value for CTR is the processed nonce.
227 */
228 memcpy(ctx->ctr, ctx->nonce, sizeof ctx->nonce);
229 }
230
231 /* see bearssl_aead.h */
232 void
233 br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len)
234 {
235 unsigned char *dbuf;
236 size_t ptr;
237
238 /*
239 * Ensure that there is actual data to process.
240 */
241 if (len == 0) {
242 return;
243 }
244
245 dbuf = data;
246 ptr = ctx->ptr;
247
248 if (ptr != 16) {
249 /*
250 * We have a partially consumed block.
251 */
252 size_t u, clen;
253
254 clen = 16 - ptr;
255 if (len <= clen) {
256 clen = len;
257 }
258 if (encrypt) {
259 for (u = 0; u < clen; u ++) {
260 ctx->buf[ptr + u] ^= dbuf[u];
261 }
262 memcpy(dbuf, ctx->buf + ptr, clen);
263 } else {
264 for (u = 0; u < clen; u ++) {
265 unsigned dx, sx;
266
267 sx = ctx->buf[ptr + u];
268 dx = dbuf[u];
269 ctx->buf[ptr + u] = dx;
270 dbuf[u] = sx ^ dx;
271 }
272 }
273
274 if (len <= clen) {
275 ctx->ptr = ptr + clen;
276 return;
277 }
278 dbuf += clen;
279 len -= clen;
280 }
281
282 /*
283 * We now have a complete encrypted block in buf[] that must still
284 * be processed with OMAC, and this is not the final buf.
285 */
286 (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, ctx->buf, sizeof ctx->buf);
287
288 /*
289 * Do CTR encryption or decryption and CBC-MAC for all full blocks
290 * except the last.
291 */
292 ptr = len & (size_t)15;
293 if (ptr == 0) {
294 len -= 16;
295 ptr = 16;
296 } else {
297 len -= ptr;
298 }
299 if (encrypt) {
300 (*ctx->bctx)->encrypt(ctx->bctx, ctx->ctr, ctx->cbcmac,
301 dbuf, len);
302 } else {
303 (*ctx->bctx)->decrypt(ctx->bctx, ctx->ctr, ctx->cbcmac,
304 dbuf, len);
305 }
306 dbuf += len;
307
308 /*
309 * Compute next block of CTR stream, and use it to finish
310 * encrypting or decrypting the data.
311 */
312 memset(ctx->buf, 0, sizeof ctx->buf);
313 (*ctx->bctx)->ctr(ctx->bctx, ctx->ctr, ctx->buf, sizeof ctx->buf);
314 if (encrypt) {
315 size_t u;
316
317 for (u = 0; u < ptr; u ++) {
318 ctx->buf[u] ^= dbuf[u];
319 }
320 memcpy(dbuf, ctx->buf, ptr);
321 } else {
322 size_t u;
323
324 for (u = 0; u < ptr; u ++) {
325 unsigned dx, sx;
326
327 sx = ctx->buf[u];
328 dx = dbuf[u];
329 ctx->buf[u] = dx;
330 dbuf[u] = sx ^ dx;
331 }
332 }
333 ctx->ptr = ptr;
334 }
335
336 /*
337 * Complete tag computation. The final tag is written in ctx->cbcmac.
338 */
339 static void
340 do_final(br_eax_context *ctx)
341 {
342 size_t u;
343
344 do_pad(ctx);
345
346 /*
347 * Authentication tag is the XOR of the three OMAC outputs for
348 * the nonce, AAD and encrypted data.
349 */
350 for (u = 0; u < 16; u ++) {
351 ctx->cbcmac[u] ^= ctx->nonce[u] ^ ctx->head[u];
352 }
353 }
354
355 /* see bearssl_aead.h */
356 void
357 br_eax_get_tag(br_eax_context *ctx, void *tag)
358 {
359 do_final(ctx);
360 memcpy(tag, ctx->cbcmac, sizeof ctx->cbcmac);
361 }
362
363 /* see bearssl_aead.h */
364 void
365 br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len)
366 {
367 do_final(ctx);
368 memcpy(tag, ctx->cbcmac, len);
369 }
370
371 /* see bearssl_aead.h */
372 uint32_t
373 br_eax_check_tag_trunc(br_eax_context *ctx, const void *tag, size_t len)
374 {
375 unsigned char tmp[16];
376 size_t u;
377 int x;
378
379 br_eax_get_tag(ctx, tmp);
380 x = 0;
381 for (u = 0; u < len; u ++) {
382 x |= tmp[u] ^ ((const unsigned char *)tag)[u];
383 }
384 return EQ0(x);
385 }
386
387 /* see bearssl_aead.h */
388 uint32_t
389 br_eax_check_tag(br_eax_context *ctx, const void *tag)
390 {
391 return br_eax_check_tag_trunc(ctx, tag, 16);
392 }
393
394 /* see bearssl_aead.h */
395 const br_aead_class br_eax_vtable = {
396 16,
397 (void (*)(const br_aead_class **, const void *, size_t))
398 &br_eax_reset,
399 (void (*)(const br_aead_class **, const void *, size_t))
400 &br_eax_aad_inject,
401 (void (*)(const br_aead_class **))
402 &br_eax_flip,
403 (void (*)(const br_aead_class **, int, void *, size_t))
404 &br_eax_run,
405 (void (*)(const br_aead_class **, void *))
406 &br_eax_get_tag,
407 (uint32_t (*)(const br_aead_class **, const void *))
408 &br_eax_check_tag,
409 (void (*)(const br_aead_class **, void *, size_t))
410 &br_eax_get_tag_trunc,
411 (uint32_t (*)(const br_aead_class **, const void *, size_t))
412 &br_eax_check_tag_trunc
413 };