chiark / gitweb /
d04f2e13cce8274ab6e97188382d47c5d294e9cc
[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(gaead_aad */*a*/,
93                               const void */*h*/, size_t /*hsz*/);
94 extern void latinpoly_aaddestroy(gaead_aad */*a*/);
95
96 /* --- @latinpoly_tag@ --- *
97  *
98  * Arguments:   @const poly1305_ctx *aad@ = Poly1305 context hashing AAD
99  *              @poly1305_ctx *ct@ = Poly1305 context hashing ciphertext
100  *              @void *tag@ = where to write the tag
101  *
102  * Returns:     ---
103  *
104  * Use:         Completes a Latin-dance-Poly1305 tag, combining the AAD and
105  *              ciphertext hashes, appending their lengths, and writing the
106  *              final masked hash to @tag@.  The @ct@ context is clobbered.
107  */
108
109 extern void latinpoly_tag(const poly1305_ctx */*aad*/,
110                           poly1305_ctx */*ct*/, void */*tag*/);
111
112 /*----- Macros ------------------------------------------------------------*/
113
114 #define LATINPOLY_DEF(latin, base, name)                                \
115                                                                         \
116 /* Utilities. */                                                        \
117                                                                         \
118 /* Reinitialize the stream cipher and hash state given a new nonce. */  \
119 static int reinit_##latin(x##latin##_ctx *ctx,                          \
120                           poly1305_ctx *aadpoly, poly1305_ctx *ctpoly,  \
121                           const void *n, size_t nsz)                    \
122 {                                                                       \
123   poly1305_key pk;                                                      \
124   octet b[POLY1305_KEYSZ + POLY1305_MASKSZ];                            \
125                                                                         \
126   switch (nsz) {                                                        \
127     case SALSA20_NONCESZ:                                               \
128       memcpy(ctx->s.a, ctx->k, sizeof(ctx->k));                         \
129       base##_setnonce(&ctx->s, n);                                      \
130       break;                                                            \
131     case SALSA20_IETF_NONCESZ:                                          \
132       memcpy(ctx->s.a, ctx->k, sizeof(ctx->k));                         \
133       base##_setnonce_ietf(&ctx->s, n);                                 \
134       break;                                                            \
135     case XSALSA20_NONCESZ:                                              \
136       x##latin##_setnonce(ctx, n);                                      \
137       break;                                                            \
138     default:                                                            \
139       return (-1);                                                      \
140   }                                                                     \
141                                                                         \
142   latin##_encrypt(&ctx->s, 0, b, sizeof(b));                            \
143   poly1305_keyinit(&pk, b, POLY1305_KEYSZ);                             \
144   poly1305_macinit(aadpoly, &pk, b + POLY1305_KEYSZ);                   \
145   poly1305_macinit(ctpoly, &pk, b + POLY1305_KEYSZ);                    \
146   latin##_encrypt(&ctx->s, 0, 0, SALSA20_OUTSZ - sizeof(b));            \
147   return (0);                                                           \
148 }                                                                       \
149                                                                         \
150 /* AAD operations. */                                                   \
151                                                                         \
152 static const gaead_aadops gaops_##latin =                               \
153   { &latin##_poly1305, 0, latinpoly_aadhash, latinpoly_aaddestroy };    \
154                                                                         \
155 /* Encryption operations. */                                            \
156                                                                         \
157 typedef struct gectx_##latin {                                          \
158   gaead_enc e;                                                          \
159   latinpoly_aad aad;                                                    \
160   x##latin##_ctx ctx;                                                   \
161   poly1305_ctx poly;                                                    \
162 } gectx_##latin;                                                        \
163                                                                         \
164 static gaead_aad *geaad_##latin(gaead_enc *e)                           \
165   { gectx_##latin *enc = (gectx_##latin *)e; return (&enc->aad.a); }    \
166                                                                         \
167 static int gereinit_##latin(gaead_enc *e, const void *n, size_t nsz,    \
168                             size_t hsz, size_t msz, size_t tsz)         \
169 {                                                                       \
170   gectx_##latin *enc = (gectx_##latin *)e;                              \
171   return (reinit_##latin(&enc->ctx, &enc->aad.poly, &enc->poly, n, nsz)); \
172 }                                                                       \
173                                                                         \
174 static int geenc_##latin(gaead_enc *e,                                  \
175                          const void *m, size_t msz, buf *b)             \
176 {                                                                       \
177   gectx_##latin *enc = (gectx_##latin *)e;                              \
178   void *q;                                                              \
179                                                                         \
180   if (msz) { q = buf_get(b, msz); if (!q) return (-1); }                \
181   else q = 0;                                                           \
182   latin##_encrypt(&enc->ctx.s, m, q, msz);                              \
183   poly1305_hash(&enc->poly, q, msz);                                    \
184   return (0);                                                           \
185 }                                                                       \
186                                                                         \
187 static int gedone_##latin(gaead_enc *e, const gaead_aad *a,             \
188                           buf *b, void *t, size_t tsz)                  \
189 {                                                                       \
190   gectx_##latin *enc = (gectx_##latin *)e;                              \
191   const latinpoly_aad *aad = (const latinpoly_aad *)a;                  \
192                                                                         \
193   if (tsz != POLY1305_TAGSZ) return (-1);                               \
194   assert((!enc->aad.poly.count && !enc->aad.poly.nbuf && !a) ||         \
195          a == &enc->aad.a);                                             \
196   if (!BOK(b)) return (-1);                                             \
197   latinpoly_tag(aad ? &aad->poly : 0, &enc->poly, t);                   \
198   return (0);                                                           \
199 }                                                                       \
200                                                                         \
201 static void gedestroy_##latin(gaead_enc *e)                             \
202   { gectx_##latin *enc = (gectx_##latin *)e; BURN(*enc); S_DESTROY(enc); } \
203                                                                         \
204 static gaead_encops geops_##latin =                                     \
205   { &latin##_poly1305, geaad_##latin, gereinit_##latin,                 \
206     geenc_##latin, gedone_##latin, gedestroy_##latin };                 \
207                                                                         \
208 /* Decryption operations. */                                            \
209                                                                         \
210 typedef struct gdctx_##latin {                                          \
211   gaead_dec d;                                                          \
212   latinpoly_aad aad;                                                    \
213   x##latin##_ctx ctx;                                                   \
214   poly1305_ctx poly;                                                    \
215 } gdctx_##latin;                                                        \
216                                                                         \
217 static gaead_aad *gdaad_##latin(gaead_dec *d)                           \
218   { gdctx_##latin *dec = (gdctx_##latin *)d; return (&dec->aad.a); }    \
219                                                                         \
220 static int gdreinit_##latin(gaead_dec *d, const void *n, size_t nsz,    \
221                             size_t hsz, size_t msz, size_t tsz)         \
222 {                                                                       \
223   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
224   return (reinit_##latin(&dec->ctx, &dec->aad.poly, &dec->poly, n, nsz)); \
225 }                                                                       \
226                                                                         \
227 static int gddec_##latin(gaead_dec *d,                                  \
228                          const void *c, size_t csz, buf *b)             \
229 {                                                                       \
230   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
231   void *q;                                                              \
232                                                                         \
233   if (csz) { q = buf_get(b, csz); if (!q) return (-1); }                \
234   else q = 0;                                                           \
235   poly1305_hash(&dec->poly, c, csz);                                    \
236   latin##_encrypt(&dec->ctx.s, c, q, csz);                              \
237   return (0);                                                           \
238 }                                                                       \
239                                                                         \
240 static int gddone_##latin(gaead_dec *d, const gaead_aad *a,             \
241                           buf *b, const void *t, size_t tsz)            \
242 {                                                                       \
243   gdctx_##latin *dec = (gdctx_##latin *)d;                              \
244   const latinpoly_aad *aad = (const latinpoly_aad *)a;                  \
245   octet u[POLY1305_TAGSZ];                                              \
246                                                                         \
247   if (tsz != POLY1305_TAGSZ) return (-1);                               \
248   assert((!dec->aad.poly.count && !dec->aad.poly.nbuf && !a) ||         \
249          a == &dec->aad.a);                                             \
250   if (!BOK(b)) return (-1);                                             \
251   latinpoly_tag(aad ? &aad->poly : 0, &dec->poly, u);                   \
252   if (ct_memeq(t, u, POLY1305_TAGSZ)) return (+1);                      \
253   else return (0);                                                      \
254 }                                                                       \
255                                                                         \
256 static void gddestroy_##latin(gaead_dec *d)                             \
257   { gdctx_##latin *dec = (gdctx_##latin *)d; BURN(*dec); S_DESTROY(dec); } \
258                                                                         \
259 static gaead_decops gdops_##latin =                                     \
260   { &latin##_poly1305, gdaad_##latin, gdreinit_##latin,                 \
261     gddec_##latin, gddone_##latin, gddestroy_##latin };                 \
262                                                                         \
263 /* Key operations. */                                                   \
264                                                                         \
265 static gaead_enc *gkenc_##latin(const gaead_key *k,                     \
266                                 const void *n, size_t nsz,              \
267                                 size_t hsz, size_t msz, size_t tsz)     \
268 {                                                                       \
269   latinpoly_key *key = (latinpoly_key *)k;                              \
270   gectx_##latin *enc = S_CREATE(gectx_##latin);                         \
271                                                                         \
272   enc->e.ops = &geops_##latin; enc->aad.a.ops = &gaops_##latin;         \
273   x##latin##_init(&enc->ctx, key->key, key->ksz, 0);                    \
274   reinit_##latin(&enc->ctx, &enc->aad.poly, &enc->poly, n, nsz);        \
275   return (&enc->e);                                                     \
276 }                                                                       \
277                                                                         \
278 static gaead_dec *gkdec_##latin(const gaead_key *k,                     \
279                                 const void *n, size_t nsz,              \
280                                 size_t hsz, size_t msz, size_t tsz)     \
281 {                                                                       \
282   latinpoly_key *key = (latinpoly_key *)k;                              \
283   gdctx_##latin *dec = S_CREATE(gdctx_##latin);                         \
284                                                                         \
285   dec->d.ops = &gdops_##latin; dec->aad.a.ops = &gaops_##latin;         \
286   x##latin##_init(&dec->ctx, key->key, key->ksz, 0);                    \
287   reinit_##latin(&dec->ctx, &dec->aad.poly, &dec->poly, n, nsz);        \
288   return (&dec->d);                                                     \
289 }                                                                       \
290                                                                         \
291 static void gkdestroy_##latin(gaead_key *k)                             \
292   { latinpoly_key *key = (latinpoly_key *)k; BURN(*key); S_DESTROY(key); } \
293                                                                         \
294 static const gaead_keyops gkops_##latin =                               \
295   { &latin##_poly1305, 0, gkenc_##latin, gkdec_##latin,                 \
296     gkdestroy_##latin };                                                \
297                                                                         \
298 /* Class definition. */                                                 \
299                                                                         \
300 static gaead_key *gkey_##latin(const void *k, size_t ksz)               \
301 {                                                                       \
302   latinpoly_key *key = S_CREATE(latinpoly_key);                         \
303                                                                         \
304   key->k.ops = &gkops_##latin;                                          \
305   KSZ_ASSERT(latin, ksz); memcpy(key->key, k, ksz); key->ksz = ksz;     \
306   return (&key->k);                                                     \
307 }                                                                       \
308                                                                         \
309 const gcaead latin##_poly1305 = {                                       \
310   name "-poly1305", latin##_keysz, latinpoly_noncesz, latinpoly_tagsz,  \
311   64, 0, 0, AEADF_AADNDEP,                                              \
312   gkey_##latin                                                          \
313 };
314
315 /*----- That's all, folks -------------------------------------------------*/
316
317 #ifdef __cplusplus
318   }
319 #endif
320
321 #endif