Commit | Line | Data |
---|---|---|
2964c388 MW |
1 | /* -*-c-*- |
2 | * | |
3 | * The EAX authenticated-encryption mode | |
4 | * | |
5 | * (c) 2017 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 | |
13 | * it under the terms of the GNU Library General Public License as | |
14 | * published by the Free Software Foundation; either version 2 of the | |
15 | * License, or (at your option) any later version. | |
16 | * | |
17 | * Catacomb is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU 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 | |
24 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
25 | * MA 02111-1307, USA. | |
26 | */ | |
27 | ||
28 | /*----- Notes on EAX ------------------------------------------------------* | |
29 | * | |
30 | * The name doesn't appear to be short for anything convincing. EAX was | |
31 | * designed in 2004 by Mihir Bellare, Phillip Rogaway, and David Wagner, as a | |
32 | * response to CCM's deficiencies, which Rogaway and Wagner had complained | |
33 | * about the previous year. Like CCM, it's a patent-free authenticated | |
34 | * encryption scheme based on counter mode and CBC-MAC, and needs two | |
35 | * blockcipher applications per message block, but it's much more refined | |
36 | * than CCM. The EAX specification is clear about how the mode applies to | |
37 | * arbitrary block sizes, and I've not had to make any decisions on how to | |
38 | * extend it myself. | |
39 | * | |
40 | * EAX allows arbitrarily sized nonces, and doesn't require precommitment to | |
41 | * any lengths, and allows header data to be processed independently of any | |
42 | * message. It's basically about as good as a rate-1/2 scheme is going to | |
43 | * be. | |
44 | */ | |
45 | ||
46 | #ifndef CATACOMB_EAX_H | |
47 | #define CATACOMB_EAX_H | |
48 | ||
49 | #ifdef __cplusplus | |
50 | extern "C" { | |
51 | #endif | |
52 | ||
53 | /*----- Header files ------------------------------------------------------*/ | |
54 | ||
55 | #include <stddef.h> | |
56 | ||
57 | #include <mLib/bits.h> | |
58 | #include <mLib/buf.h> | |
59 | ||
60 | #ifndef CATACOMB_GAEAD_H | |
61 | # include "gaead.h" | |
62 | #endif | |
63 | ||
64 | /*----- Macros ------------------------------------------------------------*/ | |
65 | ||
66 | /* --- @EAX_DECL@ --- * | |
67 | * | |
68 | * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher | |
69 | * | |
70 | * Use: Creates declarations for EAX authenticated-encryption mode. | |
71 | */ | |
72 | ||
73 | #define EAX_DECL(PRE, pre) \ | |
74 | \ | |
75 | typedef struct pre##_eaxkey { \ | |
76 | pre##_ctx ctx; /* Block cipher key */ \ | |
77 | uint32 m0[PRE##_BLKSZ/4], m1[PRE##_BLKSZ/4]; /* Final OMAC masks */ \ | |
78 | uint32 v0[PRE##_BLKSZ/4], /* OMAC tweak accumulators */ \ | |
79 | v1[PRE##_BLKSZ/4], v2[PRE##_BLKSZ/4]; \ | |
80 | uint32 z0[PRE##_BLKSZ/4], /* Empty-message tag values */ \ | |
81 | z1[PRE##_BLKSZ/4], z2[PRE##_BLKSZ/4]; \ | |
82 | } pre##_eaxkey; \ | |
83 | \ | |
84 | typedef struct pre##_eaxaadctx { \ | |
85 | pre##_eaxkey k; /* Underlying key */ \ | |
86 | uint32 a[PRE##_BLKSZ/4]; /* OMAC accumulator */ \ | |
87 | octet b[PRE##_BLKSZ]; /* Input buffer */ \ | |
88 | unsigned off; /* Length of stuff in buffer */ \ | |
89 | } pre##_eaxaadctx; \ | |
90 | \ | |
91 | typedef struct pre##_eaxctx { \ | |
92 | /* The buffer is split into two portions. The first N octets hold a \ | |
93 | * chunk of ciphertext, which will be fed into the OMAC calculation; \ | |
94 | * the remaining BLKSZ - N octets hold E_K(C), which is the XOR mask \ | |
95 | * to apply to the plaintext or ciphertext. \ | |
96 | */ \ | |
97 | pre##_eaxkey k; /* Underlying key */ \ | |
98 | uint32 c[PRE##_BLKSZ/4]; /* Current counter value */ \ | |
99 | uint32 c0[PRE##_BLKSZ/4]; /* Initial counter */ \ | |
100 | uint32 a[PRE##_BLKSZ]; /* OMAC accumulator */ \ | |
101 | octet b[PRE##_BLKSZ]; /* Ciphertext/mask buffer */ \ | |
102 | unsigned off; /* Crossover point in buffer */ \ | |
103 | } pre##_eaxctx; \ | |
104 | \ | |
105 | extern const octet pre##_eaxnoncesz[], pre##_eaxtagsz[]; \ | |
106 | \ | |
107 | /* --- @pre_eaxsetkey@ --- * \ | |
108 | * \ | |
109 | * Arguments: @pre_eaxkey *key@ = pointer to key block to fill in \ | |
110 | * @const void *k@ = pointer to key material \ | |
111 | * @size_t ksz@ = size of key material \ | |
112 | * \ | |
113 | * Returns: --- \ | |
114 | * \ | |
115 | * Use: Initializes an EAX key block. \ | |
116 | */ \ | |
117 | \ | |
118 | extern void pre##_eaxsetkey(pre##_eaxkey */*key*/, \ | |
119 | const void */*k*/, size_t /*ksz*/); \ | |
120 | \ | |
121 | /* --- @pre_eaxaadinit@ --- * \ | |
122 | * \ | |
123 | * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \ | |
124 | * @const pre_eaxkey *key@ = pointer to key block \ | |
125 | * \ | |
126 | * Returns: --- \ | |
127 | * \ | |
128 | * Use: Initializes an EAX AAD (`additional authenticated \ | |
129 | * data') context associated with a given key. AAD \ | |
130 | * contexts can be copied and/or reused, saving time if \ | |
131 | * the AAD for a number of messages has a common prefix. \ | |
132 | * \ | |
133 | * The @key@ doesn't need to be kept around, though \ | |
134 | * usually there'll at least be another copy in some EAX \ | |
135 | * operation context because the AAD on its own isn't much \ | |
136 | * good. \ | |
137 | */ \ | |
138 | \ | |
139 | extern void pre##_eaxaadinit(pre##_eaxaadctx */*aad*/, \ | |
140 | const pre##_eaxkey */*key*/); \ | |
141 | \ | |
142 | /* --- @pre_eaxaadhash@ --- * \ | |
143 | * \ | |
144 | * Arguments: @pre_eaxaadctx *aad@ = pointer to AAD context \ | |
145 | * @const void *p@ = pointer to AAD material \ | |
146 | * @size_t sz@ = length of AAD material \ | |
147 | * \ | |
148 | * Returns: --- \ | |
149 | * \ | |
150 | * Use: Feeds AAD into the context. \ | |
151 | */ \ | |
152 | \ | |
153 | extern void pre##_eaxaadhash(pre##_eaxaadctx */*aad*/, \ | |
154 | const void */*p*/, size_t /*sz*/); \ | |
155 | \ | |
156 | /* --- @pre_eaxinit@ --- * \ | |
157 | * \ | |
158 | * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \ | |
159 | * @const pre_eaxkey *key@ = pointer to key block \ | |
160 | * @const void *n@ = pointer to nonce \ | |
161 | * @size_t nsz@ = size of nonce \ | |
162 | * \ | |
163 | * Returns: --- \ | |
164 | * \ | |
165 | * Use: Initialize an EAX operation context with a given key. \ | |
166 | * \ | |
167 | * The original key needn't be kept around any more. \ | |
168 | */ \ | |
169 | \ | |
170 | extern void pre##_eaxinit(pre##_eaxctx */*ctx*/, \ | |
171 | const pre##_eaxkey */*k*/, \ | |
172 | const void */*n*/, size_t /*nsz*/); \ | |
173 | \ | |
174 | /* --- @pre_eaxreinit@ --- * \ | |
175 | * \ | |
176 | * Arguments: @pre_eaxctx *ctx@ = pointer to EAX context \ | |
177 | * @const void *n@ = pointer to nonce \ | |
178 | * @size_t nsz@ = size of nonce \ | |
179 | * \ | |
180 | * Returns: --- \ | |
181 | * \ | |
182 | * Use: Reinitialize an EAX operation context, changing the \ | |
183 | * nonce. \ | |
184 | */ \ | |
185 | \ | |
186 | extern void pre##_eaxreinit(pre##_eaxctx */*ctx*/, \ | |
187 | const void */*n*/, size_t /*nsz*/); \ | |
188 | \ | |
189 | /* --- @pre_eaxencrypt@ --- * \ | |
190 | * \ | |
191 | * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \ | |
192 | * @const void *src@ = pointer to plaintext message chunk \ | |
193 | * @size_t sz@ = size of the plaintext \ | |
194 | * @buf *dst@ = a buffer to write the ciphertext to \ | |
195 | * \ | |
196 | * Returns: Zero on success; @-1@ on failure. \ | |
197 | * \ | |
198 | * Use: Encrypts a chunk of a plaintext message, writing a \ | |
199 | * chunk of ciphertext to the output buffer and updating \ | |
200 | * the operation state. \ | |
201 | * \ | |
202 | * For EAX, we always write a ciphertext chunk the same \ | |
203 | * size as the plaintext. The messing about with @buf@ \ | |
204 | * objects makes the interface consistent with other AEAD \ | |
205 | * schemes which can't do this. \ | |
206 | */ \ | |
207 | \ | |
208 | extern int pre##_eaxencrypt(pre##_eaxctx */*ctx*/, \ | |
209 | const void */*src*/, size_t /*sz*/, \ | |
210 | buf */*dst*/); \ | |
211 | \ | |
212 | /* --- @pre_eaxdecrypt@ --- * \ | |
213 | * \ | |
214 | * Arguments: @pre_eaxctx *ctx@ = pointer to EAX operation context \ | |
215 | * @const void *src@ = pointer to ciphertext message chunk \ | |
216 | * @size_t sz@ = size of the ciphertext \ | |
217 | * @buf *dst@ = a buffer to write the plaintext to \ | |
218 | * \ | |
219 | * Returns: Zero on success; @-1@ on failure. \ | |
220 | * \ | |
221 | * Use: Decrypts a chunk of a ciphertext message, writing a \ | |
222 | * chunk of plaintext to the output buffer and updating \ | |
223 | * the operation state. \ | |
224 | * \ | |
225 | * For EAX, we always write a plaintext chunk the same \ | |
226 | * size as the ciphertext. The messing about with @buf@ \ | |
227 | * objects makes the interface consistent with other AEAD \ | |
228 | * schemes which can't do this. \ | |
229 | */ \ | |
230 | \ | |
231 | extern int pre##_eaxdecrypt(pre##_eaxctx */*ctx*/, \ | |
232 | const void */*src*/, size_t /*sz*/, \ | |
233 | buf */*dst*/); \ | |
234 | \ | |
235 | /* --- @pre_eaxencryptdone@ --- * \ | |
236 | * \ | |
237 | * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \ | |
238 | * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \ | |
239 | * null \ | |
240 | * @buf *dst@ = buffer for remaining ciphertext \ | |
241 | * @void *tag@ = where to write the tag \ | |
242 | * @size_t tsz@ = length of tag to store \ | |
243 | * \ | |
244 | * Returns: Zero on success; @-1@ on failure. \ | |
245 | * \ | |
246 | * Use: Completes an EAX encryption operation. The @aad@ \ | |
247 | * pointer may be null if there is no additional \ | |
248 | * authenticated data. EAX doesn't buffer ciphertext, but \ | |
249 | * the output buffer is provided anyway for consistency \ | |
250 | * with other AEAD schemes which don't have this property; \ | |
251 | * the function will fail if the output buffer is broken. \ | |
252 | */ \ | |
253 | \ | |
254 | extern int pre##_eaxencryptdone(pre##_eaxctx */*ctx*/, \ | |
255 | const pre##_eaxaadctx */*aad*/, \ | |
256 | buf */*dst*/, \ | |
257 | void */*tag*/, size_t /*tsz*/); \ | |
258 | \ | |
259 | /* --- @pre_eaxdecryptdone@ --- * \ | |
260 | * \ | |
261 | * Arguments: @pre_eaxctx *ctx@ = pointer to an EAX context \ | |
262 | * @const pre_eaxaadctx *aad@ = pointer to AAD context, or \ | |
263 | * null \ | |
264 | * @buf *dst@ = buffer for remaining plaintext \ | |
265 | * @const void *tag@ = tag to verify \ | |
266 | * @size_t tsz@ = length of tag \ | |
267 | * \ | |
268 | * Returns: @+1@ for complete success; @0@ if tag verification \ | |
269 | * failed; @-1@ for other kinds of errors. \ | |
270 | * \ | |
271 | * Use: Completes an EAX decryption operation. The @aad@ \ | |
272 | * pointer may be null if there is no additional \ | |
273 | * authenticated data. EAX doesn't buffer plaintext, but \ | |
274 | * the output buffer is provided anyway for consistency \ | |
275 | * with other AEAD schemes which don't have this property; \ | |
276 | * the function will fail if the output buffer is broken. \ | |
277 | */ \ | |
278 | \ | |
279 | extern int pre##_eaxdecryptdone(pre##_eaxctx */*ctx*/, \ | |
280 | const pre##_eaxaadctx */*aad*/, \ | |
281 | buf */*dst*/, \ | |
282 | const void */*tag*/, size_t /*tsz*/); \ | |
283 | \ | |
284 | /* --- Generic AEAD interface --- */ \ | |
285 | \ | |
286 | extern const gcaead pre##_eax; | |
287 | ||
288 | /*----- That's all, folks -------------------------------------------------*/ | |
289 | ||
290 | #ifdef __cplusplus | |
291 | } | |
292 | #endif | |
293 | ||
294 | #endif |