chiark / gitweb /
Merge branch '2.4.x' into 2.5.x
[catacomb] / symm / gaead.h
1 /* -*-c-*-
2  *
3  * Generic authenticated encryption interface
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_GAEAD_H
29 #define CATACOMB_GAEAD_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <stddef.h>
38
39 #include <mLib/bits.h>
40
41 #ifndef CATACOMB_BUF_H
42 #  include "buf.h"
43 #endif
44
45 #ifndef CATACOMB_KEYSZ_H
46 #  include "keysz.h"
47 #endif
48
49 /*----- Generic AEAD interface --------------------------------------------*/
50
51 typedef struct gaead_key {
52   const struct gaead_keyops *ops;
53 } gaead_key;
54
55 typedef struct gaead_enc {
56   const struct gaead_encops *ops;
57 } gaead_enc;
58
59 typedef struct gaead_dec {
60   const struct gaead_decops *ops;
61 } gaead_dec;
62
63 typedef struct gaead_aad {
64   const struct gaead_aadops *ops;
65 } gaead_aad;
66
67 typedef struct gaead_keyops {
68   const struct gcaead *c;               /* Pointer to AEAD class */
69
70   gaead_aad *(*aad)(const gaead_key */*k*/);
71         /* Return an AAD-hashing object for this key.  Only available if
72          * the @AEADF_AADNDEP@ class flag is clear.
73          */
74
75   gaead_enc *(*enc)(const gaead_key */*k*/,
76                     const void */*n*/, size_t /*nsz*/,
77                     size_t /*hsz*/, size_t /*msz*/, size_t /*tsz*/);
78         /* Return a message encryption object for this key, with the given
79          * nonce.  If the @AEADF_PCHSZ@, @AEADF_PCMSZ@ and/or @AEADF_PCTSZ@
80          * class flags are set then the caller must provide the AAD length
81          * @hsz@, message length @msz@ and/or tag length @tsz@ respectively;
82          * otherwise these arguments will be ignored.
83          *
84          * The caller is expected to have ensured that the nonce and tag
85          * lengths are acceptable, e.g., by checking against the tables
86          * provided in the class object.  Some unfortunate AEAD schemes have
87          * more complicated requirements: if the sizes are unacceptable in
88          * combination, this function returns null.
89          */
90
91   gaead_dec *(*dec)(const gaead_key */*k*/,
92                     const void */*n*/, size_t /*nsz*/,
93                     size_t /*hsz*/, size_t /*csz*/, size_t /*tsz*/);
94         /* Return a message encryption object for this key, with the given
95          * nonce.  If the @AEADF_PCHSZ@, @AEADF_PCMSZ@ and/or @AEADF_PCTSZ@
96          * class flags are set then the caller must provide the AAD length
97          * @hsz@, ciphertext length @csz@ and/or tag length @tsz@
98          * respectively; otherwise these arguments will be ignored.
99          *
100          * The caller is expected to have ensured that the nonce and tag
101          * lengths are acceptable, e.g., by checking against the tables
102          * provided in the class object.  Some unfortunate AEAD schemes have
103          * more complicated requirements: if the sizes are unacceptable in
104          * combination, this function returns null.
105          */
106
107   void (*destroy)(gaead_key */*k*/);
108         /* Destroy the key object.  This will not invalidate AAD-hashing,
109          * encryption or decryption objects.
110          */
111
112 } gaead_keyops;
113
114 typedef struct gaead_aadops {
115   const struct gcaead *c;               /* Pointer to AEAD class */
116
117   gaead_aad *(*dup)(const gaead_aad */*a*/);
118         /* Return a new AAD-hashing object with a copy of this object's
119          * state.  This is useful if the AAD for multiple messages shares a
120          * common prefix: the prefix can be processed once, and a copy
121          * created for each different suffix.  Only available if the
122          * @AEADF_AADNDEP@ class flag is clear.
123          */
124
125   void (*hash)(gaead_aad */*a*/, const void */*h*/, size_t /*hsz*/);
126         /* Feed header (additional authenticated) data into the AAD-hashing
127          * object.  If the @AEADF_NOAAD@ class flag is set then @hsz@ must be
128          * zero.
129          */
130
131   void (*destroy)(gaead_aad */*a*/);
132         /* Destroy the AAD-hashing object. */
133
134 } gaead_aadops;
135
136 typedef struct gaead_encops {
137   const struct gcaead *c;               /* Pointer to AEAD class */
138
139   gaead_aad *(*aad)(gaead_enc */*e*/);
140         /* Return a new AAD-hashing object for the current key and nonce.  If
141          * the @AEADF_AADNDEP@ class flag is clear then this works just as if
142          * the @aad@ method on the key had been called instead: the new
143          * object is in fact independent of the nonce and can be used with
144          * any encryption or decryption operation.  If @AEADF_AADNDEP@ is
145          * set, then the returned AAD-hashing object is specific to this
146          * encryption operation.  If @AEADF_AADFIRST@ is also set, then all
147          * additional data must be hashed before any message data is
148          * presented for encryption.
149          */
150
151   int (*reinit)(gaead_enc */*e*/, const void */*n*/, size_t /*nsz*/,
152                 size_t /*hsz*/, size_t /*msz*/, size_t /*tsz*/);
153         /* Reinitialize this object for a new encryption operation with a
154          * different nonce.  The data lengths @hsz@, @msz@, and @tsz@ are as
155          * for the key @enc@ method.  Returns zero on success.
156          *
157          * The caller is expected to have ensured that the nonce and tag
158          * lengths are acceptable, e.g., by checking against the tables
159          * provided in the class object.  Some unfortunate AEAD schemes have
160          * more complicated requirements: if the sizes are unacceptable in
161          * combination, this function returns @-1@.
162          */
163
164   int (*encrypt)(gaead_enc */*e*/, const void */*m*/, size_t /*msz*/,
165                  buf */*b*/);
166         /* Encrypt a chunk of data, writing the result to the output buffer
167          * @b@.  This will succeed if @BLEFT(b) >= msz + e->c->bufsz@;
168          * otherwise it might fail.  Failure doesn't affect the encryption
169          * operation's state.  Returns zero on success, or @-1@ on failure.
170          */
171
172   int (*done)(gaead_enc */*e*/, const gaead_aad */*a*/, buf */*b*/,
173               void */*t*/, size_t /*tsz*/);
174         /* Completes encryption, returning the authentication tag for the
175          * message and any additional authenticated data accumulated in @a@.
176          * The pointer @a@ may be null if there is no AAD.  If the
177          * @AEADF_AADNDEP@ class flag is set, and any header data has been
178          * provided to the operation's AAD-hashing object, then a pointer to
179          * this object must be provided as @a@.  If @AEADF_AADNDEP@ is clear,
180          * then any AAD-hashing object for this key may be provided.
181          * Internally buffered ciphertext may be written to @b@.  This will
182          * succeed if @BLEFT(b) >= e->c->bufsz@; otherwise it might fail.
183          * Failure doesn't affect the encryption operation's state.  Returns
184          * zero on success, or @-1@ on failure.
185          */
186
187   void (*destroy)(gaead_enc */*e*/);
188         /* Destroy the encryption object. */
189
190 } gaead_encops;
191
192 typedef struct gaead_decops {
193   const struct gcaead *c;               /* Pointer to AEAD class */
194
195   gaead_aad *(*aad)(gaead_dec */*d*/);
196         /* Return a new AAD-hashing object for the current key and nonce.  If
197          * the @AEADF_AADNDEP@ class flag is clear then this works just as if
198          * the @aad@ method on the key had been called instead: the new
199          * object is in fact independent of the nonce and can be used with
200          * any encryption or decryption operation.  If @AEADF_AADNDEP@ is
201          * set, then the returned AAD-hashing object is specific to this
202          * decryption operation.  If @AEADF_AADFIRST@ is also set, then all
203          * additional data must be hashed before any ciphertext is presented
204          * for decryption.
205          */
206
207   int (*reinit)(gaead_dec */*d*/, const void */*n*/, size_t /*nsz*/,
208                 size_t /*hsz*/, size_t /*csz*/, size_t /*tsz*/);
209         /* Reinitialize this object for a new decryption operation with a
210          * different nonce.  The data lengths @hsz@, @csz@, and @tsz@ are as
211          * for the key @dec@ method.
212          *
213          * The caller is expected to have ensured that the nonce and tag
214          * lengths are acceptable, e.g., by checking against the tables
215          * provided in the class object.  Some unfortunate AEAD schemes have
216          * more complicated requirements: if the sizes are unacceptable in
217          * combination, this function returns @-1@.
218          */
219
220   int (*decrypt)(gaead_dec */*d*/, const void */*c*/, size_t /*csz*/,
221                  buf */*b*/);
222         /* Decrypt a chunk of data, writing the result to the output buffer
223          * @b@.  This will succeed if @BLEFT(b) >= msz + e->c->bufsz@;
224          * otherwise it might fail.  Failure doesn't affect the decryption
225          * operation's state.  Returns zero on success, or @-1@ on failure.
226          *
227          * CAUTION: the decrypted data may be inauthentic.  Don't do anything
228          * risky with it until its tag has been verified.
229          */
230
231   int (*done)(gaead_dec */*d*/, const gaead_aad */*a*/, buf */*b*/,
232               const void */*t*/, size_t /*tsz*/);
233         /* Completes decryption, verifying the authentication tag for the
234          * message and any additional authenticated data accumulated in @a@.
235          * The pointer @a@ may be null if there is no AAD.  If the
236          * @AEADF_AADNDEP@ class flag is set, and any header data has been
237          * provided to the operation's AAD-hashing object, then a pointer to
238          * this object must be provided as @a@.  If @AEADF_AADNDEP@ is clear,
239          * then any AAD-hashing object for this key may be provided.
240          * Internally buffered plaintext may be written to @b@.  This will
241          * succeed if @BLEFT(b) >= e->c->bufsz@; otherwise it might fail.
242          * Failure doesn't affect the decryption operation's state.  Returns
243          * @+1@ on success, @0@ on verification failure, or @-1@ on other
244          * kinds of failures.
245          */
246
247   void (*destroy)(gaead_dec */*d*/);
248         /* Destroy the decryption object. */
249
250 } gaead_decops;
251
252 typedef struct gcaead {
253   const char *name;                     /* AEAD scheme name */
254   const octet *keysz;                   /* Acceptable keys-size table */
255   const octet *noncesz;                 /* Acceptable nonce-size table */
256   const octet *tagsz;                   /* Acceptable tag-size table */
257   size_t blksz;                         /* Block size, or zero if none */
258   unsigned bufsz;                       /* Maximum extra msg/ct output */
259   unsigned ohd;                         /* Maximum encryption overhead */
260   unsigned f;                           /* Various other flags */
261 #define AEADF_PCHSZ 1u                  /*   Precommit to AAD size */
262 #define AEADF_PCMSZ 2u                  /*   Precommit to message size */
263 #define AEADF_PCTSZ 4u                  /*   Precommit to tag size */
264 #define AEADF_AADNDEP 8u                /*   AAD hash is nonce-dependent */
265 #define AEADF_AADFIRST 16u              /*   AAD must precede msg/ct */
266 #define AEADF_NOAAD 32u                 /*   AAD is not permitted */
267
268   gaead_key *(*key)(const void */*k*/, size_t /*ksz*/);
269         /* Return a key object (above) with the given key material. */
270
271   int (*szok)(size_t /*nsz*/, size_t /*hsz*/,
272               size_t /*msz*/, size_t /*tsz*/);
273         /* Return true (nonzero) if the given collection of sizes for nonce,
274          * header, message, and tag are acceptable in combination.  Mostly
275          * this will be true if the nonce length and tag size are are
276          * acceptable independently (and the header and message lengths are
277          * irrelevant), but some schemes are more awkward.
278          */
279 } gcaead;
280
281 #define GAEAD_KEY(cc, k, ksz) (cc)->key((k), (ksz))
282 #define GAEAD_CLASS(obj) (obj)->ops->c
283 #define GAEAD_AAD(ked) (ked)->ops->aad((ked))
284 #define GAEAD_REINIT(ed, n, nsz, hsz, msz, tsz)                         \
285   (ed)->ops->reinit((ed), (n), (nsz), (hsz), (msz), (tsz))
286 #define GAEAD_ENC(k, n, nsz, hsz, msz, tsz)                             \
287   (k)->ops->enc((k), (n), (nsz), (hsz), (msz), (tsz))
288 #define GAEAD_DEC(k, n, nsz, hsz, msz, tsz)                             \
289   (k)->ops->dec((k), (n), (nsz), (hsz), (msz), (tsz))
290 #define GAEAD_DUP(a) (a)->ops->dup((a))
291 #define GAEAD_HASH(a, h, hsz) (a)->ops->hash((a), (h), (hsz))
292 #define GAEAD_ENCRYPT(e, m, msz, b)                                     \
293   (e)->ops->encrypt((e), (m), (msz), (b))
294 #define GAEAD_DECRYPT(d, c, csz, b)                                     \
295   (d)->ops->decrypt((d), (c), (csz), (b))
296 #define GAEAD_DONE(ed, aad, b, t, tsz)                                  \
297   (ed)->ops->done((ed), (aad), (b), (t), (tsz))
298 #define GAEAD_DESTROY(obj) (obj)->ops->destroy((obj))
299
300 /*----- Functions provided ------------------------------------------------*/
301
302 /* --- @gaead_szokcommon@ --- *
303  *
304  * Arguments:   @const gcaead *aec@ = pointer to AEAD class
305  *              @size_t nsz@, @size_t hsz@, @size_t msz@, @size_t tsz@ =
306  *                      nonce, header, message, and tag sizes
307  *
308  * Returns:     Nonzero if the sizes are acceptable to the AEAD scheme in
309  *              combination.
310  *
311  * Use:         Generic implementation for sensible AEAD schemes.
312  */
313
314 extern int gaead_szokcommon(const gcaead */*aec*/,
315                             size_t /*nsz*/, size_t /*hsz*/,
316                             size_t /*msz*/, size_t /*tsz*/);
317
318 /* --- @gaead_encrypt@ --- *
319  *
320  * Arguments:   @const gaead_key *k@ = the AEAD key, already prepared
321  *              @const void *n@, @size_t nsz@ = nonce
322  *              @const void *h@, @size_t hsz@ = additional `header' data
323  *              @const void *m@, @size_t msz@ = message input
324  *              @void *c@, @size_t *csz_input@ = ciphertext output
325  *              @void *t@, @size_t tsz@ = tag output
326  *
327  * Returns:     Zero on success, @-1@ if the output buffer is too small.
328  *
329  * Use:         Encrypts and authenticates a message in a single operation.
330  *              This just saves a bunch of messing about with the various
331  *              @gaead_...@ objects.
332  *
333  *              On entry, @*csz_inout@ should be the capacity of the
334  *              ciphertext buffer; on exit, it will be updated with the
335  *              actual size of ciphertext produced.  The function will not
336  *              fail if @*csz_inout >= msz + k->c->ohd@.
337  */
338
339 extern int gaead_encrypt(const gaead_key */*k*/,
340                          const void */*n*/, size_t /*nsz*/,
341                          const void */*h*/, size_t /*hsz*/,
342                          const void */*m*/, size_t /*msz*/,
343                          void */*c*/, size_t */*csz_inout*/,
344                          void */*t*/, size_t /*tsz*/);
345
346 /* --- @gaead_decrypt@ --- *
347  *
348  * Arguments:   @const gaead_key *k@ = the AEAD key, already prepared
349  *              @const void *n@, @size_t nsz@ = nonce
350  *              @const void *h@, @size_t hsz@ = additional `header' data
351  *              @const void *c@, @size_t csz@ = ciphertext input
352  *              @void *m@, @size_t *msz_inout@ = message output
353  *              @const void *t@, @size_t tsz@ = tag input
354  *
355  * Returns:     @+1@ if everything is good; zero for authentication failure,
356  *              @-1@ for other problems.
357  *
358  * Use:         Decrypts and verifies a message in a single operation.
359  *              This just saves a bunch of messing about with the various
360  *              @gaead_...@ objects.
361  *
362  *              On entry, @*msz_inout@ should be the capacity of the
363  *              message buffer; on exit, it will be updated with the
364  *              actual size of message produced.  The function will not
365  *              fail if @*msz_inout >= csz@.
366  */
367
368 extern int gaead_decrypt(const gaead_key */*k*/,
369                          const void */*n*/, size_t /*nsz*/,
370                          const void */*h*/, size_t /*hsz*/,
371                          const void */*c*/, size_t /*csz*/,
372                          void */*m*/, size_t */*msz_inout*/,
373                          const void */*t*/, size_t /*tsz*/);
374
375 /*----- Tables ------------------------------------------------------------*/
376
377 extern const gcaead *const gaeadtab[];
378
379 /* --- @gaead_byname@ --- *
380  *
381  * Arguments:   @const char *p@ = pointer to name string
382  *
383  * Returns:     The named AEAD class, or null.
384  */
385
386 extern const gcaead *gaead_byname(const char */*p*/);
387
388 /*----- That's all, folks -------------------------------------------------*/
389
390 #ifdef __cplusplus
391   }
392 #endif
393
394 #endif