symm/ocb3.h, symm/ocb3-def.h: Implement the OCB3 auth'ned encryption mode.
[catacomb] / symm / gcm-def.h
CommitLineData
50df5733
MW
1/* -*-c-*-
2 *
3 * The GCM authenticated encryption mode
4 *
5 * (c) 2018 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Catacomb.
11 *
12 * Catacomb is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU Library General Public License as published
14 * by the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * Catacomb is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * USA.
26 */
27
28#ifndef CATACOMB_GCM_DEF_H
29#define CATACOMB_GCM_DEF_H
30
31#ifdef __cplusplus
32 extern "C" {
33#endif
34
35/*----- Header files ------------------------------------------------------*/
36
37#include <string.h>
38
39#include <mLib/bits.h>
40#include <mLib/sub.h>
41
42#ifndef CATACOMB_ARENA_H
43# include "arena.h"
44#endif
45
46#ifndef CATACOMB_BLKC_H
47# include "blkc.h"
48#endif
49
50#ifndef CATACOMB_CT_H
51# include "ct.h"
52#endif
53
54#ifndef CATACOMB_KEYSZ_H
55# include "keysz.h"
56#endif
57
58#ifndef CATACOMB_PARANOIA_H
59# include "paranoia.h"
60#endif
61
62#ifndef CATACOMB_RSVR_H
63# include "rsvr.h"
64#endif
65
66/*----- Type definitions --------------------------------------------------*/
67
68typedef struct gcm_params {
69 unsigned f; /* flags */
70#define GCMF_SWAP 1u /* swap byte order? */
71 unsigned n; /* number of words in block */
72 uint32 poly; /* selected polynomial mask */
73} gcm_params;
74
75/*----- Utilities ---------------------------------------------------------*/
76
77/* Supported block sizes. */
78#define GCM_WIDTHS(_) _(64) _(96) _(128) _(192) _(256)
79#define GCM_NMAX 8
80
81/* Polynomial tails for the supported block sizes. */
82#define GCM_POLY_64 0xd8000000
83#define GCM_POLY_96 0x82600000
84#define GCM_POLY_128 0xe1000000
85#define GCM_POLY_192 0xe1000000
86#define GCM_POLY_256 0xa4200000
87
88/* Determine whether to set the @GCMF_SWAP@ flag. */
89#define GCM_SWAP_L GCMF_SWAP
90#define GCM_SWAP_B 0
91
92/* --- @gcm_mktable@ --- *
93 *
94 * Arguments: @const gcm_params *p@ = pointer to the parameters
95 * @uint32 *ktab@ = where to write the table; there must be
96 * space for %$32 n$% $%n$%-word entries, i.e.,
97 * %$32 n^2$% 32-bit words in total, where %$n$% is
98 * @p->n@, the block size in words
99 * @const uint32 *k@ = input field element
100 *
101 * Returns: ---
102 *
103 * Use: Construct a table for use by @gcm_mulk_...@ below, to
104 * multiply (vaguely) efficiently by @k@.
105 */
106
107extern void gcm_mktable(const gcm_params */*p*/,
108 uint32 */*ktab*/, const uint32 */*k*/);
109
110/* --- @gcm_mulk_N@ --- *
111 *
112 * Arguments: @uint32 *a@ = accumulator to multiply
113 * @const uint32 *ktab@ = table constructed by @gcm_mktable@
114 *
115 * Returns: ---
116 *
117 * Use: Multiply @a@ by @k@ (implicitly represented in @ktab@),
118 * updating @a@ in-place. There are separate functions for each
119 * supported block size because this is the function whose
120 * performance actually matters.
121 */
122
123#define GCM_DECL_MULK(nbits) \
124 extern void gcm_mulk_##nbits(uint32 */*a*/, const uint32 */*ktab*/);
125GCM_WIDTHS(GCM_DECL_MULK)
126#undef GCM_DECL_MULK
127
128/* Dispatch to the appropriate variant of @gcm_mulk@. */
129#define GCM_MULK(PRE, a, ktab) BLKC_GLUE(gcm_mulk_, BLKC_BITS(PRE))(a, ktab)
130
131/* --- @gcm_ghashdone@ --- *
132 *
133 * Arguments: @const gcm_params *p@ = pointer to the parameters
134 * @uint32 *a@ = GHASH accumulator
135 * @const uint32 *ktab@ = multiplication table, built by
136 * @gcm_mktable@
137 * @unsigned long xblocks, yblocks@ = number of whole blocks in
138 * the two inputs
139 * @unsigned xbytes, ybytes@ = number of trailing bytes in the
140 * two inputs
141 *
142 * Returns: ---
143 *
144 * Use: Finishes a GHASH operation by appending the appropriately
145 * encoded lengths of the two constituent messages.
146 */
147
148extern void gcm_ghashdone(const gcm_params */*p*/,
149 uint32 */*a*/, const uint32 */*ktab*/,
150 unsigned long /*xblocks*/, unsigned /*xbytes*/,
151 unsigned long /*yblocks*/, unsigned /*ybytes*/);
152
153/* --- @gcm_concat@ --- *
154 *
155 * Arguments: @const gcm_params *p@ = pointer to the parameters
156 * @uint32 *z@ = GHASH accumulator for suffix, updated
157 * @const uint32 *x@ = GHASH accumulator for prefix
158 * @const uint32 *ktab@ = multiplication table, built by
159 * @gcm_mktable@
160 * @unsigned long n@ = length of suffix in whole blocks
161 *
162 * Returns: ---
163 *
164 * Use: On entry, @x@ and @z@ are the results of hashing two strings
165 * %$a$% and %$b$%, each a whole number of blocks long; in
166 * particular, %$b$% is @n@ blocks long. On exit, @z@ is
167 * updated to be the hash of %$a \cat b$%.
168 */
169
170extern void gcm_concat(const gcm_params */*p*/,
171 uint32 */*z*/, const uint32 */*x*/,
172 const uint32 */*ktab*/, unsigned long /*n*/);
173
174/* Step the counter using GCM's strange only-the-last-32-bits convention. */
175#define GCM_STEP(PRE, w) BLKC_GLUE(GCM_STEP_, BLKC_ENDIAN(PRE))(PRE, w)
176#define GCM_STEP_B(PRE, w) GCM_STEP_X(PRE, BLKC_ID, w)
177#define GCM_STEP_L(PRE, w) GCM_STEP_X(PRE, ENDSWAP32, w)
178#define GCM_STEP_X(PRE, op, w) do { \
179 BLKC_W(w); \
180 _w[PRE##_BLKSZ/4 - 1] = op(op(_w[PRE##_BLKSZ/4 - 1]) + 1); \
181} while (0)
182
183/*----- Macros ------------------------------------------------------------*/
184
185/* --- @GCM_DEF@ --- *
186 *
187 * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher
188 *
189 * Use: Creates an implementation for the GCM authenticated-
190 * encryption mode.
191 */
192
193#define GCM_DEF(PRE, pre) GCM_DEFX(PRE, pre, #pre, #pre)
194
195#define GCM_DEFX(PRE, pre, name, fname) \
196 \
197static const gcm_params pre##_gcmparams = { \
198 BLKC_GLUE(GCM_SWAP_, BLKC_ENDIAN(PRE)), \
199 PRE##_BLKSZ/4, \
200 BLKC_GLUE(GCM_POLY_, BLKC_BITS(PRE)) \
201}; \
202 \
203const octet \
204 pre##_gcmnoncesz[] = { KSZ_ANY, PRE##_BLKSZ - 4 }, \
205 pre##_gcmtagsz[] = { KSZ_RANGE, PRE##_BLKSZ, 0, PRE##_BLKSZ, 1 }; \
206 \
207static const rsvr_policy pre##_gcmpolicy = { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \
208 \
209/* --- @pre_gcmsetkey@ --- * \
210 * \
211 * Arguments: @pre_gcmkey *key@ = pointer to key block to fill in \
212 * @const void *k@ = pointer to key material \
213 * @size_t ksz@ = size of key material \
214 * \
215 * Returns: --- \
216 * \
217 * Use: Initializes an GCM key block. \
218 */ \
219 \
220void pre##_gcmsetkey(pre##_gcmkey *key, const void *k, size_t ksz) \
221{ \
222 uint32 t[PRE##_BLKSZ/4]; \
223 \
224 /* Initialize the block cipher. */ \
225 pre##_init(&key->ctx, k, ksz); \
226 \
227 /* Set up the GHASH multiplication table. */ \
228 BLKC_ZERO(PRE, t); pre##_eblk(&key->ctx, t, t); \
229 gcm_mktable(&pre##_gcmparams, key->ktab, t); \
230} \
231 \
232/* --- @pre_gcmaadinit@ --- * \
233 * \
234 * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \
235 * @const pre_gcmkey *key@ = pointer to key block \
236 * \
237 * Returns: --- \
238 * \
239 * Use: Initializes an GCM AAD (`additional authenticated \
240 * data') context associated with a given key. AAD \
241 * contexts can be copied and/or reused, saving time if \
242 * the AAD for a number of messages has a common prefix. \
243 * \
244 * The @key@ doesn't need to be kept around, though \
245 * usually there'll at least be another copy in some GCM \
246 * operation context because the AAD on its own isn't much \
247 * good. \
248 */ \
249 \
250void pre##_gcmaadinit(pre##_gcmaadctx *aad, const pre##_gcmkey *key) \
251 { aad->k = *key; aad->off = 0; aad->len = 0; BLKC_ZERO(PRE, aad->a); } \
252 \
253/* --- @pre_gcmaadhash@ --- * \
254 * \
255 * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \
256 * @const void *p@ = pointer to AAD material \
257 * @size_t sz@ = length of AAD material \
258 * \
259 * Returns: --- \
260 * \
261 * Use: Feeds AAD into the context. \
262 */ \
263 \
264void pre##_gcmaadhash(pre##_gcmaadctx *aad, const void *p, size_t sz) \
265{ \
266 rsvr_state st; \
267 const octet *q; \
268 \
269 rsvr_setup(&st, &pre##_gcmpolicy, aad->b, &aad->off, p, sz); \
270 RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \
271 BLKC_XLOAD(PRE, aad->a, q); GCM_MULK(PRE, aad->a, aad->k.ktab); \
272 aad->len++; \
273 } \
274} \
275 \
276/* --- @pre_gcminit@ --- * \
277 * \
278 * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \
279 * @const pre_gcmkey *key@ = pointer to key block \
280 * @const void *n@ = pointer to nonce \
281 * @size_t nsz@ = size of nonce \
282 * \
283 * Returns: --- \
284 * \
285 * Use: Initialize an GCM operation context with a given key. \
286 * \
287 * The original key needn't be kept around any more. \
288 */ \
289 \
290void pre##_gcminit(pre##_gcmctx *ctx, const pre##_gcmkey *k, \
291 const void *n, size_t nsz) \
292 { ctx->k = *k; pre##_gcmreinit(ctx, n, nsz); } \
293 \
294/* --- @pre_gcmreinit@ --- * \
295 * \
296 * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \
297 * @const void *n@ = pointer to nonce \
298 * @size_t nsz@ = size of nonce \
299 * \
300 * Returns: --- \
301 * \
302 * Use: Reinitialize an GCM operation context, changing the \
303 * nonce. \
304 */ \
305 \
306void pre##_gcmreinit(pre##_gcmctx *ctx, const void *n, size_t nsz) \
307{ \
308 octet b[PRE##_BLKSZ]; \
309 const octet *q = n; \
310 size_t nblocks; \
311 unsigned i; \
312 \
313 /* Zero the counters. */ \
314 ctx->off = 0; ctx->len = 0; \
315 BLKC_ZERO(PRE, ctx->a); \
316 \
317 /* Calculate the initial counter from the nonce. */ \
318 if (nsz == PRE##_BLKSZ - 4) { \
319 /* Easy version: initialize the final word to 1 and copy the \
320 * remaining words from the nonce. (The spec shows the nonce and \
321 * counter the other way around for 64-bit block ciphers, but I'm \
322 * sure this is just a mistake.) \
323 */ \
324 \
325 for (i = 0; i < PRE##_BLKSZ/4 - 1; i++) \
326 { ctx->c0[i] = BLKC_LOAD_E(PRE)(q); q += 4; } \
327 ctx->c0[PRE##_BLKSZ/4 - 1] = BLKC_BWORD(PRE, 1); \
328 } else { \
329 /* Harder version: hash the nonce down with GHASH. */ \
330 \
331 BLKC_ZERO(PRE, ctx->c0); nblocks = 0; \
332 while (nsz >= PRE##_BLKSZ) { \
333 BLKC_XLOAD(PRE, ctx->c0, q); q += PRE##_BLKSZ; \
334 GCM_MULK(PRE, ctx->c0, ctx->k.ktab); \
335 nsz -= PRE##_BLKSZ; nblocks++; \
336 } \
337 if (nsz) { \
338 memcpy(b, q, nsz); memset(b + nsz, 0, PRE##_BLKSZ - nsz); \
339 BLKC_XLOAD(PRE, ctx->c0, b); \
340 GCM_MULK(PRE, ctx->c0, ctx->k.ktab); \
341 } \
342 gcm_ghashdone(&pre##_gcmparams, ctx->c0, ctx->k.ktab, \
343 0, 0, nblocks, nsz); \
344 } \
345 \
346 /* We must remember the initial counter for the final tag \
347 * calculation. (I conjecture that storing the final counter instead \
348 * would be just as secure, and require less state, but I've not \
349 * proven this, and anyway it wouldn't interoperate.) Copy it to \
350 * make the working counter. \
351 */ \
352 BLKC_MOVE(PRE, ctx->c, ctx->c0); \
353} \
354 \
355/* --- @pre_gcmencrypt@ --- * \
356 * \
357 * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \
358 * @const void *src@ = pointer to plaintext message chunk \
359 * @size_t sz@ = size of the plaintext \
360 * @buf *dst@ = a buffer to write the ciphertext to \
361 * \
362 * Returns: Zero on success; @-1@ on failure. \
363 * \
364 * Use: Encrypts a chunk of a plaintext message, writing a \
365 * chunk of ciphertext to the output buffer and updating \
366 * the operation state. \
367 * \
368 * For GCM, we always write a ciphertext chunk the same \
369 * size as the plaintext. The messing about with @buf@ \
370 * objects makes the interface consistent with other AEAD \
371 * schemes which can't do this. \
372 */ \
373 \
374int pre##_gcmencrypt(pre##_gcmctx *ctx, \
375 const void *src, size_t sz, buf *dst) \
376{ \
377 rsvr_plan plan; \
378 uint32 t[PRE##_BLKSZ/4]; \
379 const octet *p = src; \
380 octet *q, *r, y; \
381 \
382 /* Allocate space for the ciphertext. */ \
383 if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \
384 else q = 0; \
385 \
386 /* Determine the buffering plan. Our buffer is going to do double- \
387 * duty here. The end portion is going to contain mask from the \
388 * encrypted counter which we mix into the plaintext to encrypt it; \
389 * the start portion, which originally mask bytes we've already used, \
390 * will hold the output ciphertext, which will eventually be \
391 * collected into the GHASH state. \
392 */ \
393 rsvr_mkplan(&plan, &pre##_gcmpolicy, ctx->off, sz); \
394 \
395 /* Initial portion, fulfilled from the buffer. If the buffer is \
396 * empty, then that means that we haven't yet encrypted the current \
397 * counter, so we should do that and advance it. \
398 */ \
399 if (plan.head) { \
400 if (!ctx->off) { \
401 GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \
402 BLKC_STORE(PRE, ctx->b, t); \
403 } \
404 r = ctx->b + ctx->off; ctx->off += plan.head; \
405 while (plan.head--) { y = *p++ ^ *r; *r++ = *q++ = y; } \
406 } \
407 \
408 /* If we've filled up the buffer then we need to cycle the MAC and \
409 * reset the offset. \
410 */ \
411 if (plan.from_rsvr) { \
412 BLKC_XLOAD(PRE, ctx->a, ctx->b); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \
413 ctx->len++; ctx->off = 0; \
414 } \
415 \
416 /* Now to process the main body of the input. */ \
417 while (plan.from_input) { \
418 GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \
419 BLKC_XLOAD(PRE, t, p); p += PRE##_BLKSZ; \
420 BLKC_STORE(PRE, q, t); q += PRE##_BLKSZ; \
421 BLKC_XMOVE(PRE, ctx->a, t); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \
422 plan.from_input -= PRE##_BLKSZ; ctx->len++; \
423 } \
424 \
425 /* Finally, deal with any final portion. If there is one, we know \
426 * that the buffer is empty: we must have filled it above, or this \
427 * would all count as `initial' data. \
428 */ \
429 if (plan.tail) { \
430 GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \
431 BLKC_STORE(PRE, ctx->b, t); \
432 r = ctx->b; ctx->off += plan.tail; \
433 while (plan.tail--) { y = *p++ ^ *r; *r++ = *q++ = y; } \
434 } \
435 \
436 /* And we're done. */ \
437 return (0); \
438} \
439 \
440/* --- @pre_gcmdecrypt@ --- * \
441 * \
442 * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \
443 * @const void *src@ = pointer to ciphertext message chunk \
444 * @size_t sz@ = size of the ciphertext \
445 * @buf *dst@ = a buffer to write the plaintext to \
446 * \
447 * Returns: Zero on success; @-1@ on failure. \
448 * \
449 * Use: Decrypts a chunk of a ciphertext message, writing a \
450 * chunk of plaintext to the output buffer and updating \
451 * the operation state. \
452 * \
453 * For GCM, we always write a plaintext chunk the same \
454 * size as the ciphertext. The messing about with @buf@ \
455 * objects makes the interface consistent with other AEAD \
456 * schemes which can't do this. \
457 */ \
458 \
459int pre##_gcmdecrypt(pre##_gcmctx *ctx, \
460 const void *src, size_t sz, buf *dst) \
461{ \
462 rsvr_plan plan; \
463 uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \
464 const octet *p = src; \
465 octet *q, *r, y; \
466 \
467 /* Allocate space for the plaintext. */ \
468 if (sz) { q = buf_get(dst, sz); if (!q) return (-1); } \
469 else q = 0; \
470 \
471 /* Determine the buffering plan. Our buffer is going to do double- \
472 * duty here. The end portion is going to contain mask from the \
473 * encrypted counter which we mix into the plaintext to encrypt it; \
474 * the start portion, which originally mask bytes we've already used, \
475 * will hold the input ciphertext, which will eventually be \
476 * collected into the GHASH state. \
477 */ \
478 rsvr_mkplan(&plan, &pre##_gcmpolicy, ctx->off, sz); \
479 \
480 /* Initial portion, fulfilled from the buffer. If the buffer is \
481 * empty, then that means that we haven't yet encrypted the current \
482 * counter, so we should do that and advance it. \
483 */ \
484 if (plan.head) { \
485 if (!ctx->off) { \
486 GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \
487 BLKC_STORE(PRE, ctx->b, t); \
488 } \
489 r = ctx->b + ctx->off; ctx->off += plan.head; \
490 while (plan.head--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \
491 } \
492 \
493 /* If we've filled up the buffer then we need to cycle the MAC and \
494 * reset the offset. \
495 */ \
496 if (plan.from_rsvr) { \
497 BLKC_XLOAD(PRE, ctx->a, ctx->b); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \
498 ctx->len++; ctx->off = 0; \
499 } \
500 \
501 /* Now to process the main body of the input. */ \
502 while (plan.from_input) { \
503 GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \
504 BLKC_LOAD(PRE, u, p); p += PRE##_BLKSZ; \
505 BLKC_XSTORE(PRE, q, t, u); q += PRE##_BLKSZ; \
506 BLKC_XMOVE(PRE, ctx->a, u); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \
507 plan.from_input -= PRE##_BLKSZ; ctx->len++; \
508 } \
509 \
510 /* Finally, deal with any final portion. If there is one, we know \
511 * that the buffer is empty: we must have filled it above, or this \
512 * would all count as `initial' data. \
513 */ \
514 if (plan.tail) { \
515 GCM_STEP(PRE, ctx->c); pre##_eblk(&ctx->k.ctx, ctx->c, t); \
516 BLKC_STORE(PRE, ctx->b, t); \
517 r = ctx->b; ctx->off += plan.tail; \
518 while (plan.tail--) { y = *p++; *q++ = y ^ *r; *r++ = y; } \
519 } \
520 \
521 /* And we're done. */ \
522 return (0); \
523} \
524 \
525/* --- @pre_gcmtag@ --- * \
526 * \
527 * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \
528 * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \
529 * null \
530 * @octet *t@ = where to write a (full-length) tag \
531 * \
532 * Returns: --- \
533 * \
534 * Use: Finishes an GCM operation, by calculating the tag. \
535 */ \
536 \
537static void pre##_gcmtag(pre##_gcmctx *ctx, \
538 const pre##_gcmaadctx *aad, octet *t) \
539{ \
540 octet b[PRE##_BLKSZ]; \
541 uint32 u[PRE##_BLKSZ/4]; \
542 unsigned long n; \
543 \
544 /* Finish tagging the ciphertext. */ \
545 if (ctx->off) { \
546 memcpy(b, ctx->b, ctx->off); \
547 memset(b + ctx->off, 0, PRE##_BLKSZ - ctx->off); \
548 BLKC_XLOAD(PRE, ctx->a, b); GCM_MULK(PRE, ctx->a, ctx->k.ktab); \
549 } \
550 \
551 /* If there's no AAD, because the pointer is null or no data was \
552 * supplied, then apply that to the GHASH state. (Otherwise there's \
553 * nothing to do here.) \
554 */ \
555 if (aad && (aad->len || aad->off)) { \
556 BLKC_MOVE(PRE, u, aad->a); \
557 if (aad->off) { \
558 memcpy(b, aad->b, aad->off); \
559 memset(b + aad->off, 0, PRE##_BLKSZ - aad->off); \
560 BLKC_XLOAD(PRE, u, b); GCM_MULK(PRE, u, ctx->k.ktab); \
561 } \
562 n = ctx->len; if (ctx->off) n++; \
563 gcm_concat(&pre##_gcmparams, ctx->a, u, ctx->k.ktab, n); \
564 } \
565 \
566 /* Finish off the hash by appending the length. */ \
567 gcm_ghashdone(&pre##_gcmparams, ctx->a, ctx->k.ktab, \
568 aad ? aad->len : 0, aad ? aad->off : 0, \
569 ctx->len, ctx->off); \
570 \
571 /* Mask the hash and store. */ \
572 pre##_eblk(&ctx->k.ctx, ctx->c0, u); \
573 BLKC_XSTORE(PRE, t, ctx->a, u); \
574} \
575 \
576/* --- @pre_gcmencryptdone@ --- * \
577 * \
578 * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \
579 * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \
580 * null \
581 * @buf *dst@ = buffer for remaining ciphertext \
582 * @void *tag@ = where to write the tag \
583 * @size_t tsz@ = length of tag to store \
584 * \
585 * Returns: Zero on success; @-1@ on failure. \
586 * \
587 * Use: Completes an GCM encryption operation. The @aad@ \
588 * pointer may be null if there is no additional \
589 * authenticated data. GCM doesn't buffer ciphertext, but \
590 * the output buffer is provided anyway for consistency \
591 * with other AEAD schemes which don't have this property; \
592 * the function will fail if the output buffer is broken. \
593 */ \
594 \
595int pre##_gcmencryptdone(pre##_gcmctx *ctx, \
596 const pre##_gcmaadctx *aad, buf *dst, \
597 void *tag, size_t tsz) \
598{ \
599 octet t[PRE##_BLKSZ]; \
600 \
601 if (tsz > PRE##_BLKSZ) return (-1); \
602 if (!BOK(dst)) return (-1); \
603 pre##_gcmtag(ctx, aad, t); memcpy(tag, t, tsz); \
604 return (0); \
605} \
606 \
607/* --- @pre_gcmdecryptdone@ --- * \
608 * \
609 * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \
610 * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \
611 * null \
612 * @buf *dst@ = buffer for remaining plaintext \
613 * @const void *tag@ = tag to verify \
614 * @size_t tsz@ = length of tag \
615 * \
616 * Returns: @+1@ for complete success; @0@ if tag verification \
617 * failed; @-1@ for other kinds of errors. \
618 * \
619 * Use: Completes an GCM decryption operation. The @aad@ \
620 * pointer may be null if there is no additional \
621 * authenticated data. GCM doesn't buffer plaintext, but \
622 * the output buffer is provided anyway for consistency \
623 * with other AEAD schemes which don't have this property; \
624 * the function will fail if the output buffer is broken. \
625 */ \
626 \
627int pre##_gcmdecryptdone(pre##_gcmctx *ctx, \
628 const pre##_gcmaadctx *aad, buf *dst, \
629 const void *tag, size_t tsz) \
630{ \
631 octet t[PRE##_BLKSZ]; \
632 \
633 if (tsz > PRE##_BLKSZ) return (-1); \
634 if (!BOK(dst)) return (-1); \
635 pre##_gcmtag(ctx, aad, t); \
636 if (!ct_memeq(tag, t, tsz)) return (0); \
637 else return (+1); \
638} \
639 \
640/* --- Generic AEAD interface --- */ \
641 \
642typedef struct gactx { \
643 gaead_aad a; \
644 pre##_gcmaadctx aad; \
645} gactx; \
646 \
647static gaead_aad *gadup(const gaead_aad *a) \
648 { gactx *aad = S_CREATE(gactx); *aad = *(gactx *)a; return (&aad->a); } \
649 \
650static void gahash(gaead_aad *a, const void *h, size_t hsz) \
651 { gactx *aad = (gactx *)a; pre##_gcmaadhash(&aad->aad, h, hsz); } \
652 \
653static void gadestroy(gaead_aad *a) \
654 { gactx *aad = (gactx *)a; BURN(*aad); S_DESTROY(aad); } \
655 \
656static const gaead_aadops gaops = \
657 { &pre##_gcm, gadup, gahash, gadestroy }; \
658 \
659static gaead_aad *gaad(const pre##_gcmkey *k) \
660{ \
661 gactx *aad = S_CREATE(gactx); \
662 aad->a.ops = &gaops; \
663 pre##_gcmaadinit(&aad->aad, k); \
664 return (&aad->a); \
665} \
666 \
667typedef struct gectx { \
668 gaead_enc e; \
669 pre##_gcmctx ctx; \
670} gectx; \
671 \
672static gaead_aad *geaad(gaead_enc *e) \
673 { gectx *enc = (gectx *)e; return (gaad(&enc->ctx.k)); } \
674 \
675static int gereinit(gaead_enc *e, const void *n, size_t nsz, \
676 size_t hsz, size_t msz, size_t tsz) \
677{ \
678 gectx *enc = (gectx *)e; \
679 \
680 if (tsz > PRE##_BLKSZ) return (-1); \
681 pre##_gcmreinit(&enc->ctx, n, nsz); \
682 return (0); \
683} \
684 \
685static int geenc(gaead_enc *e, const void *m, size_t msz, buf *b) \
686{ \
687 gectx *enc = (gectx *)e; \
688 return (pre##_gcmencrypt(&enc->ctx, m, msz, b)); \
689} \
690 \
691static int gedone(gaead_enc *e, const gaead_aad *a, \
692 buf *b, void *t, size_t tsz) \
693{ \
694 gectx *enc = (gectx *)e; gactx *aad = (gactx *)a; \
695 assert(!a || a->ops == &gaops); \
696 return (pre##_gcmencryptdone(&enc->ctx, a ? &aad->aad : 0, b, t, tsz)); \
697} \
698 \
699static void gedestroy(gaead_enc *e) \
700 { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \
701 \
702static const gaead_encops geops = \
703 { &pre##_gcm, geaad, gereinit, geenc, gedone, gedestroy }; \
704 \
705typedef struct gdctx { \
706 gaead_dec d; \
707 pre##_gcmctx ctx; \
708} gdctx; \
709 \
710static gaead_aad *gdaad(gaead_dec *d) \
711 { gdctx *dec = (gdctx *)d; return (gaad(&dec->ctx.k)); } \
712 \
713static int gdreinit(gaead_dec *d, const void *n, size_t nsz, \
714 size_t hsz, size_t csz, size_t tsz) \
715{ \
716 gdctx *dec = (gdctx *)d; \
717 \
718 if (tsz > PRE##_BLKSZ) return (-1); \
719 pre##_gcmreinit(&dec->ctx, n, nsz); \
720 return (0); \
721} \
722 \
723static int gddec(gaead_dec *d, const void *c, size_t csz, buf *b) \
724{ \
725 gdctx *dec = (gdctx *)d; \
726 return (pre##_gcmdecrypt(&dec->ctx, c, csz, b)); \
727} \
728 \
729static int gddone(gaead_dec *d, const gaead_aad *a, \
730 buf *b, const void *t, size_t tsz) \
731{ \
732 gdctx *dec = (gdctx *)d; gactx *aad = (gactx *)a; \
733 assert(!a || a->ops == &gaops); \
734 return (pre##_gcmdecryptdone(&dec->ctx, a ? &aad->aad : 0, b, t, tsz)); \
735} \
736 \
737static void gddestroy(gaead_dec *d) \
738 { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \
739 \
740static const gaead_decops gdops = \
741 { &pre##_gcm, gdaad, gdreinit, gddec, gddone, gddestroy }; \
742 \
743typedef struct gkctx { \
744 gaead_key k; \
745 pre##_gcmkey key; \
746} gkctx; \
747 \
748static gaead_aad *gkaad(const gaead_key *k) \
749 { gkctx *key = (gkctx *)k; return (gaad(&key->key)); } \
750 \
751static gaead_enc *gkenc(const gaead_key *k, const void *n, size_t nsz, \
752 size_t hsz, size_t msz, size_t tsz) \
753{ \
754 gkctx *key = (gkctx *)k; \
755 gectx *enc = S_CREATE(gectx); \
756 \
757 enc->e.ops = &geops; \
758 pre##_gcminit(&enc->ctx, &key->key, n, nsz); \
759 return (&enc->e); \
760} \
761 \
762static gaead_dec *gkdec(const gaead_key *k, const void *n, size_t nsz, \
763 size_t hsz, size_t csz, size_t tsz) \
764{ \
765 gkctx *key = (gkctx *)k; \
766 gdctx *dec = S_CREATE(gdctx); \
767 \
768 dec->d.ops = &gdops; \
769 pre##_gcminit(&dec->ctx, &key->key, n, nsz); \
770 return (&dec->d); \
771} \
772 \
773static void gkdestroy(gaead_key *k) \
774 { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \
775 \
776static const gaead_keyops gkops = \
777 { &pre##_gcm, gkaad, gkenc, gkdec, gkdestroy }; \
778 \
779static gaead_key *gckey(const void *k, size_t ksz) \
780{ \
781 gkctx *key = S_CREATE(gkctx); \
782 key->k.ops = &gkops; \
783 pre##_gcmsetkey(&key->key, k, ksz); \
784 return (&key->k); \
785} \
786 \
787const gcaead pre##_gcm = { \
788 name "-gcm", \
789 pre##_keysz, pre##_gcmnoncesz, pre##_gcmtagsz, \
790 PRE##_BLKSZ, 0, 0, 0, \
791 gckey \
792}; \
793 \
794GCM_TESTX(PRE, pre, name, fname)
795
796/*----- Test rig ----------------------------------------------------------*/
797
798#define GCM_TEST(PRE, pre) GCM_TESTX(PRE, pre, #pre, #pre)
799
800/* --- @GCM_TEST@ --- *
801 *
802 * Arguments: @PRE, pre@ = prefixes for the underlying block cipher
803 *
804 * Use: Standard test rig for GCM functions.
805 */
806
807#ifdef TEST_RIG
808
809#include <stdio.h>
810
811#include <mLib/dstr.h>
812#include <mLib/quis.h>
813#include <mLib/testrig.h>
814
815#define GCM_TESTX(PRE, pre, name, fname) \
816 \
817static int gcmverify(dstr *v) \
818{ \
819 pre##_gcmkey key; \
820 pre##_gcmaadctx aad; \
821 pre##_gcmctx ctx; \
822 int ok = 1, win; \
823 int i; \
824 octet *p; \
825 int szs[] = { 1, 7, 192, -1, 0 }, *ip; \
826 size_t hsz, msz; \
827 dstr d = DSTR_INIT, t = DSTR_INIT; \
828 buf b; \
829 \
830 dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \
831 dstr_ensure(&t, v[5].len); t.len = v[5].len; \
832 \
833 pre##_gcmsetkey(&key, v[0].buf, v[0].len); \
834 \
835 for (ip = szs; *ip; ip++) { \
836 \
837 pre##_gcminit(&ctx, &key, (octet *)v[1].buf, v[1].len); \
838 \
839 i = *ip; \
840 hsz = v[2].len; \
841 if (i == -1) i = hsz; \
842 if (i > hsz) continue; \
843 p = (octet *)v[2].buf; \
844 pre##_gcmaadinit(&aad, &key); \
845 while (hsz) { \
846 if (i > hsz) i = hsz; \
847 pre##_gcmaadhash(&aad, p, i); \
848 p += i; hsz -= i; \
849 } \
850 \
851 buf_init(&b, d.buf, d.sz); \
852 i = *ip; \
853 msz = v[3].len; \
854 if (i == -1) i = msz; \
855 if (i > msz) continue; \
856 p = (octet *)v[3].buf; \
857 while (msz) { \
858 if (i > msz) i = msz; \
859 if (pre##_gcmencrypt(&ctx, p, i, &b)) { \
860 puts("!! gcmencrypt reports failure"); \
861 goto fail_enc; \
862 } \
863 p += i; msz -= i; \
864 } \
865 \
866 if (pre##_gcmencryptdone(&ctx, &aad, &b, (octet *)t.buf, t.len)) { \
867 puts("!! gcmencryptdone reports failure"); \
868 goto fail_enc; \
869 } \
870 d.len = BLEN(&b); \
871 \
872 if (d.len != v[4].len || \
873 memcmp(d.buf, v[4].buf, v[4].len) != 0 || \
874 memcmp(t.buf, v[5].buf, v[5].len) != 0) { \
875 fail_enc: \
876 printf("\nfail encrypt:\n\tstep = %i", *ip); \
877 fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \
878 fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \
879 fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \
880 fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \
881 fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \
882 fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \
883 fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \
884 fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \
885 putchar('\n'); \
886 ok = 0; \
887 } \
888 \
889 pre##_gcminit(&ctx, &key, (octet *)v[1].buf, v[1].len); \
890 \
891 buf_init(&b, d.buf, d.sz); \
892 i = *ip; \
893 msz = v[4].len; \
894 if (i == -1) i = msz; \
895 if (i > msz) continue; \
896 p = (octet *)v[4].buf; \
897 while (msz) { \
898 if (i > msz) i = msz; \
899 if (pre##_gcmdecrypt(&ctx, p, i, &b)) { \
900 puts("!! gcmdecrypt reports failure"); \
901 win = 0; goto fail_dec; \
902 } \
903 p += i; msz -= i; \
904 } \
905 \
906 win = pre##_gcmdecryptdone(&ctx, &aad, &b, \
907 (octet *)v[5].buf, v[5].len); \
908 if (win < 0) { \
909 puts("!! gcmdecryptdone reports failure"); \
910 goto fail_dec; \
911 } \
912 d.len = BLEN(&b); \
913 \
914 if (d.len != v[3].len || !win || \
915 memcmp(d.buf, v[3].buf, v[3].len) != 0) { \
916 fail_dec: \
917 printf("\nfail decrypt:\n\tstep = %i", *ip); \
918 fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \
919 fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \
920 fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \
921 fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \
922 fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \
923 fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \
924 fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \
925 printf("\n\tverify %s", win ? "ok" : "FAILED"); \
926 putchar('\n'); \
927 ok = 0; \
928 } \
929 } \
930 \
931 dstr_destroy(&d); dstr_destroy(&t); \
932 return (ok); \
933} \
934 \
935static test_chunk aeaddefs[] = { \
936 { name "-gcm", gcmverify, \
937 { &type_hex, &type_hex, &type_hex, &type_hex, \
938 &type_hex, &type_hex, 0 } }, \
939 { 0, 0, { 0 } } \
940}; \
941 \
942int main(int argc, char *argv[]) \
943{ \
944 ego(argv[0]); \
945 test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \
946 return (0); \
947}
948
949#else
950# define GCM_TESTX(PRE, pre, name, fname)
951#endif
952
953/*----- That's all, folks -------------------------------------------------*/
954
955#ifdef __cplusplus
956 }
957#endif
958
959#endif