1/*
2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#include "inner.h"
26
27/*
28 * Implementation Notes
29 * ====================
30 *
31 * Since CTR and GHASH implementations can handle only full blocks, a
32 * 16-byte buffer (buf[]) is maintained in the context:
33 *
34 *  - When processing AAD, buf[] contains the 0-15 unprocessed bytes.
35 *
36 *  - When doing CTR encryption / decryption, buf[] contains the AES output
37 *    for the last partial block, to be used with the next few bytes of
38 *    data, as well as the already encrypted bytes. For instance, if the
39 *    processed data length so far is 21 bytes, then buf[0..4] contains
40 *    the five last encrypted bytes, and buf[5..15] contains the next 11
41 *    AES output bytes to be XORed with the next 11 bytes of input.
42 *
43 *    The recorded AES output bytes are used to complete the block when
44 *    the corresponding bytes are obtained. Note that buf[] always
45 *    contains the _encrypted_ bytes, whether we apply encryption or
46 *    decryption: these bytes are used as input to GHASH when the block
47 *    is complete.
48 *
49 * In both cases, the low bits of the data length counters (count_aad,
50 * count_ctr) are used to work out the current situation.
51 */
52
53/* see bearssl_aead.h */
54void
55br_gcm_init(br_gcm_context *ctx, const br_block_ctr_class **bctx, br_ghash gh)
56{
57	unsigned char iv[12];
58
59	ctx->vtable = &br_gcm_vtable;
60	ctx->bctx = bctx;
61	ctx->gh = gh;
62
63	/*
64	 * The GHASH key h[] is the raw encryption of the all-zero
65	 * block. Since we only have a CTR implementation, we use it
66	 * with an all-zero IV and a zero counter, to CTR-encrypt an
67	 * all-zero block.
68	 */
69	memset(ctx->h, 0, sizeof ctx->h);
70	memset(iv, 0, sizeof iv);
71	(*bctx)->run(bctx, iv, 0, ctx->h, sizeof ctx->h);
72}
73
74/* see bearssl_aead.h */
75void
76br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len)
77{
78	/*
79	 * If the provided nonce is 12 bytes, then this is the initial
80	 * IV for CTR mode; it will be used with a counter that starts
81	 * at 2 (value 1 is for encrypting the GHASH output into the tag).
82	 *
83	 * If the provided nonce has any other length, then it is hashed
84	 * (with GHASH) into a 16-byte value that will be the IV for CTR
85	 * (both 12-byte IV and 32-bit counter).
86	 */
87	if (len == 12) {
88		memcpy(ctx->j0_1, iv, 12);
89		ctx->j0_2 = 1;
90	} else {
91		unsigned char ty[16], tmp[16];
92
93		memset(ty, 0, sizeof ty);
94		ctx->gh(ty, ctx->h, iv, len);
95		memset(tmp, 0, 8);
96		br_enc64be(tmp + 8, (uint64_t)len << 3);
97		ctx->gh(ty, ctx->h, tmp, 16);
98		memcpy(ctx->j0_1, ty, 12);
99		ctx->j0_2 = br_dec32be(ty + 12);
100	}
101	ctx->jc = ctx->j0_2 + 1;
102	memset(ctx->y, 0, sizeof ctx->y);
103	ctx->count_aad = 0;
104	ctx->count_ctr = 0;
105}
106
107/* see bearssl_aead.h */
108void
109br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len)
110{
111	size_t ptr, dlen;
112
113	ptr = (size_t)ctx->count_aad & (size_t)15;
114	if (ptr != 0) {
115		/*
116		 * If there is a partial block, then we first try to
117		 * complete it.
118		 */
119		size_t clen;
120
121		clen = 16 - ptr;
122		if (len < clen) {
123			memcpy(ctx->buf + ptr, data, len);
124			ctx->count_aad += (uint64_t)len;
125			return;
126		}
127		memcpy(ctx->buf + ptr, data, clen);
128		ctx->gh(ctx->y, ctx->h, ctx->buf, 16);
129		data = (const unsigned char *)data + clen;
130		len -= clen;
131		ctx->count_aad += (uint64_t)clen;
132	}
133
134	/*
135	 * Now AAD is aligned on a 16-byte block (with regards to GHASH).
136	 * We process all complete blocks, and save the last partial
137	 * block.
138	 */
139	dlen = len & ~(size_t)15;
140	ctx->gh(ctx->y, ctx->h, data, dlen);
141	memcpy(ctx->buf, (const unsigned char *)data + dlen, len - dlen);
142	ctx->count_aad += (uint64_t)len;
143}
144
145/* see bearssl_aead.h */
146void
147br_gcm_flip(br_gcm_context *ctx)
148{
149	/*
150	 * We complete the GHASH computation if there is a partial block.
151	 * The GHASH implementation automatically applies padding with
152	 * zeros.
153	 */
154	size_t ptr;
155
156	ptr = (size_t)ctx->count_aad & (size_t)15;
157	if (ptr != 0) {
158		ctx->gh(ctx->y, ctx->h, ctx->buf, ptr);
159	}
160}
161
162/* see bearssl_aead.h */
163void
164br_gcm_run(br_gcm_context *ctx, int encrypt, void *data, size_t len)
165{
166	unsigned char *buf;
167	size_t ptr, dlen;
168
169	buf = data;
170	ptr = (size_t)ctx->count_ctr & (size_t)15;
171	if (ptr != 0) {
172		/*
173		 * If we have a partial block, then we try to complete it.
174		 */
175		size_t u, clen;
176
177		clen = 16 - ptr;
178		if (len < clen) {
179			clen = len;
180		}
181		for (u = 0; u < clen; u ++) {
182			unsigned x, y;
183
184			x = buf[u];
185			y = x ^ ctx->buf[ptr + u];
186			ctx->buf[ptr + u] = encrypt ? y : x;
187			buf[u] = y;
188		}
189		ctx->count_ctr += (uint64_t)clen;
190		buf += clen;
191		len -= clen;
192		if (ptr + clen < 16) {
193			return;
194		}
195		ctx->gh(ctx->y, ctx->h, ctx->buf, 16);
196	}
197
198	/*
199	 * Process full blocks.
200	 */
201	dlen = len & ~(size_t)15;
202	if (!encrypt) {
203		ctx->gh(ctx->y, ctx->h, buf, dlen);
204	}
205	ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->jc, buf, dlen);
206	if (encrypt) {
207		ctx->gh(ctx->y, ctx->h, buf, dlen);
208	}
209	buf += dlen;
210	len -= dlen;
211	ctx->count_ctr += (uint64_t)dlen;
212
213	if (len > 0) {
214		/*
215		 * There is a partial block.
216		 */
217		size_t u;
218
219		memset(ctx->buf, 0, sizeof ctx->buf);
220		ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1,
221			ctx->jc, ctx->buf, 16);
222		for (u = 0; u < len; u ++) {
223			unsigned x, y;
224
225			x = buf[u];
226			y = x ^ ctx->buf[u];
227			ctx->buf[u] = encrypt ? y : x;
228			buf[u] = y;
229		}
230		ctx->count_ctr += (uint64_t)len;
231	}
232}
233
234/* see bearssl_aead.h */
235void
236br_gcm_get_tag(br_gcm_context *ctx, void *tag)
237{
238	size_t ptr;
239	unsigned char tmp[16];
240
241	ptr = (size_t)ctx->count_ctr & (size_t)15;
242	if (ptr > 0) {
243		/*
244		 * There is a partial block: encrypted/decrypted data has
245		 * been produced, but the encrypted bytes must still be
246		 * processed by GHASH.
247		 */
248		ctx->gh(ctx->y, ctx->h, ctx->buf, ptr);
249	}
250
251	/*
252	 * Final block for GHASH: the AAD and plaintext lengths (in bits).
253	 */
254	br_enc64be(tmp, ctx->count_aad << 3);
255	br_enc64be(tmp + 8, ctx->count_ctr << 3);
256	ctx->gh(ctx->y, ctx->h, tmp, 16);
257
258	/*
259	 * Tag is the GHASH output XORed with the encryption of the
260	 * nonce with the initial counter value.
261	 */
262	memcpy(tag, ctx->y, 16);
263	(*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->j0_2, tag, 16);
264}
265
266/* see bearssl_aead.h */
267void
268br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len)
269{
270	unsigned char tmp[16];
271
272	br_gcm_get_tag(ctx, tmp);
273	memcpy(tag, tmp, len);
274}
275
276/* see bearssl_aead.h */
277uint32_t
278br_gcm_check_tag_trunc(br_gcm_context *ctx, const void *tag, size_t len)
279{
280	unsigned char tmp[16];
281	size_t u;
282	int x;
283
284	br_gcm_get_tag(ctx, tmp);
285	x = 0;
286	for (u = 0; u < len; u ++) {
287		x |= tmp[u] ^ ((const unsigned char *)tag)[u];
288	}
289	return EQ0(x);
290}
291
292/* see bearssl_aead.h */
293uint32_t
294br_gcm_check_tag(br_gcm_context *ctx, const void *tag)
295{
296	return br_gcm_check_tag_trunc(ctx, tag, 16);
297}
298
299/* see bearssl_aead.h */
300const br_aead_class br_gcm_vtable = {
301	16,
302	(void (*)(const br_aead_class **, const void *, size_t))
303		&br_gcm_reset,
304	(void (*)(const br_aead_class **, const void *, size_t))
305		&br_gcm_aad_inject,
306	(void (*)(const br_aead_class **))
307		&br_gcm_flip,
308	(void (*)(const br_aead_class **, int, void *, size_t))
309		&br_gcm_run,
310	(void (*)(const br_aead_class **, void *))
311		&br_gcm_get_tag,
312	(uint32_t (*)(const br_aead_class **, const void *))
313		&br_gcm_check_tag,
314	(void (*)(const br_aead_class **, void *, size_t))
315		&br_gcm_get_tag_trunc,
316	(uint32_t (*)(const br_aead_class **, const void *, size_t))
317		&br_gcm_check_tag_trunc
318};
319