Commit | Line | Data |
---|---|---|
50df5733 MW |
1 | /* -*-c-*- |
2 | * | |
3 | * The GCM authenticated encryption mode | |
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 | /*----- Notes on GCM ------------------------------------------------------* | |
29 | * | |
30 | * The name is short for `Galois Counter Mode'. GCM was designed in 2005 by | |
31 | * David McGrew and John Viega as a fast, patent-free authenticated | |
32 | * encryption scheme; and it's specified by NIST in SP800-38D. It combines | |
33 | * counter-mode encryption with a Carter--Wegman authenticator based on a | |
34 | * polynomial hash over %$\gf{2^{128}}%, so it needs only one blockcipher | |
35 | * application per message block, together with a multiplication by a | |
36 | * constant in the finite field. GCM is essentially the winner in the | |
37 | * authenticated-encryption-mode competition, to the extent that Intel and | |
38 | * ARM both added instructions to their architectures to accelerate it. | |
39 | * | |
40 | * GCM allows arbitrary-sized nonces, though it's happiest if the nonce is 32 | |
41 | * bits shorter than the block size, leaving a fixed-size block counter in | |
42 | * the low 32 bits. It permits header data to be processed independently of | |
43 | * the message, though doing this requires some slightly fiddly algebra and | |
44 | * most implementations don't allow callers to take advantage of this. | |
45 | * | |
46 | * One downside is that the field multiplication is inefficient in software. | |
47 | * Back in 2005 it was assumed that implementors would use large tables, but | |
48 | * that leaks the authentication secret through the processor cache. This | |
49 | * implementation runs in constant time, but the penalty is that, without | |
50 | * dedicated processor support, it's much slower than an extra blockcipher | |
51 | * application would have been. | |
52 | * | |
53 | * Another downside is that, while GCM came with a security proof, it was | |
54 | * subtly incorrect in a few ways which mean that its concrete security is | |
55 | * significantly less than one would expect. | |
56 | * | |
57 | * If interoperability isn't a concern, then OCB3 is probably a better | |
58 | * choice; if the OCB patent situation is also worrying, then EAX is likely | |
59 | * preferable. | |
60 | */ | |
61 | ||
62 | #ifndef CATACOMB_GCM_H | |
63 | #define CATACOMB_GCM_H | |
64 | ||
65 | #ifdef __cplusplus | |
66 | extern "C" { | |
67 | #endif | |
68 | ||
69 | /*----- Header files ------------------------------------------------------*/ | |
70 | ||
71 | #include <stddef.h> | |
72 | ||
73 | #include <mLib/bits.h> | |
74 | #include <mLib/buf.h> | |
75 | ||
76 | #ifndef CATACOMB_GAEAD_H | |
77 | # include "gaead.h" | |
78 | #endif | |
79 | ||
80 | /*----- Macros ------------------------------------------------------------*/ | |
81 | ||
82 | /* --- @GCM_DECL@ --- * | |
83 | * | |
84 | * Arguments: @PRE@, @pre@ = prefixes for the underlying block cipher | |
85 | * | |
86 | * Use: Creates declarations for GCM authenticated-encryption mode. | |
87 | */ | |
88 | ||
89 | #define GCM_DECL(PRE, pre) \ | |
90 | \ | |
91 | typedef struct pre##_gcmkey { \ | |
92 | pre##_ctx ctx; /* Block cipher key */ \ | |
93 | uint32 ktab[32*PRE##_BLKSZ*PRE##_BLKSZ]; /* Multiplication table */ \ | |
94 | } pre##_gcmkey; \ | |
95 | \ | |
96 | typedef struct pre##_gcmaadctx { \ | |
97 | pre##_gcmkey k; /* Underlying key */ \ | |
98 | uint32 a[PRE##_BLKSZ/4]; /* GHASH accumulator */ \ | |
99 | octet b[PRE##_BLKSZ]; /* Input buffer */ \ | |
100 | unsigned off; /* Length of stuff in buffer */ \ | |
101 | unsigned long len; /* Number of blocks so far */ \ | |
102 | } pre##_gcmaadctx; \ | |
103 | \ | |
104 | typedef struct pre##_gcmctx { \ | |
105 | /* The buffer is split into two portions. The first N octets hold a \ | |
106 | * chunk of ciphertext, which will be fed into the OMAC calculation; \ | |
107 | * the remaining BLKSZ - N octets hold E_K(C), which is the XOR mask \ | |
108 | * to apply to the plaintext or ciphertext. \ | |
109 | */ \ | |
110 | pre##_gcmkey k; /* Underlying key */ \ | |
111 | uint32 c[PRE##_BLKSZ/4]; /* Current counter value */ \ | |
112 | uint32 c0[PRE##_BLKSZ/4]; /* Initial counter */ \ | |
113 | uint32 a[PRE##_BLKSZ]; /* GHASH accumulator */ \ | |
114 | octet b[PRE##_BLKSZ]; /* Ciphertext/mask buffer */ \ | |
115 | unsigned off; /* Crossover point in buffer */ \ | |
116 | unsigned long len; /* Number of blocks so far */ \ | |
117 | } pre##_gcmctx; \ | |
118 | \ | |
119 | extern const octet pre##_gcmnoncesz[], pre##_gcmtagsz[]; \ | |
120 | \ | |
121 | /* --- @pre_gcmsetkey@ --- * \ | |
122 | * \ | |
123 | * Arguments: @pre_gcmkey *key@ = pointer to key block to fill in \ | |
124 | * @const void *k@ = pointer to key material \ | |
125 | * @size_t ksz@ = size of key material \ | |
126 | * \ | |
127 | * Returns: --- \ | |
128 | * \ | |
129 | * Use: Initializes an GCM key block. \ | |
130 | */ \ | |
131 | \ | |
132 | extern void pre##_gcmsetkey(pre##_gcmkey */*key*/, \ | |
133 | const void */*k*/, size_t /*ksz*/); \ | |
134 | \ | |
135 | /* --- @pre_gcmaadinit@ --- * \ | |
136 | * \ | |
137 | * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \ | |
138 | * @const pre_gcmkey *key@ = pointer to key block \ | |
139 | * \ | |
140 | * Returns: --- \ | |
141 | * \ | |
142 | * Use: Initializes an GCM AAD (`additional authenticated \ | |
143 | * data') context associated with a given key. AAD \ | |
144 | * contexts can be copied and/or reused, saving time if \ | |
145 | * the AAD for a number of messages has a common prefix. \ | |
146 | * \ | |
147 | * The @key@ doesn't need to be kept around, though \ | |
148 | * usually there'll at least be another copy in some GCM \ | |
149 | * operation context because the AAD on its own isn't much \ | |
150 | * good. \ | |
151 | */ \ | |
152 | \ | |
153 | extern void pre##_gcmaadinit(pre##_gcmaadctx */*aad*/, \ | |
154 | const pre##_gcmkey */*key*/); \ | |
155 | \ | |
156 | /* --- @pre_gcmaadhash@ --- * \ | |
157 | * \ | |
158 | * Arguments: @pre_gcmaadctx *aad@ = pointer to AAD context \ | |
159 | * @const void *p@ = pointer to AAD material \ | |
160 | * @size_t sz@ = length of AAD material \ | |
161 | * \ | |
162 | * Returns: --- \ | |
163 | * \ | |
164 | * Use: Feeds AAD into the context. \ | |
165 | */ \ | |
166 | \ | |
167 | extern void pre##_gcmaadhash(pre##_gcmaadctx */*aad*/, \ | |
168 | const void */*p*/, size_t /*sz*/); \ | |
169 | \ | |
170 | /* --- @pre_gcminit@ --- * \ | |
171 | * \ | |
172 | * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \ | |
173 | * @const pre_gcmkey *key@ = pointer to key block \ | |
174 | * @const void *n@ = pointer to nonce \ | |
175 | * @size_t nsz@ = size of nonce \ | |
176 | * \ | |
177 | * Returns: --- \ | |
178 | * \ | |
179 | * Use: Initialize an GCM operation context with a given key. \ | |
180 | * \ | |
181 | * The original key needn't be kept around any more. \ | |
182 | */ \ | |
183 | \ | |
184 | extern void pre##_gcminit(pre##_gcmctx */*ctx*/, \ | |
185 | const pre##_gcmkey */*k*/, \ | |
186 | const void */*n*/, size_t /*nsz*/); \ | |
187 | \ | |
188 | /* --- @pre_gcmreinit@ --- * \ | |
189 | * \ | |
190 | * Arguments: @pre_gcmctx *ctx@ = pointer to GCM context \ | |
191 | * @const void *n@ = pointer to nonce \ | |
192 | * @size_t nsz@ = size of nonce \ | |
193 | * \ | |
194 | * Returns: --- \ | |
195 | * \ | |
196 | * Use: Reinitialize an GCM operation context, changing the \ | |
197 | * nonce. \ | |
198 | */ \ | |
199 | \ | |
200 | extern void pre##_gcmreinit(pre##_gcmctx */*ctx*/, \ | |
201 | const void */*n*/, size_t /*nsz*/); \ | |
202 | \ | |
203 | /* --- @pre_gcmencrypt@ --- * \ | |
204 | * \ | |
205 | * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \ | |
206 | * @const void *src@ = pointer to plaintext message chunk \ | |
207 | * @size_t sz@ = size of the plaintext \ | |
208 | * @buf *dst@ = a buffer to write the ciphertext to \ | |
209 | * \ | |
210 | * Returns: Zero on success; @-1@ on failure. \ | |
211 | * \ | |
212 | * Use: Encrypts a chunk of a plaintext message, writing a \ | |
213 | * chunk of ciphertext to the output buffer and updating \ | |
214 | * the operation state. \ | |
215 | * \ | |
216 | * For GCM, we always write a ciphertext chunk the same \ | |
217 | * size as the plaintext. The messing about with @buf@ \ | |
218 | * objects makes the interface consistent with other AEAD \ | |
219 | * schemes which can't do this. \ | |
220 | */ \ | |
221 | \ | |
222 | extern int pre##_gcmencrypt(pre##_gcmctx */*ctx*/, \ | |
223 | const void */*src*/, size_t /*sz*/, \ | |
224 | buf */*dst*/); \ | |
225 | \ | |
226 | /* --- @pre_gcmdecrypt@ --- * \ | |
227 | * \ | |
228 | * Arguments: @pre_gcmctx *ctx@ = pointer to GCM operation context \ | |
229 | * @const void *src@ = pointer to ciphertext message chunk \ | |
230 | * @size_t sz@ = size of the ciphertext \ | |
231 | * @buf *dst@ = a buffer to write the plaintext to \ | |
232 | * \ | |
233 | * Returns: Zero on success; @-1@ on failure. \ | |
234 | * \ | |
235 | * Use: Decrypts a chunk of a ciphertext message, writing a \ | |
236 | * chunk of plaintext to the output buffer and updating \ | |
237 | * the operation state. \ | |
238 | * \ | |
239 | * For GCM, we always write a plaintext chunk the same \ | |
240 | * size as the ciphertext. The messing about with @buf@ \ | |
241 | * objects makes the interface consistent with other AEAD \ | |
242 | * schemes which can't do this. \ | |
243 | */ \ | |
244 | \ | |
245 | extern int pre##_gcmdecrypt(pre##_gcmctx */*ctx*/, \ | |
246 | const void */*src*/, size_t /*sz*/, \ | |
247 | buf */*dst*/); \ | |
248 | \ | |
249 | /* --- @pre_gcmencryptdone@ --- * \ | |
250 | * \ | |
251 | * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \ | |
252 | * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \ | |
253 | * null \ | |
254 | * @buf *dst@ = buffer for remaining ciphertext \ | |
255 | * @void *tag@ = where to write the tag \ | |
256 | * @size_t tsz@ = length of tag to store \ | |
257 | * \ | |
258 | * Returns: Zero on success; @-1@ on failure. \ | |
259 | * \ | |
260 | * Use: Completes an GCM encryption operation. The @aad@ \ | |
261 | * pointer may be null if there is no additional \ | |
262 | * authenticated data. GCM doesn't buffer ciphertext, but \ | |
263 | * the output buffer is provided anyway for consistency \ | |
264 | * with other AEAD schemes which don't have this property; \ | |
265 | * the function will fail if the output buffer is broken. \ | |
266 | */ \ | |
267 | \ | |
268 | extern int pre##_gcmencryptdone(pre##_gcmctx */*ctx*/, \ | |
269 | const pre##_gcmaadctx */*aad*/, \ | |
270 | buf */*dst*/, \ | |
271 | void */*tag*/, size_t /*tsz*/); \ | |
272 | \ | |
273 | /* --- @pre_gcmdecryptdone@ --- * \ | |
274 | * \ | |
275 | * Arguments: @pre_gcmctx *ctx@ = pointer to an GCM context \ | |
276 | * @const pre_gcmaadctx *aad@ = pointer to AAD context, or \ | |
277 | * null \ | |
278 | * @buf *dst@ = buffer for remaining plaintext \ | |
279 | * @const void *tag@ = tag to verify \ | |
280 | * @size_t tsz@ = length of tag \ | |
281 | * \ | |
282 | * Returns: @+1@ for complete success; @0@ if tag verification \ | |
283 | * failed; @-1@ for other kinds of errors. \ | |
284 | * \ | |
285 | * Use: Completes an GCM decryption operation. The @aad@ \ | |
286 | * pointer may be null if there is no additional \ | |
287 | * authenticated data. GCM doesn't buffer plaintext, 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 | \ | |
293 | extern int pre##_gcmdecryptdone(pre##_gcmctx */*ctx*/, \ | |
294 | const pre##_gcmaadctx */*aad*/, \ | |
295 | buf */*dst*/, \ | |
296 | const void */*tag*/, size_t /*tsz*/); \ | |
297 | \ | |
298 | /* --- Generic AEAD interface --- */ \ | |
299 | \ | |
300 | extern const gcaead pre##_gcm; | |
301 | ||
302 | /*----- That's all, folks -------------------------------------------------*/ | |
303 | ||
304 | #ifdef __cplusplus | |
305 | } | |
306 | #endif | |
307 | ||
308 | #endif |