Merge branch '2.5.x'
[catacomb] / symm / ccm.h
CommitLineData
55b6b722
MW
1/* -*-c-*-
2 *
3 * The CCM 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 CCM ------------------------------------------------------*
29 *
30 * The name is short for `Counter with CBC-MAC'. CCM was designed in 2002 by
31 * Russ Housley, Doug Whiting, and Niels Ferguson to be a patent-free
32 * alternative to Rogaway's OCB, and is specified by NIST in SP800-38C. It's
33 * a classic two-pass authenticated encryption scheme, so it needs two
34 * blockcipher applications per message block.
35 *
36 * Unfortunately, CCM is rather annoying in actual use. The internals
37 * involve quite a lot of fiddly framing, which I've had to generalize for
38 * block sizes other than 128 bits, but that's not exposed beyond the API.
39 * (This does mean that it's rather unlikely that Catacomb's CCM will
40 * interoperate with anyone else's when using a blockcipher with a block size
41 * other than 128 bits.)
42 *
43 * More problematically:
44 *
45 * * The mode requires that callers precommit to the header, message, and
46 * tag sizes before commencing processing. If you don't know these in
47 * advance then you can't use CCM.
48 *
49 * * The mode requires that callers present all of the header data before
50 * encrypting the message.
51 *
52 * * The header data processing is dependent on the nonce (and the message
53 * and tag lengths), so it's not possible to preprocess a constant prefix
54 * of the header.
55 *
56 * * There's an uncomfortable tradeoff between nonce length and message
57 * length because the counter input holds both in separate fields, with a
58 * variably-positioned split between them.
59 *
60 * The implementation is very picky and will abort if you get things wrong.
61 */
62
63#ifndef CATACOMB_CCM_H
64#define CATACOMB_CCM_H
65
66#ifdef __cplusplus
67 extern "C" {
68#endif
69
70/*----- Header files ------------------------------------------------------*/
71
72#include <stddef.h>
73
74#include <mLib/bits.h>
75#include <mLib/buf.h>
76
77#ifndef CATACOMB_GAEAD_H
78# include "gaead.h"
79#endif
80
81/*----- Common machinery -------------------------------------------------*/
82
83typedef struct ccm_params {
84 unsigned long hsz, msz; /* AAD and message lengths */
85 unsigned bsz, nsz, tsz; /* Block, nonce and tag length */
86} ccm_params;
87
88enum { CCMST_AAD, CCMST_MSG };
89
90/* Minimum and maximum nonce lengths.
91 *
92 * Let the block size be %$N$% bytes, and let %$q$% be the length-of-the-
93 * length of the messaage. The nonce length is not encoded directly; rather,
94 * it's what's left after the flags bytes and message length fields have been
95 * allocated.
96 *
97 * The maximum is always %$N - 3$%. If %$N \le 16$%, then there is one byte
98 * used for flags, and at least two bytes for the message length/counter:
99 * (since %$q$% is encoded in a 3-bit field as %$q - 1$%, %$q = 0$% cannot be
100 * encoded and the encoding zero, for %$q = 1$%, is reserved. If %$N > 16$
101 * then there are two flags bytes, but %$q$% is encoded directly, so only
102 * %$q = 0$% is reserved.
103 *
104 * The minimum is more complicated. If %$N \le 16$% then we must have %$q
105 * \le 8$%; with one flags byte, this leaves at least %$\max\{ 0, N - 9 \}$%
106 * bytes for the nonce. When %$N = 8$% this is zero, but when %$N = 16$%
107 * this is 7. When %$N > 16$%, there are two flags bits, but %$q \le 127$%
108 * (since %$q$%) is encoded directly: thus the nonce may be empty if
109 * %$16 < N \le 129$%, and otherwise must be at least %$N - 129$% bytes.
110 */
111#define CCM_NSZMIN(PRE) (PRE##_BLKSZ == 16 ? 7 : \
112 PRE##_BLKSZ <= 129 ? 0 : \
113 PRE##_BLKSZ - 129)
114#define CCM_NSZMAX(PRE) (PRE##_BLKSZ - 3)
115
116/* Minimum and maximum tag lengths.
117 *
118 * This is even more exasperating. Again, let the block size be %$N$% bytes;
119 * let %$t$% be the tag length.
120 *
121 * When %$N = 16$%, the tag length is encoded as %$t/2 - 1$% in a three-bit
122 * field, and the encoding zero is reserved. (The security of the scheme
123 * depends on this reservation to disambiguate MAC header blocks from
124 * counters; I'd have used the remaining flag bit.) Anyway, this leaves
125 * %$1 \le t/2 - 1 \le 7$%, so we must have %$4 \le t \le 16$% with %$t$%
126 * even.
127 *
128 * When %$N = 8$%, the tag length is encoded in three bits as %$t - 1$%;
129 * again, the zero encoding is reserved. This leaves %$2 \le t \le 8$%.
130 *
131 * Finally, when %$N \ge 16$%, the tag length is encoded directly in a
132 * seven-bit field. The zero encoding is still reserved, so we have
133 * %$1 \le t \le \min \{ N, 127 \}$%.
134 */
135#define CCM_TSZMIN(PRE) (PRE##_BLKSZ == 8 ? 2 : \
136 PRE##_BLKSZ == 16 ? 4 : \
137 1)
138#define CCM_TSZMAX(PRE) (PRE##_BLKSZ <= 127 ? PRE##_BLKSZ : 127)
139
140/*----- Macros ------------------------------------------------------------*/
141
142/* --- @CCM_DECL@ --- *
143 *
144 * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher
145 *
146 * Use: Creates declarations for CCM authenticated-encryption mode.
147 */
148
149#define CCM_DECL(PRE, pre) \
150 \
151typedef struct pre##_ccmctx { \
152 /* The buffer is split into two portions during encryption/ \
153 * decryption. The first N octets hold a chunk of plaintext, which \
154 * will be fed into the CBC-MAC calculation; the remaining BLKSZ - N \
155 * octets hold E_K(C), which is the XOR mask to apply to the \
156 * plaintext or ciphertext. \
157 */ \
158 pre##_ctx k; /* Underlying key */ \
159 ccm_params p; /* CCM parameters */ \
160 unsigned long i; /* Current position in bytes */ \
161 unsigned st; /* Current state */ \
162 uint32 c[PRE##_BLKSZ/4]; /* Current counter value */ \
163 uint32 a[PRE##_BLKSZ/4]; /* CBC-MAC accumulator */ \
164 uint32 s0[PRE##_BLKSZ/4]; /* Mask for MAC tag */ \
165 octet b[PRE##_BLKSZ]; /* AAD or msg/mask buffer */ \
166 unsigned off; /* Crossover point in buffer */ \
167} pre##_ccmctx; \
168 \
169extern const octet pre##_ccmnoncesz[], pre##_ccmtagsz[]; \
170 \
171/* --- @pre_ccminit@ --- * \
172 * \
173 * Arguments: @pre_ccmctx *aad@ = pointer to CCM context \
174 * @const pre_ctx *k@ = pointer to key material \
175 * @const void *n@ = pointer to nonce \
176 * @size_t nsz@ = size of the nonce \
177 * @size_t hsz@ = size of the AAD \
178 * @size_t msz@ = size of the message/ciphertext \
179 * @size_t tsz@ = size of the tag to produce \
180 * \
181 * Returns: Zero on success; nonzero if the parameters are invalid. \
182 * \
183 * Use: Initialize an CCM operation context with a given key. \
184 * \
185 * The original key needn't be kept around any more. \
186 */ \
187 \
188extern int pre##_ccminit(pre##_ccmctx */*ctx*/, \
189 const pre##_ctx */*k*/, \
190 const void */*n*/, size_t /*nsz*/, \
191 size_t /*hsz*/, size_t /*msz*/, \
192 size_t /*tsz*/); \
193 \
194/* --- @pre_ccmreinit@ --- * \
195 * \
196 * Arguments: @pre_ccmctx *ctx@ = pointer to CCM context \
197 * @const void *n@ = pointer to nonce \
198 * @size_t nsz@ = size of nonce \
199 * @size_t hsz@ = size of the AAD \
200 * @size_t msz@ = size of the message/ciphertext \
201 * @size_t tsz@ = size of the tag to produce \
202 * \
203 * Returns: Zero on success; nonzero if the parameters are invalid. \
204 * \
205 * Use: Reinitialize an CCM operation context, changing the \
206 * nonce and/or other parameters. \
207 */ \
208 \
209extern int pre##_ccmreinit(pre##_ccmctx */*ctx*/, \
210 const void */*n*/, size_t /*nsz*/, \
211 size_t /*hsz*/, size_t /*msz*/, \
212 size_t /*tsz*/); \
213 \
214/* --- @pre_ccmaadhash@ --- * \
215 * \
216 * Arguments: @pre_ccmctx *ctx@ = pointer to AAD context \
217 * @const void *p@ = pointer to AAD material \
218 * @size_t sz@ = length of AAD material \
219 * \
220 * Returns: --- \
221 * \
222 * Use: Feeds AAD into the context. This must be done before \
223 * any of the message/ciphertext is processed because CCM \
224 * is really annoying like that. \
225 */ \
226 \
227extern void pre##_ccmaadhash(pre##_ccmctx */*ctx*/, \
228 const void */*p*/, size_t /*sz*/); \
229 \
230/* --- @pre_ccmencrypt@ --- * \
231 * \
232 * Arguments: @pre_ccmctx *ctx@ = pointer to CCM operation context \
233 * @const void *src@ = pointer to plaintext message chunk \
234 * @size_t sz@ = size of the plaintext \
235 * @buf *dst@ = a buffer to write the ciphertext to \
236 * \
237 * Returns: Zero on success; @-1@ on failure. \
238 * \
239 * Use: Encrypts a chunk of a plaintext message, writing a \
240 * chunk of ciphertext to the output buffer and updating \
241 * the operation state. \
242 * \
243 * For CCM, we always write a ciphertext chunk the same \
244 * size as the plaintext. The messing about with @buf@ \
245 * objects makes the interface consistent with other AEAD \
246 * schemes which can't do this. \
247 */ \
248 \
249extern int pre##_ccmencrypt(pre##_ccmctx */*ctx*/, \
250 const void */*src*/, size_t /*sz*/, \
251 buf */*dst*/); \
252 \
253/* --- @pre_ccmdecrypt@ --- * \
254 * \
255 * Arguments: @pre_ccmctx *ctx@ = pointer to CCM operation context \
256 * @const void *src@ = pointer to ciphertext message chunk \
257 * @size_t sz@ = size of the ciphertext \
258 * @buf *dst@ = a buffer to write the plaintext to \
259 * \
260 * Returns: Zero on success; @-1@ on failure. \
261 * \
262 * Use: Decrypts a chunk of a ciphertext message, writing a \
263 * chunk of plaintext to the output buffer and updating \
264 * the operation state. \
265 * \
266 * For CCM, we always write a plaintext chunk the same \
267 * size as the ciphertext. The messing about with @buf@ \
268 * objects makes the interface consistent with other AEAD \
269 * schemes which can't do this. \
270 */ \
271 \
272extern int pre##_ccmdecrypt(pre##_ccmctx */*ctx*/, \
273 const void */*src*/, size_t /*sz*/, \
274 buf */*dst*/); \
275 \
276/* --- @pre_ccmencryptdone@ --- * \
277 * \
278 * Arguments: @pre_ccmctx *ctx@ = pointer to an CCM context \
279 * @buf *dst@ = buffer for remaining ciphertext \
280 * @void *tag@ = where to write the tag \
281 * @size_t tsz@ = length of tag to store \
282 * \
283 * Returns: Zero on success; @-1@ on failure. \
284 * \
285 * Use: Completes an CCM encryption operation. The @aad@ \
286 * pointer may be null if there is no additional \
287 * authenticated data. CCM doesn't buffer ciphertext, but \
288 * the output buffer is provided anyway for consistency \
289 * with other AEAD schemes which don't have this property; \
290 * the function will fail if the output buffer is broken. \
291 */ \
292 \
293extern int pre##_ccmencryptdone(pre##_ccmctx */*ctx*/, buf */*dst*/, \
294 void */*tag*/, size_t /*tsz*/); \
295 \
296/* --- @pre_ccmdecryptdone@ --- * \
297 * \
298 * Arguments: @pre_ccmctx *ctx@ = pointer to an CCM context \
299 * @buf *dst@ = buffer for remaining plaintext \
300 * @const void *tag@ = tag to verify \
301 * @size_t tsz@ = length of tag \
302 * \
303 * Returns: @+1@ for complete success; @0@ if tag verification \
304 * failed; @-1@ for other kinds of errors. \
305 * \
306 * Use: Completes an CCM decryption operation. The @aad@ \
307 * pointer may be null if there is no additional \
308 * authenticated data. CCM doesn't buffer plaintext, but \
309 * the output buffer is provided anyway for consistency \
310 * with other AEAD schemes which don't have this property; \
311 * the function will fail if the output buffer is broken. \
312 */ \
313 \
314extern int pre##_ccmdecryptdone(pre##_ccmctx */*ctx*/, buf */*dst*/, \
315 const void */*tag*/, size_t /*tsz*/); \
316 \
317/* --- Generic AEAD interface --- */ \
318 \
319extern const gcaead pre##_ccm;
320
321/*----- That's all, folks -------------------------------------------------*/
322
323#ifdef __cplusplus
324 }
325#endif
326
327#endif