3 * Generic authenticated encryption interface
5 * (c) 2018 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Catacomb.
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.
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.
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,
28 #ifndef CATACOMB_GAEAD_H
29 #define CATACOMB_GAEAD_H
35 /*----- Header files ------------------------------------------------------*/
39 #include <mLib/bits.h>
41 #ifndef CATACOMB_BUF_H
45 #ifndef CATACOMB_KEYSZ_H
49 /*----- Generic AEAD interface --------------------------------------------*/
51 typedef struct gaead_key
{
52 const struct gaead_keyops
*ops
;
55 typedef struct gaead_enc
{
56 const struct gaead_encops
*ops
;
59 typedef struct gaead_dec
{
60 const struct gaead_decops
*ops
;
63 typedef struct gaead_aad
{
64 const struct gaead_aadops
*ops
;
67 typedef struct gaead_keyops
{
68 const struct gcaead
*c
; /* Pointer to AEAD class */
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.
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.
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.
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.
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.
107 void (*destroy
)(gaead_key */
*k*/
);
108 /* Destroy the key object. This will not invalidate AAD-hashing,
109 * encryption or decryption objects.
114 typedef struct gaead_aadops
{
115 const struct gcaead
*c
; /* Pointer to AEAD class */
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.
125 void (*hash
)(gaead_aad */
*a*/
, const void */
*h*/
, size_t /*hsz*/);
126 /* Feed header (additional authenticated) data into the AAD-hashing
130 void (*destroy
)(gaead_aad */
*a*/
);
131 /* Destroy the AAD-hashing object. */
135 typedef struct gaead_encops
{
136 const struct gcaead
*c
; /* Pointer to AEAD class */
138 gaead_aad
*(*aad
)(gaead_enc */
*e*/
);
139 /* Return a new AAD-hashing object for the current key and nonce. If
140 * the @AEADF_AADNDEP@ class flag is clear then this works just as if
141 * the @aad@ method on the key had been called instead: the new
142 * object is in fact independent of the nonce and can be used with
143 * any encryption or decryption operation. If @AEADF_AADNDEP@ is
144 * set, then the returned AAD-hashing object is specific to this
145 * encryption operation. If @AEADF_AADFIRST@ is also set, then all
146 * additional data must be hashed before any message data is
147 * presented for encryption.
150 int (*reinit
)(gaead_enc */
*e*/
, const void */
*n*/
, size_t /*nsz*/,
151 size_t /*hsz*/, size_t /*msz*/, size_t /*tsz*/);
152 /* Reinitialize this object for a new encryption operation with a
153 * different nonce. The data lengths @hsz@, @msz@, and @tsz@ are as
154 * for the key @enc@ method. Returns zero on success.
156 * The caller is expected to have ensured that the nonce and tag
157 * lengths are acceptable, e.g., by checking against the tables
158 * provided in the class object. Some unfortunate AEAD schemes have
159 * more complicated requirements: if the sizes are unacceptable in
160 * combination, this function returns @-1@.
163 int (*encrypt
)(gaead_enc */
*e*/
, const void */
*m*/
, size_t /*msz*/,
165 /* Encrypt a chunk of data, writing the result to the output buffer
166 * @b@. This will succeed if @BLEFT(b) >= msz + e->c->bufsz@;
167 * otherwise it might fail. Failure doesn't affect the encryption
168 * operation's state. Returns zero on success, or @-1@ on failure.
171 int (*done
)(gaead_enc */
*e*/
, const gaead_aad */
*a*/
, buf */
*b*/
,
172 void */
*t*/
, size_t /*tsz*/);
173 /* Completes encryption, returning the authentication tag for the
174 * message and any additional authenticated data accumulated in @a@.
175 * The pointer @a@ may be null if there is no AAD. If the
176 * @AEADF_AADNDEP@ class flag is set, and any header data has been
177 * provided to the operation's AAD-hashing object, then a pointer to
178 * this object must be provided as @a@. If @AEADF_AADNDEP@ is clear,
179 * then any AAD-hashing object for this key may be provided.
180 * Internally buffered ciphertext may be written to @b@. This will
181 * succeed if @BLEFT(b) >= e->c->bufsz@; otherwise it might fail.
182 * Failure doesn't affect the encryption operation's state. Returns
183 * zero on success, or @-1@ on failure.
186 void (*destroy
)(gaead_enc */
*e*/
);
187 /* Destroy the encryption object. */
191 typedef struct gaead_decops
{
192 const struct gcaead
*c
; /* Pointer to AEAD class */
194 gaead_aad
*(*aad
)(gaead_dec */
*d*/
);
195 /* Return a new AAD-hashing object for the current key and nonce. If
196 * the @AEADF_AADNDEP@ class flag is clear then this works just as if
197 * the @aad@ method on the key had been called instead: the new
198 * object is in fact independent of the nonce and can be used with
199 * any encryption or decryption operation. If @AEADF_AADNDEP@ is
200 * set, then the returned AAD-hashing object is specific to this
201 * decryption operation. If @AEADF_AADFIRST@ is also set, then all
202 * additional data must be hashed before any ciphertext is presented
206 int (*reinit
)(gaead_dec */
*d*/
, const void */
*n*/
, size_t /*nsz*/,
207 size_t /*hsz*/, size_t /*csz*/, size_t /*tsz*/);
208 /* Reinitialize this object for a new decryption operation with a
209 * different nonce. The data lengths @hsz@, @csz@, and @tsz@ are as
210 * for the key @dec@ method.
212 * The caller is expected to have ensured that the nonce and tag
213 * lengths are acceptable, e.g., by checking against the tables
214 * provided in the class object. Some unfortunate AEAD schemes have
215 * more complicated requirements: if the sizes are unacceptable in
216 * combination, this function returns @-1@.
219 int (*decrypt
)(gaead_dec */
*d*/
, const void */
*c*/
, size_t /*csz*/,
221 /* Decrypt a chunk of data, writing the result to the output buffer
222 * @b@. This will succeed if @BLEFT(b) >= msz + e->c->bufsz@;
223 * otherwise it might fail. Failure doesn't affect the decryption
224 * operation's state. Returns zero on success, or @-1@ on failure.
226 * CAUTION: the decrypted data may be inauthentic. Don't do anything
227 * risky with it until its tag has been verified.
230 int (*done
)(gaead_dec */
*d*/
, const gaead_aad */
*a*/
, buf */
*b*/
,
231 const void */
*t*/
, size_t /*tsz*/);
232 /* Completes decryption, verifying the authentication tag for the
233 * message and any additional authenticated data accumulated in @a@.
234 * The pointer @a@ may be null if there is no AAD. If the
235 * @AEADF_AADNDEP@ class flag is set, and any header data has been
236 * provided to the operation's AAD-hashing object, then a pointer to
237 * this object must be provided as @a@. If @AEADF_AADNDEP@ is clear,
238 * then any AAD-hashing object for this key may be provided.
239 * Internally buffered plaintext may be written to @b@. This will
240 * succeed if @BLEFT(b) >= e->c->bufsz@; otherwise it might fail.
241 * Failure doesn't affect the decryption operation's state. Returns
242 * @+1@ on success, @0@ on verification failure, or @-1@ on other
246 void (*destroy
)(gaead_dec */
*d*/
);
247 /* Destroy the decryption object. */
251 typedef struct gcaead
{
252 const char *name
; /* AEAD scheme name */
253 const octet
*keysz
; /* Acceptable keys-size table */
254 const octet
*noncesz
; /* Acceptable nonce-size table */
255 const octet
*tagsz
; /* Acceptable tag-size table */
256 size_t blksz
; /* Block size, or zero if none */
257 unsigned bufsz
; /* Maximum extra msg/ct output */
258 unsigned ohd
; /* Maximum encryption overhead */
259 unsigned f
; /* Various other flags */
260 #define AEADF_PCHSZ 1u /* Precommit to AAD size */
261 #define AEADF_PCMSZ 2u /* Precommit to message size */
262 #define AEADF_PCTSZ 4u /* Precommit to tag size */
263 #define AEADF_AADNDEP 8u /* AAD hash is nonce-dependent */
264 #define AEADF_AADFIRST 16u /* AAD must precede msg/ct */
266 gaead_key
*(*key
)(const void */
*k*/
, size_t /*ksz*/);
267 /* Return a key object (above) with the given key material. */
269 int (*szok
)(size_t /*nsz*/, size_t /*hsz*/,
270 size_t /*msz*/, size_t /*tsz*/);
271 /* Return true (nonzero) if the given collection of sizes for nonce,
272 * header, message, and tag are acceptable in combination. Mostly
273 * this will be true if the nonce length and tag size are are
274 * acceptable independently (and the header and message lengths are
275 * irrelevant), but some schemes are more awkward.
279 #define GAEAD_KEY(cc, k, ksz) (cc)->key((k), (ksz))
280 #define GAEAD_CLASS(obj) (obj)->ops->c
281 #define GAEAD_AAD(ked) (ked)->ops->aad((ked))
282 #define GAEAD_REINIT(ed, n, nsz, hsz, msz, tsz) \
283 (ed)->ops->reinit((ed), (n), (nsz), (hsz), (msz), (tsz))
284 #define GAEAD_ENC(k, n, nsz, hsz, msz, tsz) \
285 (k)->ops->enc((k), (n), (nsz), (hsz), (msz), (tsz))
286 #define GAEAD_DEC(k, n, nsz, hsz, msz, tsz) \
287 (k)->ops->dec((k), (n), (nsz), (hsz), (msz), (tsz))
288 #define GAEAD_DUP(a) (a)->ops->dup((a))
289 #define GAEAD_HASH(a, h, hsz) (a)->ops->hash((a), (h), (hsz))
290 #define GAEAD_ENCRYPT(e, m, msz, b) \
291 (e)->ops->encrypt((e), (m), (msz), (b))
292 #define GAEAD_DECRYPT(d, c, csz, b) \
293 (d)->ops->decrypt((d), (c), (csz), (b))
294 #define GAEAD_DONE(ed, aad, b, t, tsz) \
295 (ed)->ops->done((ed), (aad), (b), (t), (tsz))
296 #define GAEAD_DESTROY(obj) (obj)->ops->destroy((obj))
298 /*----- Functions provided ------------------------------------------------*/
300 /* --- @gaead_szokcommon@ --- *
302 * Arguments: @const gcaead *aec@ = pointer to AEAD class
303 * @size_t nsz@, @size_t hsz@, @size_t msz@, @size_t tsz@ =
304 * nonce, header, message, and tag sizes
306 * Returns: Nonzero if the sizes are acceptable to the AEAD scheme in
309 * Use: Generic implementation for sensible AEAD schemes.
312 extern int gaead_szokcommon(const gcaead */
*aec*/
,
313 size_t /*nsz*/, size_t /*hsz*/,
314 size_t /*msz*/, size_t /*tsz*/);
316 /* --- @gaead_encrypt@ --- *
318 * Arguments: @const gaead_key *k@ = the AEAD key, already prepared
319 * @const void *n@, @size_t nsz@ = nonce
320 * @const void *h@, @size_t hsz@ = additional `header' data
321 * @const void *m@, @size_t msz@ = message input
322 * @void *c@, @size_t *csz_input@ = ciphertext output
323 * @void *t@, @size_t tsz@ = tag output
325 * Returns: Zero on success, @-1@ if the output buffer is too small.
327 * Use: Encrypts and authenticates a message in a single operation.
328 * This just saves a bunch of messing about with the various
329 * @gaead_...@ objects.
331 * On entry, @*csz_inout@ should be the capacity of the
332 * ciphertext buffer; on exit, it will be updated with the
333 * actual size of ciphertext produced. The function will not
334 * fail if @*csz_inout >= msz + k->c->ohd@.
337 extern int gaead_encrypt(const gaead_key */
*k*/
,
338 const void */
*n*/
, size_t /*nsz*/,
339 const void */
*h*/
, size_t /*hsz*/,
340 const void */
*m*/
, size_t /*msz*/,
341 void */
*c*/
, size_t */
*csz_inout*/
,
342 void */
*t*/
, size_t /*tsz*/);
344 /* --- @gaead_decrypt@ --- *
346 * Arguments: @const gaead_key *k@ = the AEAD key, already prepared
347 * @const void *n@, @size_t nsz@ = nonce
348 * @const void *h@, @size_t hsz@ = additional `header' data
349 * @const void *c@, @size_t csz@ = ciphertext input
350 * @void *m@, @size_t *msz_inout@ = message output
351 * @const void *t@, @size_t tsz@ = tag input
353 * Returns: @+1@ if everything is good; zero for authentication failure,
354 * @-1@ for other problems.
356 * Use: Decrypts and verifies a message in a single operation.
357 * This just saves a bunch of messing about with the various
358 * @gaead_...@ objects.
360 * On entry, @*msz_inout@ should be the capacity of the
361 * message buffer; on exit, it will be updated with the
362 * actual size of message produced. The function will not
363 * fail if @*msz_inout >= csz@.
366 extern int gaead_decrypt(const gaead_key */
*k*/
,
367 const void */
*n*/
, size_t /*nsz*/,
368 const void */
*h*/
, size_t /*hsz*/,
369 const void */
*c*/
, size_t /*csz*/,
370 void */
*m*/
, size_t */
*msz_inout*/
,
371 const void */
*t*/
, size_t /*tsz*/);
373 /*----- Tables ------------------------------------------------------------*/
375 extern const gcaead
*const gaeadtab
[];
377 /* --- @gaead_byname@ --- *
379 * Arguments: @const char *p@ = pointer to name string
381 * Returns: The named AEAD class, or null.
384 extern const gcaead
*gaead_byname(const char */
*p*/
);
386 /*----- That's all, folks -------------------------------------------------*/