/ src / aead / gcm.c
gcm.c
  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 */
 54  void
 55  br_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 */
 75  void
 76  br_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 */
108  void
109  br_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 */
146  void
147  br_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 */
163  void
164  br_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 */
235  void
236  br_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 */
267  void
268  br_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 */
277  uint32_t
278  br_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 */
293  uint32_t
294  br_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 */
300  const 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  };