Deploy the new <ctype.h> and `foocmp' macros from mLib.
[catacomb] / symm / ocb3-def.h
1 /* -*-c-*-
2 *
3 * The OCB3 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_OCB3_DEF_H
29 #define CATACOMB_OCB3_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_RSVR_H
59 # include "rsvr.h"
60 #endif
61
62 #ifndef CATACOMB_PARANOIA_H
63 # include "paranoia.h"
64 #endif
65
66 /*----- Macros ------------------------------------------------------------*/
67
68 #define OCB3_TSHIFT(PRE) BLKC_GLUE(OCB3_TSHIFT_, BLKC_BITS(PRE))
69 #define OCB3_TSHIFT_64 2
70 #define OCB3_TSHIFT_96 1
71 #define OCB3_TSHIFT_128 1
72 #define OCB3_TSHIFT_192 0
73 #define OCB3_TSHIFT_256 0
74
75 #define OCB3_STRETCHMASK(PRE) BLKC_GLUE(OCB3_STRETCHMASK_, BLKC_BITS(PRE))
76 #define OCB3_STRETCHMASK_64 0x1f
77 #define OCB3_STRETCHMASK_96 0x3f
78 #define OCB3_STRETCHMASK_128 0x3f
79 #define OCB3_STRETCHMASK_192 0x7f
80 #define OCB3_STRETCHMASK_256 0xff
81
82 #define OCB3_STRETCHSHIFT(PRE) BLKC_GLUE(OCB3_STRETCHSHIFT_, BLKC_BITS(PRE))
83 #define OCB3_STRETCHSHIFT_64 25
84 #define OCB3_STRETCHSHIFT_96 33
85 #define OCB3_STRETCHSHIFT_128 8
86 #define OCB3_STRETCHSHIFT_192 40
87 #define OCB3_STRETCHSHIFT_256 1
88
89 /* --- @OCB3_DEF@ --- *
90 *
91 * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher
92 *
93 * Use: Creates an implementation for the OCB3 authenticated-
94 * encryption mode.
95 */
96
97 #define OCB3_DEF(PRE, pre) OCB3_DEFX(PRE, pre, #pre, #pre)
98
99 #define OCB3_DEFX(PRE, pre, name, fname) \
100 \
101 static const rsvr_policy pre##_ocb3policy = \
102 { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \
103 \
104 const octet \
105 pre##_ocb3noncesz[] = { KSZ_RANGE, OCB3_NSZMAX(PRE), \
106 0, OCB3_NSZMAX(PRE), 1 }, \
107 pre##_ocb3tagsz[] = { KSZ_RANGE, PRE##_BLKSZ, 0, PRE##_BLKSZ, 1 }; \
108 \
109 /* --- @pre_ocb3setkey@ --- * \
110 * \
111 * Arguments: @pre_ocb3key *key@ = pointer to OCB3 key block \
112 * @ocnst void *k@ = pointer to key material \
113 * @size_t ksz@ = size of key material \
114 * \
115 * Returns: --- \
116 * \
117 * Use: Initializes a OCB3 key. This can be used for \
118 * several encryption/or MAC operations. \
119 */ \
120 \
121 void pre##_ocb3setkey(pre##_ocb3key *key, const void *k, size_t ksz) \
122 { \
123 unsigned i; \
124 \
125 pre##_init(&key->ctx, k, ksz); \
126 BLKC_ZERO(PRE, key->lstar); \
127 pre##_eblk(&key->ctx, key->lstar, key->lstar); \
128 BLKC_BLSHIFT(PRE, IRRED, key->ldollar, key->lstar); \
129 BLKC_BLSHIFT(PRE, IRRED, key->lmask[0], key->ldollar); \
130 for (i = 1; i < OCB_NCALC; i++) \
131 BLKC_BLSHIFT(PRE, IRRED, key->lmask[i], key->lmask[i - 1]); \
132 } \
133 \
134 /* --- @pre_ocb3aadinit@ --- * \
135 * \
136 * Arguments: @pre_ocb3aadctx *aad@ = pointer to context block \
137 * @pre_ocb3key *k@ = key block \
138 * \
139 * Returns: --- \
140 * \
141 * Use: Initializes an OCB3 AAD (`additional authenticated \
142 * data') context associated witha a given key. \
143 * AAD contexts can be copied and/or reused, saving time \
144 * if the AAD for a number of messages has a common \
145 * prefix. \
146 * \
147 * The @key@ doesn't need to be kept around. \
148 */ \
149 \
150 void pre##_ocb3aadinit(pre##_ocb3aadctx *aad, const pre##_ocb3key *k) \
151 { \
152 aad->k = *k; \
153 aad->off = 0; aad->i = 1; \
154 BLKC_ZERO(PRE, aad->a); \
155 BLKC_ZERO(PRE, aad->o); \
156 } \
157 \
158 /* --- @pre_ocb3aadhash@ --- * \
159 * \
160 * Arguments: @pre_ocb3aadctx *aad@ = pointer to context block \
161 * @ocnst void *p@ = pointer to message buffer \
162 * @size_t sz@ = size of message buffer \
163 * \
164 * Returns: --- \
165 * \
166 * Use: Hashes some AAD input data. \
167 */ \
168 \
169 void pre##_ocb3aadhash(pre##_ocb3aadctx *aad, const void *p, size_t sz) \
170 { \
171 rsvr_state st; \
172 uint32 t[PRE##_BLKSZ/4]; \
173 const octet *q; \
174 \
175 rsvr_setup(&st, &pre##_ocb3policy, aad->b, &aad->off, p, sz); \
176 RSVR_DO(&st) while ((q = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \
177 OCB_OFFSET(PRE, aad->o, aad->k.lmask, aad->i++); \
178 BLKC_LOAD(PRE, t, q); BLKC_XMOVE(PRE, t, aad->o); \
179 pre##_eblk(&aad->k.ctx, t, t); \
180 BLKC_XMOVE(PRE, aad->a, t); \
181 } \
182 } \
183 \
184 /* --- @pre_ocb3augment@ --- * \
185 * \
186 * Arguments: @uint32 *nn@ = where to write the augmented nonce \
187 * @const octet *n@ = pointer to input nonce data \
188 * @size_t nsz@ = size of input nonce \
189 * @size_t tsz@ = tag length \
190 * \
191 * Returns: The nonce shift index. \
192 * \
193 * Use: Constructs the augmented base nonce, mixing in the tag \
194 * length appropriately. \
195 */ \
196 \
197 static unsigned pre##_ocb3augment(uint32 *nn, const octet *n, \
198 size_t nsz, size_t tsz) \
199 { \
200 octet b[PRE##_BLKSZ] = { 0 }; \
201 uint32 t; \
202 unsigned nix; \
203 \
204 b[0] = 8*(tsz%PRE##_BLKSZ) << OCB3_TSHIFT(PRE); \
205 b[PRE##_BLKSZ - nsz - 1] |= 0x01; \
206 memcpy(b + PRE##_BLKSZ - nsz, n, nsz); \
207 BLKC_LOAD(PRE, nn, b); \
208 t = BLKC_BWORD(PRE, nn[PRE##_BLKSZ/4 - 1]); \
209 nix = t&OCB3_STRETCHMASK(PRE); \
210 t &= ~(uint32)OCB3_STRETCHMASK(PRE); \
211 nn[PRE##_BLKSZ/4 - 1] = BLKC_BWORD(PRE, t); \
212 return (nix); \
213 } \
214 \
215 /* --- @pre_ocb3stretch@ --- * \
216 * \
217 * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \
218 * \
219 * Returns: --- \
220 * \
221 * Use: Stretches the augmented nonce. \
222 */ \
223 \
224 static void pre##_ocb3stretch(pre##_ocb3ctx *ctx) \
225 { \
226 unsigned nw = OCB3_STRETCHSHIFT(PRE)/32, \
227 nl = OCB3_STRETCHSHIFT(PRE)%32, nr = 32 - nl; \
228 unsigned i; \
229 uint32 c = 0, t, u; \
230 \
231 pre##_eblk(&ctx->k.ctx, ctx->nbase, ctx->nstretch); \
232 for (i = 0; i < PRE##_BLKSZ/4; i++) \
233 ctx->nstretch[i] = BLKC_BWORD(PRE, ctx->nstretch[i]); \
234 i = PRE##_BLKSZ/4; \
235 while (i > PRE##_BLKSZ/4 - nw) \
236 { i--; ctx->nstretch[i + PRE##_BLKSZ/4] = ctx->nstretch[i]; } \
237 while (i--) { \
238 u = ctx->nstretch[i]; t = ctx->nstretch[i + nw]; \
239 ctx->nstretch[i + PRE##_BLKSZ/4] = u ^ (t << nl) ^ c; \
240 if (nr < 32) c = U32(t) >> nr; \
241 } \
242 } \
243 \
244 /* --- @pre_ocb3shift@ --- * \
245 * \
246 * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \
247 * @unsigned nix@ = nonce index \
248 * \
249 * Returns: --- \
250 * \
251 * Use: Extracts a chunk out of the OCB3 stretched nonce and \
252 * writes it to @ctx->o@. \
253 */ \
254 \
255 static void pre##_ocb3shift(pre##_ocb3ctx *ctx, unsigned nix) \
256 { \
257 unsigned nw = nix/32, nl = nix%32, nr = 32 - nl; \
258 uint32 c, t; \
259 unsigned i; \
260 \
261 i = PRE##_BLKSZ/4; \
262 if (nr < 32) c = U32(ctx->nstretch[PRE##_BLKSZ/4 + nw]) >> nr; \
263 else c = 0; \
264 while (i--) { \
265 t = ctx->nstretch[i + nw]; \
266 ctx->o[i] = BLKC_BWORD(PRE, (t << nl) | c); \
267 if (nr < 32) c = U32(t) >> nr; \
268 } \
269 } \
270 \
271 /* --- @pre_ocb3init@ --- * \
272 * \
273 * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \
274 * @const pre_ocb3key *key@ = pointer to key block \
275 * @const void *n@ = pointer to nonce \
276 * @size_t nsz@ = size of nonce \
277 * @size_t tsz@ = tag length \
278 * \
279 * Returns: Zero on success, @-1@ if the nonce or tag length is \
280 * bad. \
281 * \
282 * Use: Initialize an OCB3 operation context with a given key. \
283 * \
284 * The original key needn't be kept around any more. \
285 */ \
286 \
287 int pre##_ocb3init(pre##_ocb3ctx *ctx, const pre##_ocb3key *k, \
288 const void *n, size_t nsz, size_t tsz) \
289 { \
290 unsigned nix; \
291 \
292 /* Preflight checking. */ \
293 if (nsz > OCB3_NSZMAX(PRE)) return (-1); \
294 if (tsz > PRE##_BLKSZ) return (-1); \
295 \
296 /* Copy over the blockcipher key. */ \
297 ctx->k = *k; \
298 \
299 /* Sort out the nonce. */ \
300 nix = pre##_ocb3augment(ctx->nbase, n, nsz, tsz); \
301 ctx->nix = nix; ctx->tsz = tsz; \
302 pre##_ocb3stretch(ctx); \
303 pre##_ocb3shift(ctx, nix); \
304 \
305 /* Other random things. */ \
306 ctx->off = 0; ctx->i = 1; \
307 BLKC_ZERO(PRE, ctx->a); \
308 \
309 /* Done. */ \
310 return (0); \
311 } \
312 \
313 /* --- @pre_ocb3reinit@ --- * \
314 * \
315 * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \
316 * @const void *n@ = pointer to nonce \
317 * @size_t nsz@ = size of nonce \
318 * @size_t tsz@ = tag length \
319 * \
320 * Returns: Zero on success, @-1@ if the nonce or tag length is \
321 * bad. \
322 * \
323 * Use: Reinitialize an OCB3 operation context, changing the \
324 * nonce and/or tag length. \
325 */ \
326 \
327 int pre##_ocb3reinit(pre##_ocb3ctx *ctx, \
328 const void *n, size_t nsz, size_t tsz) \
329 { \
330 uint32 t[PRE##_BLKSZ/4]; \
331 unsigned nix, i; \
332 \
333 /* Preflight checking. */ \
334 if (nsz > OCB3_NSZMAX(PRE)) return (-1); \
335 if (tsz > PRE##_BLKSZ) return (-1); \
336 \
337 /* Sort out the nonce. */ \
338 nix = pre##_ocb3augment(t, n, nsz, tsz); \
339 for (i = 0; i < PRE##_BLKSZ/4; i++) { \
340 if (t[i] == ctx->nbase[i]) continue; \
341 ctx->nix = nix; ctx->tsz = tsz; \
342 BLKC_MOVE(PRE, ctx->nbase, t); pre##_ocb3stretch(ctx); \
343 break; \
344 } \
345 pre##_ocb3shift(ctx, nix); \
346 \
347 /* Other random things. */ \
348 ctx->off = 0; ctx->i = 1; \
349 BLKC_ZERO(PRE, ctx->a); \
350 \
351 /* Done. */ \
352 return (0); \
353 } \
354 \
355 /* --- @pre_ocb3step@ --- * \
356 * \
357 * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 context \
358 * \
359 * Returns: --- \
360 * \
361 * Use: Reinitialize an OCB3 operation context, stepping to \
362 * the `next' nonce along. \
363 */ \
364 \
365 void pre##_ocb3step(pre##_ocb3ctx *ctx) \
366 { \
367 /* Sort out the nonce. */ \
368 if (ctx->nix < OCB3_STRETCHMASK(PRE)) \
369 pre##_ocb3shift(ctx, ++ctx->nix); \
370 else { \
371 ctx->nix = 0; \
372 BLKC_BADD(PRE, ctx->nbase, OCB3_STRETCHMASK(PRE) + 1); \
373 pre##_ocb3stretch(ctx); \
374 pre##_ocb3shift(ctx, 0); \
375 } \
376 \
377 /* Other random things. */ \
378 ctx->off = 0; ctx->i = 1; \
379 BLKC_ZERO(PRE, ctx->a); \
380 } \
381 \
382 /* --- @pre_ocb3encrypt@ --- * \
383 * \
384 * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 operation context \
385 * @const void *src@ = pointer to plaintext message chunk \
386 * @size_t sz@ = size of the plaintext \
387 * @buf *dst@ = a buffer to write the ciphertext to \
388 * \
389 * Returns: Zero on success; @-1@ on failure. \
390 * \
391 * Use: Encrypts a chunk of a plaintext message, writing a \
392 * chunk of ciphertext to the output buffer and updating \
393 * the operation state. \
394 * \
395 * Note that OCB3 delays output if its input is not a \
396 * whole number of blocks. This means that the output \
397 * might be smaller or larger the input by up to the block \
398 * size. \
399 */ \
400 \
401 int pre##_ocb3encrypt(pre##_ocb3ctx *ctx, \
402 const void *src, size_t sz, buf *dst) \
403 { \
404 rsvr_state st; \
405 size_t osz; \
406 uint32 t[PRE##_BLKSZ/4]; \
407 const octet *p; \
408 octet *q; \
409 \
410 /* Figure out what we're going to do. */ \
411 rsvr_setup(&st, &pre##_ocb3policy, ctx->b, &ctx->off, src, sz); \
412 \
413 /* Determine the output size and verify that there is enough \
414 * space. \
415 */ \
416 osz = st.plan.from_rsvr + st.plan.from_input; \
417 if (!osz) q = 0; \
418 else { q = buf_get(dst, osz); if (!q) return (-1); } \
419 \
420 /* Process the input in whole blocks at a time. */ \
421 RSVR_DO(&st) while ((p = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \
422 OCB_OFFSET(PRE, ctx->o, ctx->k.lmask, ctx->i++); \
423 BLKC_LOAD(PRE, t, p); BLKC_XMOVE(PRE, ctx->a, t); \
424 BLKC_XMOVE(PRE, t, ctx->o); pre##_eblk(&ctx->k.ctx, t, t); \
425 BLKC_XSTORE(PRE, q, t, ctx->o); q += PRE##_BLKSZ; \
426 } \
427 \
428 /* Done. */ \
429 return (0); \
430 } \
431 \
432 /* --- @pre_ocb3decrypt@ --- * \
433 * \
434 * Arguments: @pre_ocb3ctx *ctx@ = pointer to OCB3 operation context \
435 * @const void *src@ = pointer to ciphertext message chunk \
436 * @size_t sz@ = size of the ciphertext \
437 * @buf *dst@ = a buffer to write the plaintext to \
438 * \
439 * Returns: Zero on success; @-1@ on failure. \
440 * \
441 * Use: Decrypts a chunk of a ciphertext message, writing a \
442 * chunk of plaintext to the output buffer and updating \
443 * the operation state. \
444 * \
445 * Note that OCB3 delays output if its input is not a \
446 * whole number of blocks. This means that the output \
447 * might be smaller or larger the input by up to the block \
448 * size. \
449 */ \
450 \
451 int pre##_ocb3decrypt(pre##_ocb3ctx *ctx, \
452 const void *src, size_t sz, buf *dst) \
453 { \
454 rsvr_state st; \
455 size_t osz; \
456 uint32 t[PRE##_BLKSZ/4]; \
457 const octet *p; \
458 octet *q; \
459 \
460 /* Figure out what we're going to do. */ \
461 rsvr_setup(&st, &pre##_ocb3policy, ctx->b, &ctx->off, src, sz); \
462 \
463 /* Determine the output size and verify that there is enough \
464 * space. \
465 */ \
466 osz = st.plan.from_rsvr + st.plan.from_input; \
467 if (!osz) q = 0; \
468 else { q = buf_get(dst, osz); if (!q) return (-1); } \
469 \
470 /* Process the input in whole blocks at a time. */ \
471 RSVR_DO(&st) while ((p = RSVR_NEXT(&st, PRE##_BLKSZ)) != 0) { \
472 OCB_OFFSET(PRE, ctx->o, ctx->k.lmask, ctx->i++); \
473 BLKC_LOAD(PRE, t, p); \
474 BLKC_XMOVE(PRE, t, ctx->o); pre##_dblk(&ctx->k.ctx, t, t); \
475 BLKC_XMOVE(PRE, t, ctx->o); BLKC_XMOVE(PRE, ctx->a, t); \
476 BLKC_STORE(PRE, q, t); q += PRE##_BLKSZ; \
477 } \
478 \
479 /* Done. */ \
480 return (0); \
481 } \
482 \
483 /* --- @pre_ocb3tag@ --- * \
484 * \
485 * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \
486 * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \
487 * or null \
488 * @buf *dst@ = buffer for remaining ciphertext \
489 * \
490 * Returns: Zero on success; @-1@ on failure. \
491 * \
492 * Use: Common end-of-message handling for encryption and \
493 * decryption. The caller is expected to have processed \
494 * the last partial block, mixing the padded plaintext \
495 * into the checksum and leaving the partial output in \
496 * the context's buffer: this function will write the \
497 * output to the caller's output buffer. It will compute \
498 * the final full-length tag and leave it in the \
499 * context's buffer. \
500 */ \
501 \
502 static int pre##_ocb3tag(pre##_ocb3ctx *ctx, \
503 const pre##_ocb3aadctx *aad, buf *dst) \
504 { \
505 octet *q; \
506 \
507 /* Arrange space for the final output (if any). */ \
508 if (!ctx->off) { q = 0; if (!BOK(dst)) return (-1); } \
509 else { q = buf_get(dst, ctx->off); if (!q) return (-1); } \
510 \
511 /* Deal with whatever's left in the input buffer, if anything */ \
512 if (ctx->off) memcpy(q, ctx->b, ctx->off); \
513 \
514 /* Wrap up the checksum calculation. */ \
515 BLKC_XMOVE(PRE, ctx->o, ctx->k.ldollar); \
516 BLKC_XMOVE(PRE, ctx->a, ctx->o); \
517 pre##_eblk(&ctx->k.ctx, ctx->a, ctx->a); \
518 \
519 /* Finish off the AAD processing. */ \
520 if (aad) { \
521 if (aad->i) BLKC_XMOVE(PRE, ctx->a, aad->a); \
522 if (aad->off) { \
523 memcpy(ctx->b, aad->b, aad->off); \
524 ctx->b[aad->off] = 0x80; \
525 memset(ctx->b + aad->off + 1, 0, PRE##_BLKSZ - aad->off - 1); \
526 BLKC_LOAD(PRE, ctx->o, ctx->b); \
527 BLKC_XMOVE(PRE, ctx->o, aad->o); \
528 BLKC_XMOVE(PRE, ctx->o, ctx->k.lstar); \
529 pre##_eblk(&ctx->k.ctx, ctx->o, ctx->o); \
530 BLKC_XMOVE(PRE, ctx->a, ctx->o); \
531 } \
532 } \
533 \
534 /* Write the final tag. */ \
535 BLKC_STORE(PRE, ctx->b, ctx->a); \
536 \
537 /* Done. */ \
538 return (0); \
539 } \
540 \
541 /* --- @pre_ocb3encryptdone@ --- * \
542 * \
543 * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \
544 * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \
545 * or null \
546 * @buf *dst@ = buffer for remaining ciphertext \
547 * @void *tag@ = where to write the tag \
548 * @size_t tsz@ = length of tag to store \
549 * \
550 * Returns: Zero on success; @-1@ on failure. \
551 * \
552 * Use: Completes an OCB3 encryption operation. The @aad@ \
553 * pointer may be null if there is no additional \
554 * authenticated data. OCB3 delays output, so this will \
555 * cause any remaining buffered plaintext to be encrypted \
556 * and written to @dst@. Anyway, the function will fail \
557 * if the output buffer is broken. \
558 */ \
559 \
560 int pre##_ocb3encryptdone(pre##_ocb3ctx *ctx, \
561 const pre##_ocb3aadctx *aad, buf *dst, \
562 void *tag, size_t tsz) \
563 { \
564 uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \
565 \
566 /* Deal with any final partial block. */ \
567 if (ctx->off) { \
568 BLKC_XMOVE(PRE, ctx->o, ctx->k.lstar); \
569 ctx->b[ctx->off] = 0x80; \
570 memset(ctx->b + ctx->off + 1, 0, PRE##_BLKSZ - ctx->off - 1); \
571 BLKC_LOAD(PRE, t, ctx->b); \
572 BLKC_XMOVE(PRE, ctx->a, t); \
573 pre##_eblk(&ctx->k.ctx, ctx->o, u); \
574 BLKC_XSTORE(PRE, ctx->b, t, u); \
575 } \
576 \
577 /* Return the tag. */ \
578 assert(tsz == ctx->tsz); \
579 if (pre##_ocb3tag(ctx, aad, dst)) return (-1); \
580 memcpy(tag, ctx->b, tsz); \
581 return (0); \
582 } \
583 \
584 /* --- @pre_ocb3decryptdone@ --- * \
585 * \
586 * Arguments: @pre_ocb3ctx *ctx@ = pointer to an OCB3 context \
587 * @const pre_ocb3aadctx *aad@ = pointer to AAD context, \
588 * or null \
589 * @buf *dst@ = buffer for remaining plaintext \
590 * @const void *tag@ = tag to verify \
591 * @size_t tsz@ = length of tag \
592 * \
593 * Returns: @+1@ for complete success; @0@ if tag verification \
594 * failed; @-1@ for other kinds of errors. \
595 * \
596 * Use: Completes an OCB3 decryption operation. The @aad@ \
597 * pointer may be null if there is no additional \
598 * authenticated data. OCB3 delays output, so this will \
599 * cause any remaining buffered ciphertext to be decrypted \
600 * and written to @dst@. Anyway, the function will fail \
601 * if the output buffer is broken. \
602 */ \
603 \
604 int pre##_ocb3decryptdone(pre##_ocb3ctx *ctx, \
605 const pre##_ocb3aadctx *aad, buf *dst, \
606 const void *tag, size_t tsz) \
607 { \
608 uint32 t[PRE##_BLKSZ/4], u[PRE##_BLKSZ]; \
609 \
610 /* Deal with any final partial block. */ \
611 if (ctx->off) { \
612 BLKC_XMOVE(PRE, ctx->o, ctx->k.lstar); \
613 BLKC_LOAD(PRE, t, ctx->b); \
614 pre##_eblk(&ctx->k.ctx, ctx->o, u); \
615 BLKC_XSTORE(PRE, ctx->b, t, u); \
616 ctx->b[ctx->off] = 0x80; \
617 memset(ctx->b + ctx->off + 1, 0, PRE##_BLKSZ - ctx->off - 1); \
618 BLKC_XLOAD(PRE, ctx->a, ctx->b); \
619 } \
620 \
621 /* Check the tag. */ \
622 assert(tsz == ctx->tsz); \
623 if (pre##_ocb3tag(ctx, aad, dst)) return (-1); \
624 if (ct_memeq(tag, ctx->b, ctx->tsz)) return (+1); \
625 else return (0); \
626 } \
627 \
628 /* --- Generic AEAD interface --- */ \
629 \
630 typedef struct gactx { \
631 gaead_aad a; \
632 pre##_ocb3aadctx aad; \
633 } gactx; \
634 \
635 static gaead_aad *gadup(const gaead_aad *a) \
636 { gactx *aad = S_CREATE(gactx); *aad = *(gactx *)a; return (&aad->a); } \
637 \
638 static void gahash(gaead_aad *a, const void *h, size_t hsz) \
639 { gactx *aad = (gactx *)a; pre##_ocb3aadhash(&aad->aad, h, hsz); } \
640 \
641 static void gadestroy(gaead_aad *a) \
642 { gactx *aad = (gactx *)a; BURN(*aad); S_DESTROY(aad); } \
643 \
644 static const gaead_aadops gaops = \
645 { &pre##_ocb3, gadup, gahash, gadestroy }; \
646 \
647 static gaead_aad *gaad(const pre##_ocb3key *k) \
648 { \
649 gactx *aad = S_CREATE(gactx); \
650 aad->a.ops = &gaops; \
651 pre##_ocb3aadinit(&aad->aad, k); \
652 return (&aad->a); \
653 } \
654 \
655 typedef struct gectx { \
656 gaead_enc e; \
657 pre##_ocb3ctx ctx; \
658 } gectx; \
659 \
660 static gaead_aad *geaad(gaead_enc *e) \
661 { gectx *enc = (gectx *)e; return (gaad(&enc->ctx.k)); } \
662 \
663 static int gereinit(gaead_enc *e, const void *n, size_t nsz, \
664 size_t hsz, size_t msz, size_t tsz) \
665 { \
666 gectx *enc = (gectx *)e; \
667 return (pre##_ocb3reinit(&enc->ctx, n, nsz, tsz)); \
668 } \
669 \
670 static int geenc(gaead_enc *e, const void *m, size_t msz, buf *b) \
671 { \
672 gectx *enc = (gectx *)e; \
673 return (pre##_ocb3encrypt(&enc->ctx, m, msz, b)); \
674 } \
675 \
676 static int gedone(gaead_enc *e, const gaead_aad *a, \
677 buf *b, void *t, size_t tsz) \
678 { \
679 gectx *enc = (gectx *)e; gactx *aad = (gactx *)a; \
680 assert(!a || a->ops == &gaops); \
681 return (pre##_ocb3encryptdone(&enc->ctx, a ? &aad->aad : 0, b, t, tsz)); \
682 } \
683 \
684 static void gedestroy(gaead_enc *e) \
685 { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \
686 \
687 static const gaead_encops geops = \
688 { &pre##_ocb3, geaad, gereinit, geenc, gedone, gedestroy }; \
689 \
690 typedef struct gdctx { \
691 gaead_dec d; \
692 pre##_ocb3ctx ctx; \
693 } gdctx; \
694 \
695 static gaead_aad *gdaad(gaead_dec *d) \
696 { gdctx *dec = (gdctx *)d; return (gaad(&dec->ctx.k)); } \
697 \
698 static int gdreinit(gaead_dec *d, const void *n, size_t nsz, \
699 size_t hsz, size_t csz, size_t tsz) \
700 { \
701 gdctx *dec = (gdctx *)d; \
702 return (pre##_ocb3reinit(&dec->ctx, n, nsz, tsz)); \
703 } \
704 \
705 static int gddec(gaead_dec *d, const void *c, size_t csz, buf *b) \
706 { \
707 gdctx *dec = (gdctx *)d; \
708 return (pre##_ocb3decrypt(&dec->ctx, c, csz, b)); \
709 } \
710 \
711 static int gddone(gaead_dec *d, const gaead_aad *a, \
712 buf *b, const void *t, size_t tsz) \
713 { \
714 gdctx *dec = (gdctx *)d; gactx *aad = (gactx *)a; \
715 assert(!a || a->ops == &gaops); \
716 return (pre##_ocb3decryptdone(&dec->ctx, a ? &aad->aad : 0, b, t, tsz)); \
717 } \
718 \
719 static void gddestroy(gaead_dec *d) \
720 { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \
721 \
722 static const gaead_decops gdops = \
723 { &pre##_ocb3, gdaad, gdreinit, gddec, gddone, gddestroy }; \
724 \
725 typedef struct gkctx { \
726 gaead_key k; \
727 pre##_ocb3key key; \
728 } gkctx; \
729 \
730 static gaead_aad *gkaad(const gaead_key *k) \
731 { gkctx *key = (gkctx *)k; return (gaad(&key->key)); } \
732 \
733 static gaead_enc *gkenc(const gaead_key *k, const void *n, size_t nsz, \
734 size_t hsz, size_t msz, size_t tsz) \
735 { \
736 gkctx *key = (gkctx *)k; \
737 gectx *enc = S_CREATE(gectx); \
738 \
739 enc->e.ops = &geops; \
740 if (pre##_ocb3init(&enc->ctx, &key->key, n, nsz, tsz)) \
741 { gedestroy(&enc->e); return (0); } \
742 return (&enc->e); \
743 } \
744 \
745 static gaead_dec *gkdec(const gaead_key *k, const void *n, size_t nsz, \
746 size_t hsz, size_t csz, size_t tsz) \
747 { \
748 gkctx *key = (gkctx *)k; \
749 gdctx *dec = S_CREATE(gdctx); \
750 \
751 dec->d.ops = &gdops; \
752 if (pre##_ocb3init(&dec->ctx, &key->key, n, nsz, tsz)) \
753 { gddestroy(&dec->d); return (0); } \
754 return (&dec->d); \
755 } \
756 \
757 static void gkdestroy(gaead_key *k) \
758 { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \
759 \
760 static const gaead_keyops gkops = \
761 { &pre##_ocb3, gkaad, gkenc, gkdec, gkdestroy }; \
762 \
763 static gaead_key *gckey(const void *k, size_t ksz) \
764 { \
765 gkctx *key = S_CREATE(gkctx); \
766 key->k.ops = &gkops; \
767 pre##_ocb3setkey(&key->key, k, ksz); \
768 return (&key->k); \
769 } \
770 \
771 const gcaead pre##_ocb3 = { \
772 name "-ocb3", \
773 pre##_keysz, pre##_ocb3noncesz, pre##_ocb3tagsz, \
774 PRE##_BLKSZ, PRE##_BLKSZ - 1, 0, AEADF_PCTSZ, \
775 gckey \
776 }; \
777 \
778 OCB3_TESTX(PRE, pre, name, fname)
779
780 /*----- Test rig ----------------------------------------------------------*/
781
782 #define OCB3_TEST(PRE, pre) OCB3_TESTX(PRE, pre, #pre, #pre)
783
784 /* --- @OCB3_TEST@ --- *
785 *
786 * Arguments: @PRE, pre@ = prefixes for the underlying block cipher
787 *
788 * Use: Standard test rig for OCB3 functions.
789 */
790
791 #ifdef TEST_RIG
792
793 #include <stdio.h>
794
795 #include <mLib/dstr.h>
796 #include <mLib/quis.h>
797 #include <mLib/testrig.h>
798
799 #define OCB3_TESTX(PRE, pre, name, fname) \
800 \
801 static int ocb3verify(dstr *v) \
802 { \
803 pre##_ocb3key key; \
804 pre##_ocb3aadctx aad; \
805 pre##_ocb3ctx ctx; \
806 int ok = 1, win; \
807 int i; \
808 octet *p; \
809 int szs[] = { 1, 7, 192, -1, 0 }, *ip; \
810 size_t hsz, msz; \
811 dstr d = DSTR_INIT, t = DSTR_INIT; \
812 buf b; \
813 \
814 dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \
815 dstr_ensure(&t, v[5].len); t.len = v[5].len; \
816 \
817 pre##_ocb3setkey(&key, v[0].buf, v[0].len); \
818 \
819 for (ip = szs; *ip; ip++) { \
820 \
821 pre##_ocb3init(&ctx, &key, (octet *)v[1].buf, v[1].len, v[5].len); \
822 \
823 i = *ip; \
824 hsz = v[2].len; \
825 if (i == -1) i = hsz; \
826 if (i > hsz) continue; \
827 p = (octet *)v[2].buf; \
828 pre##_ocb3aadinit(&aad, &key); \
829 while (hsz) { \
830 if (i > hsz) i = hsz; \
831 pre##_ocb3aadhash(&aad, p, i); \
832 p += i; hsz -= i; \
833 } \
834 \
835 buf_init(&b, d.buf, d.sz); \
836 i = *ip; \
837 msz = v[3].len; \
838 if (i == -1) i = msz; \
839 if (i > msz) continue; \
840 p = (octet *)v[3].buf; \
841 while (msz) { \
842 if (i > msz) i = msz; \
843 if (pre##_ocb3encrypt(&ctx, p, i, &b)) { \
844 puts("!! ocb3encrypt reports failure"); \
845 goto fail_enc; \
846 } \
847 p += i; msz -= i; \
848 } \
849 \
850 if (pre##_ocb3encryptdone(&ctx, &aad, &b, (octet *)t.buf, t.len)) { \
851 puts("!! ocb3encryptdone reports failure"); \
852 goto fail_enc; \
853 } \
854 d.len = BLEN(&b); \
855 \
856 if (d.len != v[4].len || \
857 MEMCMP(d.buf, !=, v[4].buf, v[4].len) || \
858 MEMCMP(t.buf, !=, v[5].buf, v[5].len)) { \
859 fail_enc: \
860 printf("\nfail encrypt:\n\tstep = %i", *ip); \
861 fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \
862 fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \
863 fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \
864 fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \
865 fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \
866 fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \
867 fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \
868 fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \
869 putchar('\n'); \
870 ok = 0; \
871 } \
872 \
873 pre##_ocb3init(&ctx, &key, (octet *)v[1].buf, v[1].len, v[5].len); \
874 \
875 buf_init(&b, d.buf, d.sz); \
876 i = *ip; \
877 msz = v[4].len; \
878 if (i == -1) i = msz; \
879 if (i > msz) continue; \
880 p = (octet *)v[4].buf; \
881 while (msz) { \
882 if (i > msz) i = msz; \
883 if (pre##_ocb3decrypt(&ctx, p, i, &b)) { \
884 puts("!! ocb3decrypt reports failure"); \
885 win = 0; goto fail_dec; \
886 } \
887 p += i; msz -= i; \
888 } \
889 \
890 win = pre##_ocb3decryptdone(&ctx, &aad, &b, \
891 (octet *)v[5].buf, v[5].len); \
892 if (win < 0) { \
893 puts("!! ocb3decryptdone reports failure"); \
894 goto fail_dec; \
895 } \
896 d.len = BLEN(&b); \
897 \
898 if (d.len != v[3].len || !win || \
899 MEMCMP(d.buf, !=, v[3].buf, v[3].len)) { \
900 fail_dec: \
901 printf("\nfail decrypt:\n\tstep = %i", *ip); \
902 fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \
903 fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \
904 fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \
905 fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \
906 fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \
907 fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \
908 fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \
909 printf("\n\tverify %s", win ? "ok" : "FAILED"); \
910 putchar('\n'); \
911 ok = 0; \
912 } \
913 } \
914 \
915 dstr_destroy(&d); dstr_destroy(&t); \
916 return (ok); \
917 } \
918 \
919 static int ocb3mct(dstr *v) \
920 { \
921 unsigned ksz = *(unsigned long *)v[0].buf, tsz = v[1].len; \
922 dstr d = DSTR_INIT; \
923 octet z[128]; \
924 pre##_ocb3key k; \
925 pre##_ocb3ctx ctx; \
926 pre##_ocb3aadctx oaad, iaad; \
927 int rc; \
928 buf b; \
929 unsigned i; \
930 int ok = 1; \
931 \
932 dstr_ensure(&d, ksz); memset(d.buf, 0, ksz - 4); \
933 STORE32_B(d.buf + ksz - 4, 8*tsz); \
934 pre##_ocb3setkey(&k, d.buf, ksz); \
935 \
936 pre##_ocb3aadinit(&oaad, &k); \
937 \
938 dstr_ensure(&d, 128 + tsz); \
939 memset(z, 0, 128); \
940 pre##_ocb3init(&ctx, &k, z, PRE##_BLKSZ - 4, tsz); \
941 \
942 for (i = 0; i < 128; i++) { \
943 pre##_ocb3aadinit(&iaad, &k); pre##_ocb3aadhash(&iaad, z, i); \
944 \
945 pre##_ocb3step(&ctx); buf_init(&b, d.buf, i); \
946 rc = pre##_ocb3encrypt(&ctx, z, i, &b); if (rc) goto fail; \
947 rc = pre##_ocb3encryptdone(&ctx, &iaad, &b, d.buf + i, tsz); \
948 if (rc) goto fail; \
949 pre##_ocb3aadhash(&oaad, d.buf, i + tsz); \
950 \
951 pre##_ocb3step(&ctx); buf_init(&b, d.buf, i); \
952 rc = pre##_ocb3encrypt(&ctx, z, i, &b); if (rc) goto fail; \
953 rc = pre##_ocb3encryptdone(&ctx, 0, &b, d.buf + i, tsz); \
954 if (rc) goto fail; \
955 pre##_ocb3aadhash(&oaad, d.buf, i + tsz); \
956 \
957 pre##_ocb3step(&ctx); buf_init(&b, 0, 0); \
958 rc = pre##_ocb3encryptdone(&ctx, &iaad, &b, d.buf, tsz); \
959 if (rc) goto fail; \
960 pre##_ocb3aadhash(&oaad, d.buf, tsz); \
961 } \
962 \
963 pre##_ocb3step(&ctx); buf_init(&b, 0, 0); \
964 rc = pre##_ocb3encryptdone(&ctx, &oaad, &b, d.buf, tsz); \
965 if (rc) goto fail; \
966 \
967 d.len = tsz; \
968 if (MEMCMP(d.buf, !=, v[1].buf, tsz)) { \
969 fail: \
970 printf("\nfail mct: ksz = %u, tsz = %u", ksz, tsz); \
971 fputs("\n\texp tag = ", stdout); type_hex.dump(&v[1], stdout); \
972 fputs("\n\tcalc tag = ", stdout); type_hex.dump(&d, stdout); \
973 putchar('\n'); \
974 ok = 0; \
975 } \
976 \
977 return (ok); \
978 } \
979 \
980 static test_chunk aeaddefs[] = { \
981 { name "-ocb3", ocb3verify, \
982 { &type_hex, &type_hex, &type_hex, &type_hex, \
983 &type_hex, &type_hex, 0 } }, \
984 { name "-ocb3-mct", ocb3mct, \
985 { &type_ulong, &type_hex, 0 } }, \
986 { 0, 0, { 0 } } \
987 }; \
988 \
989 int main(int argc, char *argv[]) \
990 { \
991 ego(argv[0]); \
992 test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \
993 return (0); \
994 }
995
996 #else
997 # define OCB3_TESTX(PRE, pre, name, fname)
998 #endif
999
1000 /*----- That's all, folks -------------------------------------------------*/
1001
1002 #ifdef __cplusplus
1003 }
1004 #endif
1005
1006 #endif