chiark / gitweb /
math/t/mpx-mul4: Fix comment markers.
[catacomb] / symm / latinpoly-def.h
1 /* -*-c-*-
2  *
3  * AEAD schemes based on Salsa20/ChaCha and Poly1305
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_LATINPOLY_DEF_H
29 #define CATACOMB_LATINPOLY_DEF_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <mLib/bits.h>
38 #include <mLib/buf.h>
39 #include <mLib/sub.h>
40
41 #ifndef CATACOMB_ARENA_H
42 #  include "arena.h"
43 #endif
44
45 #ifndef CATACOMB_CT_H
46 #  include "ct.h"
47 #endif
48
49 #ifndef CATACOMB_GAEAD_H
50 #  include "gaead.h"
51 #endif
52
53 #ifndef CATACOMB_KEYSZ_H
54 #  include "keysz.h"
55 #endif
56
57 #ifndef CATACOMB_LATINPOLY_H
58 #  include "latinpoly.h"
59 #endif
60
61 #ifndef CATACOMB_PARANOIA_H
62 #  include "paranoia.h"
63 #endif
64
65 #ifndef CATACOMB_POLY1305_H
66 #  include "poly1305.h"
67 #endif
68
69 #ifndef CATACOMB_SALSA20_H
70 #  include "salsa20.h"
71 #endif
72
73 /*----- Data structures ---------------------------------------------------*/
74
75 typedef struct latinpoly_aad {
76   gaead_aad a;
77   poly1305_ctx poly;
78 } latinpoly_aad;
79
80 typedef struct latinpoly_key {
81   gaead_key k;
82   octet key[SALSA20_KEYSZ];
83   size_t ksz;
84 } latinpoly_key;
85
86 /*----- Common definitions ------------------------------------------------*/
87
88 /* Tables. */
89 extern const octet latinpoly_noncesz[], latinpoly_tagsz[];
90
91 /* AAD methods. */
92 extern void latinpoly_aadhash_poly1305(gaead_aad */*a*/,
93                                        const void */*h*/, size_t /*hsz*/);
94 extern void latinpoly_aadhash_naclbox(gaead_aad */*a*/,
95                                       const void */*h*/, size_t /*hsz*/);
96 extern void latinpoly_aaddestroy(gaead_aad */*a*/);
97
98 /* Variants. */
99 enum { LPVAR_NACLBOX, LPVAR_POLY1305 };
100
101 /* --- @latinpoly_tag@ --- *
102  *
103  * Arguments:   @const poly1305_ctx *aad@ = Poly1305 context hashing AAD
104  *              @poly1305_ctx *ct@ = Poly1305 context hashing ciphertext
105  *              @void *tag@ = where to write the tag
106  *
107  * Returns:     ---
108  *
109  * Use:         Completes a Latin-dance-Poly1305 tag, combining the AAD and
110  *              ciphertext hashes, appending their lengths, and writing the
111  *              final masked hash to @tag@.  The @ct@ context is clobbered.
112  */
113
114 extern void latinpoly_tag(const poly1305_ctx */*aad*/,
115                           poly1305_ctx */*ct*/, void */*tag*/);
116
117 /*----- Macros ------------------------------------------------------------*/
118
119 #define LATINPOLY_DEF(latin, base, name)                                \
120                                                                         \
121 /* Utilities. */                                                        \
122                                                                         \
123 /* Reinitialize the stream cipher and hash state given a new nonce. */  \
124 static int reinit_##latin(x##latin##_ctx *ctx,  int var,                \
125                           poly1305_ctx *aadpoly, poly1305_ctx *ctpoly,  \
126                           const void *n, size_t nsz)                    \
127 {                                                                       \
128   poly1305_key pk;                                                      \
129   octet b[POLY1305_KEYSZ + POLY1305_MASKSZ];                            \
130                                                                         \
131   switch (nsz) {                                                        \
132     case SALSA20_NONCESZ:                                               \
133       memcpy(ctx->s.a, ctx->k, sizeof(ctx->k));                         \
134       base##_setnonce(&ctx->s, n);                                      \
135       break;                                                            \
136     case SALSA20_IETF_NONCESZ:                                          \
137       memcpy(ctx->s.a, ctx->k, sizeof(ctx->k));                         \
138       base##_setnonce_ietf(&ctx->s, n);                                 \
139       break;                                                            \
140     case XSALSA20_NONCESZ:                                              \
141       x##latin##_setnonce(ctx, n);                                      \
142       break;                                                            \
143     default:                                                            \
144       return (-1);                                                      \
145   }                                                                     \
146                                                                         \
147   latin##_encrypt(&ctx->s, 0, b, sizeof(b));                            \
148   poly1305_keyinit(&pk, b, POLY1305_KEYSZ);                             \
149   poly1305_macinit(ctpoly, &pk, b + POLY1305_KEYSZ);                    \
150   switch (var) {                                                        \
151     case LPVAR_NACLBOX:                                                 \
152       aadpoly->count = 0; aadpoly->nbuf = 0;                            \
153       break;                                                            \
154     case LPVAR_POLY1305:                                                \
155       poly1305_macinit(aadpoly, &pk, b + POLY1305_KEYSZ);               \
156       latin##_encrypt(&ctx->s, 0, 0, SALSA20_OUTSZ - sizeof(b));        \
157       break;                                                            \
158     default:                                                            \
159       assert(0);                                                        \
160   }                                                                     \
161   return (0);                                                           \
162 }                                                                       \
163                                                                         \
164 /* AAD operations. */                                                   \
165                                                                         \
166 static const gaead_aadops gaops_##latin##_poly1305 =                    \
167   { &latin##_poly1305, 0, latinpoly_aadhash_poly1305, latinpoly_aaddestroy }; \
168                                                                         \
169 static const gaead_aadops gaops_##latin##_naclbox =                     \
170   { &latin##_naclbox, 0, latinpoly_aadhash_naclbox, latinpoly_aaddestroy }; \
171                                                                         \
172 /* Encryption operations. */                                            \
173                                                                         \
174 typedef struct gectx_##latin {                                          \
175   gaead_enc e;                                                          \
176   latinpoly_aad aad;                                                    \
177   x##latin##_ctx ctx;                                                   \
178   poly1305_ctx poly;                                                    \
179 } gectx_##latin;                                                        \
180                                                                         \
181 static gaead_aad *geaad_##latin(gaead_enc *e)                           \
182   { gectx_##latin *enc = (gectx_##latin *)e; return (&enc->aad.a); }    \
183                                                                         \
184 static int gereinit_##latin##_poly1305(gaead_enc *e,                    \
185                                        const void *n, size_t nsz,       \
186                                        size_t hsz, size_t msz, size_t tsz) \
187 {                                                                       \
188   gectx_##latin *enc = (gectx_##latin *)e;                              \
189   return (reinit_##latin(&enc->ctx, LPVAR_POLY1305,                     \
190                          &enc->aad.poly, &enc->poly, n, nsz));          \
191 }                                                                       \
192                                                                         \
193 static int gereinit_##latin##_naclbox(gaead_enc *e,                     \
194                                       const void *n, size_t nsz,        \
195                                       size_t hsz, size_t msz, size_t tsz) \
196 {                                                                       \
197   gectx_##latin *enc = (gectx_##latin *)e;                              \
198   return (reinit_##latin(&enc->ctx, LPVAR_NACLBOX,                      \
199                          &enc->aad.poly, &enc->poly, n, nsz));          \
200 }                                                                       \
201                                                                         \
202 static int geenc_##latin(gaead_enc *e,                                  \
203                          const void *m, size_t msz, buf *b)             \
204 {                                                                       \
205   gectx_##latin *enc = (gectx_##latin *)e;                              \
206   void *q;                                                              \
207                                                                         \
208   if (msz) { q = buf_get(b, msz); if (!q) return (-1); }                \
209   else q = 0;                                                           \
210   latin##_encrypt(&enc->ctx.s, m, q, msz);                              \
211   poly1305_hash(&enc->poly, q, msz);                                    \
212   return (0);                                                           \
213 }                                                                       \
214                                                                         \
215 static int gedone_##latin##_common(gectx_##latin *enc,                  \
216                                    const latinpoly_aad *aad,            \
217                                    buf *b, size_t tsz)                  \
218 {                                                                       \
219   if (tsz != POLY1305_TAGSZ) return (-1);                               \
220   assert((!enc->aad.poly.count && !enc->aad.poly.nbuf && !aad) ||       \
221          aad == &enc->aad);                                             \
222   if (!BOK(b)) return (-1);                                             \
223   return (0);                                                           \
224 }                                                                       \
225                                                                         \
226 static int gedone_##latin##_poly1305(gaead_enc *e, const gaead_aad *a,  \
227                                      buf *b, void *t, size_t tsz)       \
228 {                                                                       \
229   gectx_##latin *enc = (gectx_##latin *)e;                              \
230   const latinpoly_aad *aad = (const latinpoly_aad *)a;                  \
231                                                                         \
232   if (gedone_##latin##_common(enc, aad, b, tsz)) return (-1);           \
233   latinpoly_tag(aad ? &aad->poly : 0, &enc->poly, t);                   \
234   return (0);                                                           \
235 }                                                                       \
236                                                                         \
237 static int gedone_##latin##_naclbox(gaead_enc *e, const gaead_aad *a,   \
238                                     buf *b, void *t, size_t tsz)        \
239 {                                                                       \
240   gectx_##latin *enc = (gectx_##latin *)e;                              \
241   const latinpoly_aad *aad = (const latinpoly_aad *)a;                  \
242                                                                         \
243   if (gedone_##latin##_common(enc, aad, b, tsz)) return (-1);           \
244   poly1305_done(&enc->poly, t);                                         \
245   return (0);                                                           \
246 }                                                                       \
247                                                                         \
248 static void gedestroy_##latin(gaead_enc *e)                             \
249   { gectx_##latin *enc = (gectx_##latin *)e; BURN(*enc); S_DESTROY(enc); } \
250                                                                         \
251 static gaead_encops geops_##latin##_poly1305 =                          \
252   { &latin##_poly1305, geaad_##latin, gereinit_##latin##_poly1305,      \
253     geenc_##latin, gedone_##latin##_poly1305, gedestroy_##latin };      \
254                                                                         \
255 static gaead_encops geops_##latin##_naclbox =                           \
256   { &latin##_naclbox, geaad_##latin, gereinit_##latin##_naclbox,        \
257     geenc_##latin, gedone_##latin##_naclbox, gedestroy_##latin };       \
258                                                                         \
259 /* Decryption operations. */                                            \
260                                                                         \
261 typedef struct gdctx_##latin {                                          \
262   gaead_dec d;                                                          \
263   latinpoly_aad aad;                                                    \
264   x##latin##_ctx ctx;                                                   \
265   poly1305_ctx poly;                                                    \
266 } gdctx_##latin;                                                        \
267                                                                         \
268 static gaead_aad *gdaad_##latin(gaead_dec *d)                           \
269   { gdctx_##latin *dec = (gdctx_##latin *)d; return (&dec->aad.a); }    \
270                                                                         \
271 static int gdreinit_##latin##_poly1305(gaead_dec *d,                    \
272                                        const void *n, size_t nsz,       \
273                                        size_t hsz, size_t msz, size_t tsz) \
274 {                                                                       \
275   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
276   return (reinit_##latin(&dec->ctx, LPVAR_POLY1305,                     \
277                          &dec->aad.poly, &dec->poly, n, nsz));          \
278 }                                                                       \
279                                                                         \
280 static int gdreinit_##latin##_naclbox(gaead_dec *d,                     \
281                                       const void *n, size_t nsz,        \
282                                       size_t hsz, size_t msz, size_t tsz) \
283 {                                                                       \
284   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
285   return (reinit_##latin(&dec->ctx, LPVAR_NACLBOX,                      \
286                          &dec->aad.poly, &dec->poly, n, nsz));          \
287 }                                                                       \
288                                                                         \
289 static int gddec_##latin(gaead_dec *d,                                  \
290                          const void *c, size_t csz, buf *b)             \
291 {                                                                       \
292   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
293   void *q;                                                              \
294                                                                         \
295   if (csz) { q = buf_get(b, csz); if (!q) return (-1); }                \
296   else q = 0;                                                           \
297   poly1305_hash(&dec->poly, c, csz);                                    \
298   latin##_encrypt(&dec->ctx.s, c, q, csz);                              \
299   return (0);                                                           \
300 }                                                                       \
301                                                                         \
302 static int gddone_##latin##_common(gdctx_##latin *dec,                  \
303                                    const latinpoly_aad *aad,            \
304                                    buf *b, size_t tsz)                  \
305 {                                                                       \
306   if (tsz != POLY1305_TAGSZ) return (-1);                               \
307   assert((!dec->aad.poly.count && !dec->aad.poly.nbuf && !aad) ||       \
308          aad == &dec->aad);                                             \
309   if (!BOK(b)) return (-1);                                             \
310   return (0);                                                           \
311 }                                                                       \
312                                                                         \
313 static int gddone_##latin##_poly1305(gaead_dec *d, const gaead_aad *a,  \
314                                      buf *b, const void *t, size_t tsz) \
315 {                                                                       \
316   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
317   const latinpoly_aad *aad = (const latinpoly_aad *)a;                  \
318   octet u[POLY1305_TAGSZ];                                              \
319                                                                         \
320   if (gddone_##latin##_common(dec, aad, b, tsz)) return (-1);           \
321   latinpoly_tag(aad ? &aad->poly : 0, &dec->poly, u);                   \
322   if (ct_memeq(t, u, POLY1305_TAGSZ)) return (+1);                      \
323   else return (0);                                                      \
324 }                                                                       \
325                                                                         \
326 static int gddone_##latin##_naclbox(gaead_dec *d, const gaead_aad *a,   \
327                                     buf *b, const void *t, size_t tsz)  \
328 {                                                                       \
329   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
330   const latinpoly_aad *aad = (const latinpoly_aad *)a;                  \
331   octet u[POLY1305_TAGSZ];                                              \
332                                                                         \
333   if (gddone_##latin##_common(dec, aad, b, tsz)) return (-1);           \
334   poly1305_done(&dec->poly, u);                                         \
335   if (ct_memeq(t, u, POLY1305_TAGSZ)) return (+1);                      \
336   else return (0);                                                      \
337 }                                                                       \
338                                                                         \
339 static void gddestroy_##latin(gaead_dec *d)                             \
340   { gdctx_##latin *dec = (gdctx_##latin *)d; BURN(*dec); S_DESTROY(dec); } \
341                                                                         \
342 static gaead_decops gdops_##latin##_poly1305 =                          \
343   { &latin##_poly1305, gdaad_##latin, gdreinit_##latin##_poly1305,      \
344     gddec_##latin, gddone_##latin##_poly1305, gddestroy_##latin };      \
345                                                                         \
346 static gaead_decops gdops_##latin##_naclbox =                           \
347   { &latin##_poly1305, gdaad_##latin, gdreinit_##latin##_naclbox,       \
348     gddec_##latin, gddone_##latin##_naclbox, gddestroy_##latin };       \
349                                                                         \
350 /* Key operations. */                                                   \
351                                                                         \
352 static gaead_enc *gkenc_##latin##_poly1305(const gaead_key *k,          \
353                                            const void *n, size_t nsz,   \
354                                            size_t hsz, size_t msz,      \
355                                            size_t tsz)                  \
356 {                                                                       \
357   latinpoly_key *key = (latinpoly_key *)k;                              \
358   gectx_##latin *enc = S_CREATE(gectx_##latin);                         \
359                                                                         \
360   enc->e.ops = &geops_##latin##_poly1305;                               \
361   enc->aad.a.ops = &gaops_##latin##_poly1305;                           \
362   x##latin##_init(&enc->ctx, key->key, key->ksz, 0);                    \
363   if (reinit_##latin(&enc->ctx, LPVAR_POLY1305,                         \
364                      &enc->aad.poly, &enc->poly, n, nsz))               \
365     { gedestroy_##latin(&enc->e); return (0); }                         \
366   return (&enc->e);                                                     \
367 }                                                                       \
368                                                                         \
369 static gaead_enc *gkenc_##latin##_naclbox(const gaead_key *k,           \
370                                           const void *n, size_t nsz,    \
371                                           size_t hsz, size_t msz,       \
372                                           size_t tsz)                   \
373 {                                                                       \
374   latinpoly_key *key = (latinpoly_key *)k;                              \
375   gectx_##latin *enc = S_CREATE(gectx_##latin);                         \
376                                                                         \
377   enc->e.ops = &geops_##latin##_naclbox;                                \
378   enc->aad.a.ops = &gaops_##latin##_naclbox;                            \
379   x##latin##_init(&enc->ctx, key->key, key->ksz, 0);                    \
380   if (reinit_##latin(&enc->ctx, LPVAR_NACLBOX,                          \
381                      &enc->aad.poly, &enc->poly, n, nsz))               \
382     { gedestroy_##latin(&enc->e); return (0); }                         \
383   return (&enc->e);                                                     \
384 }                                                                       \
385                                                                         \
386 static gaead_dec *gkdec_##latin##_poly1305(const gaead_key *k,          \
387                                            const void *n, size_t nsz,   \
388                                            size_t hsz, size_t msz,      \
389                                            size_t tsz)                  \
390 {                                                                       \
391   latinpoly_key *key = (latinpoly_key *)k;                              \
392   gdctx_##latin *dec = S_CREATE(gdctx_##latin);                         \
393                                                                         \
394   dec->d.ops = &gdops_##latin##_poly1305;                               \
395   dec->aad.a.ops = &gaops_##latin##_poly1305;                           \
396   x##latin##_init(&dec->ctx, key->key, key->ksz, 0);                    \
397   if (reinit_##latin(&dec->ctx, LPVAR_POLY1305,                         \
398                      &dec->aad.poly, &dec->poly, n, nsz))               \
399     { gddestroy_##latin(&dec->d); return (0); }                         \
400   return (&dec->d);                                                     \
401 }                                                                       \
402                                                                         \
403 static gaead_dec *gkdec_##latin##_naclbox(const gaead_key *k,           \
404                                           const void *n, size_t nsz,    \
405                                           size_t hsz, size_t msz,       \
406                                           size_t tsz)                   \
407 {                                                                       \
408   latinpoly_key *key = (latinpoly_key *)k;                              \
409   gdctx_##latin *dec = S_CREATE(gdctx_##latin);                         \
410                                                                         \
411   dec->d.ops = &gdops_##latin##_naclbox;                                \
412   dec->aad.a.ops = &gaops_##latin##_naclbox;                            \
413   x##latin##_init(&dec->ctx, key->key, key->ksz, 0);                    \
414   if (reinit_##latin(&dec->ctx, LPVAR_NACLBOX,                          \
415                      &dec->aad.poly, &dec->poly, n, nsz))               \
416     { gddestroy_##latin(&dec->d); return (0); }                         \
417   return (&dec->d);                                                     \
418 }                                                                       \
419                                                                         \
420 static void gkdestroy_##latin(gaead_key *k)                             \
421   { latinpoly_key *key = (latinpoly_key *)k; BURN(*key); S_DESTROY(key); } \
422                                                                         \
423 static const gaead_keyops gkops_##latin##_poly1305 =                    \
424   { &latin##_poly1305, 0,                                               \
425     gkenc_##latin##_poly1305, gkdec_##latin##_poly1305,                 \
426     gkdestroy_##latin };                                                \
427                                                                         \
428 static const gaead_keyops gkops_##latin##_naclbox =                     \
429   { &latin##_naclbox, 0,                                                \
430     gkenc_##latin##_naclbox, gkdec_##latin##_naclbox,                   \
431     gkdestroy_##latin };                                                \
432                                                                         \
433 /* Class definition. */                                                 \
434                                                                         \
435 static gaead_key *gkey_##latin##_common(const gaead_keyops *ops,        \
436                                         const void *k, size_t ksz)      \
437 {                                                                       \
438   latinpoly_key *key = S_CREATE(latinpoly_key);                         \
439                                                                         \
440   key->k.ops = ops;                                                     \
441   KSZ_ASSERT(latin, ksz); memcpy(key->key, k, ksz); key->ksz = ksz;     \
442   return (&key->k);                                                     \
443 }                                                                       \
444                                                                         \
445 static gaead_key *gkey_##latin##_poly1305(const void *k, size_t ksz)    \
446   { return (gkey_##latin##_common(&gkops_##latin##_poly1305, k, ksz)); } \
447                                                                         \
448 static gaead_key *gkey_##latin##_naclbox(const void *k, size_t ksz)     \
449   { return (gkey_##latin##_common(&gkops_##latin##_naclbox, k, ksz)); } \
450                                                                         \
451 const gcaead latin##_poly1305 = {                                       \
452   name "-poly1305", latin##_keysz, latinpoly_noncesz, latinpoly_tagsz,  \
453   64, 0, 0, AEADF_AADNDEP,                                              \
454   gkey_##latin##_poly1305                                               \
455 };                                                                      \
456                                                                         \
457 const gcaead latin##_naclbox = {                                        \
458   name "-naclbox", latin##_keysz, latinpoly_noncesz, latinpoly_tagsz,   \
459   64, 0, 0, AEADF_AADNDEP | AEADF_NOAAD,                                \
460   gkey_##latin##_naclbox                                                \
461 };
462
463 /*----- That's all, folks -------------------------------------------------*/
464
465 #ifdef __cplusplus
466   }
467 #endif
468
469 #endif