progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / ocb3-def.h
CommitLineData
09734e51
MW
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 \
101static const rsvr_policy pre##_ocb3policy = \
102 { 0, PRE##_BLKSZ, PRE##_BLKSZ }; \
103 \
104const 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 \
121void 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 \
150void 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 \
169void 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 \
197static 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 \
224static 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 \
255static 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 \
287int 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 \
327int 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 \
365void 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 \
401int 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 \
451int 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 \
502static 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 \
560int 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 \
604int 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 \
630typedef struct gactx { \
631 gaead_aad a; \
632 pre##_ocb3aadctx aad; \
633} gactx; \
634 \
635static gaead_aad *gadup(const gaead_aad *a) \
636 { gactx *aad = S_CREATE(gactx); *aad = *(gactx *)a; return (&aad->a); } \
637 \
638static void gahash(gaead_aad *a, const void *h, size_t hsz) \
639 { gactx *aad = (gactx *)a; pre##_ocb3aadhash(&aad->aad, h, hsz); } \
640 \
641static void gadestroy(gaead_aad *a) \
642 { gactx *aad = (gactx *)a; BURN(*aad); S_DESTROY(aad); } \
643 \
644static const gaead_aadops gaops = \
645 { &pre##_ocb3, gadup, gahash, gadestroy }; \
646 \
647static 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 \
655typedef struct gectx { \
656 gaead_enc e; \
657 pre##_ocb3ctx ctx; \
658} gectx; \
659 \
660static gaead_aad *geaad(gaead_enc *e) \
661 { gectx *enc = (gectx *)e; return (gaad(&enc->ctx.k)); } \
662 \
663static 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 \
670static 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 \
676static 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 \
684static void gedestroy(gaead_enc *e) \
685 { gectx *enc = (gectx *)e; BURN(*enc); S_DESTROY(enc); } \
686 \
687static const gaead_encops geops = \
688 { &pre##_ocb3, geaad, gereinit, geenc, gedone, gedestroy }; \
689 \
690typedef struct gdctx { \
691 gaead_dec d; \
692 pre##_ocb3ctx ctx; \
693} gdctx; \
694 \
695static gaead_aad *gdaad(gaead_dec *d) \
696 { gdctx *dec = (gdctx *)d; return (gaad(&dec->ctx.k)); } \
697 \
698static 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 \
705static 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 \
711static 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 \
719static void gddestroy(gaead_dec *d) \
720 { gdctx *dec = (gdctx *)d; BURN(*dec); S_DESTROY(dec); } \
721 \
722static const gaead_decops gdops = \
723 { &pre##_ocb3, gdaad, gdreinit, gddec, gddone, gddestroy }; \
724 \
725typedef struct gkctx { \
726 gaead_key k; \
727 pre##_ocb3key key; \
728} gkctx; \
729 \
730static gaead_aad *gkaad(const gaead_key *k) \
731 { gkctx *key = (gkctx *)k; return (gaad(&key->key)); } \
732 \
733static 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 \
745static 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 \
757static void gkdestroy(gaead_key *k) \
758 { gkctx *key = (gkctx *)k; BURN(*key); S_DESTROY(key); } \
759 \
760static const gaead_keyops gkops = \
761 { &pre##_ocb3, gkaad, gkenc, gkdec, gkdestroy }; \
762 \
763static 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 \
1491bf9e
MW
771static int gcszok(size_t nsz, size_t hsz, size_t msz, size_t tsz) \
772 { return (gaead_szokcommon(&pre##_ocb3, nsz, hsz, msz, tsz)); } \
773 \
09734e51
MW
774const gcaead pre##_ocb3 = { \
775 name "-ocb3", \
776 pre##_keysz, pre##_ocb3noncesz, pre##_ocb3tagsz, \
777 PRE##_BLKSZ, PRE##_BLKSZ - 1, 0, AEADF_PCTSZ, \
1491bf9e 778 gckey, gcszok \
09734e51
MW
779}; \
780 \
781OCB3_TESTX(PRE, pre, name, fname)
782
783/*----- Test rig ----------------------------------------------------------*/
784
785#define OCB3_TEST(PRE, pre) OCB3_TESTX(PRE, pre, #pre, #pre)
786
787/* --- @OCB3_TEST@ --- *
788 *
789 * Arguments: @PRE, pre@ = prefixes for the underlying block cipher
790 *
791 * Use: Standard test rig for OCB3 functions.
792 */
793
794#ifdef TEST_RIG
795
796#include <stdio.h>
797
798#include <mLib/dstr.h>
799#include <mLib/quis.h>
800#include <mLib/testrig.h>
801
802#define OCB3_TESTX(PRE, pre, name, fname) \
803 \
804static int ocb3verify(dstr *v) \
805{ \
806 pre##_ocb3key key; \
807 pre##_ocb3aadctx aad; \
808 pre##_ocb3ctx ctx; \
809 int ok = 1, win; \
810 int i; \
811 octet *p; \
812 int szs[] = { 1, 7, 192, -1, 0 }, *ip; \
813 size_t hsz, msz; \
814 dstr d = DSTR_INIT, t = DSTR_INIT; \
815 buf b; \
816 \
817 dstr_ensure(&d, v[4].len > v[3].len ? v[4].len : v[3].len); \
818 dstr_ensure(&t, v[5].len); t.len = v[5].len; \
819 \
820 pre##_ocb3setkey(&key, v[0].buf, v[0].len); \
821 \
822 for (ip = szs; *ip; ip++) { \
823 \
824 pre##_ocb3init(&ctx, &key, (octet *)v[1].buf, v[1].len, v[5].len); \
825 \
826 i = *ip; \
827 hsz = v[2].len; \
828 if (i == -1) i = hsz; \
829 if (i > hsz) continue; \
830 p = (octet *)v[2].buf; \
831 pre##_ocb3aadinit(&aad, &key); \
832 while (hsz) { \
833 if (i > hsz) i = hsz; \
834 pre##_ocb3aadhash(&aad, p, i); \
835 p += i; hsz -= i; \
836 } \
837 \
838 buf_init(&b, d.buf, d.sz); \
839 i = *ip; \
840 msz = v[3].len; \
841 if (i == -1) i = msz; \
842 if (i > msz) continue; \
843 p = (octet *)v[3].buf; \
844 while (msz) { \
845 if (i > msz) i = msz; \
846 if (pre##_ocb3encrypt(&ctx, p, i, &b)) { \
847 puts("!! ocb3encrypt reports failure"); \
848 goto fail_enc; \
849 } \
850 p += i; msz -= i; \
851 } \
852 \
853 if (pre##_ocb3encryptdone(&ctx, &aad, &b, (octet *)t.buf, t.len)) { \
854 puts("!! ocb3encryptdone reports failure"); \
855 goto fail_enc; \
856 } \
857 d.len = BLEN(&b); \
858 \
859 if (d.len != v[4].len || \
141c1284
MW
860 MEMCMP(d.buf, !=, v[4].buf, v[4].len) || \
861 MEMCMP(t.buf, !=, v[5].buf, v[5].len)) { \
09734e51
MW
862 fail_enc: \
863 printf("\nfail encrypt:\n\tstep = %i", *ip); \
864 fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \
865 fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \
866 fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \
867 fputs("\n\tmessage = ", stdout); type_hex.dump(&v[3], stdout); \
868 fputs("\n\texp ct = ", stdout); type_hex.dump(&v[4], stdout); \
869 fputs("\n\tcalc ct = ", stdout); type_hex.dump(&d, stdout); \
870 fputs("\n\texp tag = ", stdout); type_hex.dump(&v[5], stdout); \
871 fputs("\n\tcalc tag = ", stdout); type_hex.dump(&t, stdout); \
872 putchar('\n'); \
873 ok = 0; \
874 } \
875 \
876 pre##_ocb3init(&ctx, &key, (octet *)v[1].buf, v[1].len, v[5].len); \
877 \
878 buf_init(&b, d.buf, d.sz); \
879 i = *ip; \
880 msz = v[4].len; \
881 if (i == -1) i = msz; \
882 if (i > msz) continue; \
883 p = (octet *)v[4].buf; \
884 while (msz) { \
885 if (i > msz) i = msz; \
886 if (pre##_ocb3decrypt(&ctx, p, i, &b)) { \
887 puts("!! ocb3decrypt reports failure"); \
888 win = 0; goto fail_dec; \
889 } \
890 p += i; msz -= i; \
891 } \
892 \
893 win = pre##_ocb3decryptdone(&ctx, &aad, &b, \
894 (octet *)v[5].buf, v[5].len); \
895 if (win < 0) { \
896 puts("!! ocb3decryptdone reports failure"); \
897 goto fail_dec; \
898 } \
899 d.len = BLEN(&b); \
900 \
901 if (d.len != v[3].len || !win || \
141c1284 902 MEMCMP(d.buf, !=, v[3].buf, v[3].len)) { \
09734e51
MW
903 fail_dec: \
904 printf("\nfail decrypt:\n\tstep = %i", *ip); \
905 fputs("\n\tkey = ", stdout); type_hex.dump(&v[0], stdout); \
906 fputs("\n\tnonce = ", stdout); type_hex.dump(&v[1], stdout); \
907 fputs("\n\theader = ", stdout); type_hex.dump(&v[2], stdout); \
908 fputs("\n\tciphertext = ", stdout); type_hex.dump(&v[4], stdout); \
909 fputs("\n\texp pt = ", stdout); type_hex.dump(&v[3], stdout); \
910 fputs("\n\tcalc pt = ", stdout); type_hex.dump(&d, stdout); \
911 fputs("\n\ttag = ", stdout); type_hex.dump(&v[5], stdout); \
912 printf("\n\tverify %s", win ? "ok" : "FAILED"); \
913 putchar('\n'); \
914 ok = 0; \
915 } \
916 } \
917 \
918 dstr_destroy(&d); dstr_destroy(&t); \
919 return (ok); \
920} \
921 \
922static int ocb3mct(dstr *v) \
923{ \
924 unsigned ksz = *(unsigned long *)v[0].buf, tsz = v[1].len; \
925 dstr d = DSTR_INIT; \
926 octet z[128]; \
927 pre##_ocb3key k; \
928 pre##_ocb3ctx ctx; \
929 pre##_ocb3aadctx oaad, iaad; \
930 int rc; \
931 buf b; \
932 unsigned i; \
933 int ok = 1; \
934 \
935 dstr_ensure(&d, ksz); memset(d.buf, 0, ksz - 4); \
936 STORE32_B(d.buf + ksz - 4, 8*tsz); \
937 pre##_ocb3setkey(&k, d.buf, ksz); \
938 \
939 pre##_ocb3aadinit(&oaad, &k); \
940 \
941 dstr_ensure(&d, 128 + tsz); \
942 memset(z, 0, 128); \
943 pre##_ocb3init(&ctx, &k, z, PRE##_BLKSZ - 4, tsz); \
944 \
945 for (i = 0; i < 128; i++) { \
946 pre##_ocb3aadinit(&iaad, &k); pre##_ocb3aadhash(&iaad, z, i); \
947 \
948 pre##_ocb3step(&ctx); buf_init(&b, d.buf, i); \
949 rc = pre##_ocb3encrypt(&ctx, z, i, &b); if (rc) goto fail; \
950 rc = pre##_ocb3encryptdone(&ctx, &iaad, &b, d.buf + i, tsz); \
951 if (rc) goto fail; \
952 pre##_ocb3aadhash(&oaad, d.buf, i + tsz); \
953 \
954 pre##_ocb3step(&ctx); buf_init(&b, d.buf, i); \
955 rc = pre##_ocb3encrypt(&ctx, z, i, &b); if (rc) goto fail; \
956 rc = pre##_ocb3encryptdone(&ctx, 0, &b, d.buf + i, tsz); \
957 if (rc) goto fail; \
958 pre##_ocb3aadhash(&oaad, d.buf, i + tsz); \
959 \
960 pre##_ocb3step(&ctx); buf_init(&b, 0, 0); \
961 rc = pre##_ocb3encryptdone(&ctx, &iaad, &b, d.buf, tsz); \
962 if (rc) goto fail; \
963 pre##_ocb3aadhash(&oaad, d.buf, tsz); \
964 } \
965 \
966 pre##_ocb3step(&ctx); buf_init(&b, 0, 0); \
967 rc = pre##_ocb3encryptdone(&ctx, &oaad, &b, d.buf, tsz); \
968 if (rc) goto fail; \
969 \
970 d.len = tsz; \
141c1284 971 if (MEMCMP(d.buf, !=, v[1].buf, tsz)) { \
09734e51
MW
972 fail: \
973 printf("\nfail mct: ksz = %u, tsz = %u", ksz, tsz); \
974 fputs("\n\texp tag = ", stdout); type_hex.dump(&v[1], stdout); \
975 fputs("\n\tcalc tag = ", stdout); type_hex.dump(&d, stdout); \
976 putchar('\n'); \
977 ok = 0; \
978 } \
979 \
980 return (ok); \
981} \
982 \
983static test_chunk aeaddefs[] = { \
984 { name "-ocb3", ocb3verify, \
985 { &type_hex, &type_hex, &type_hex, &type_hex, \
986 &type_hex, &type_hex, 0 } }, \
987 { name "-ocb3-mct", ocb3mct, \
988 { &type_ulong, &type_hex, 0 } }, \
989 { 0, 0, { 0 } } \
990}; \
991 \
992int main(int argc, char *argv[]) \
993{ \
994 ego(argv[0]); \
995 test_run(argc, argv, aeaddefs, SRCDIR"/t/" fname); \
996 return (0); \
997}
998
999#else
1000# define OCB3_TESTX(PRE, pre, name, fname)
1001#endif
1002
1003/*----- That's all, folks -------------------------------------------------*/
1004
1005#ifdef __cplusplus
1006 }
1007#endif
1008
1009#endif