chiark / gitweb /
debian/.gitignore: Ignore `catacomb-data' directory.
[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) != 0 ||                       \
858         memcmp(t.buf, v[5].buf, v[5].len) != 0) {                       \
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) != 0) {                       \
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) != 0) {                              \
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