gcm.c
Go to the documentation of this file.
1 /**
2  * @file gcm.c
3  * @brief Galois/Counter Mode (GCM)
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @section Description
26  *
27  * The Galois/Counter Mode (GCM) is an authenticated encryption algorithm
28  * designed to provide both data authenticity (integrity) and confidentiality.
29  * Refer to SP 800-38D for more details
30  *
31  * @author Oryx Embedded SARL (www.oryx-embedded.com)
32  * @version 1.9.0
33  **/
34 
35 //Switch to the appropriate trace level
36 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
37 
38 //Dependencies
39 #include "core/crypto.h"
40 #include "aead/gcm.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (GCM_SUPPORT == ENABLED)
45 
46 //Reduction table
47 static const uint32_t r[16] =
48 {
49  0x00000000,
50  0x1C200000,
51  0x38400000,
52  0x24600000,
53  0x70800000,
54  0x6CA00000,
55  0x48C00000,
56  0x54E00000,
57  0xE1000000,
58  0xFD200000,
59  0xD9400000,
60  0xC5600000,
61  0x91800000,
62  0x8DA00000,
63  0xA9C00000,
64  0xB5E00000
65 };
66 
67 
68 /**
69  * @brief Initialize GCM context
70  * @param[in] context Pointer to the GCM context
71  * @param[in] cipherAlgo Cipher algorithm
72  * @param[in] cipherContext Pointer to the cipher algorithm context
73  * @return Error code
74  **/
75 
76 error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
77  void *cipherContext)
78 {
79  uint_t i;
80  uint_t j;
81  uint32_t c;
82  uint32_t h[4];
83 
84  //GCM supports only symmetric block ciphers whose block size is 128 bits
85  if(cipherAlgo->type != CIPHER_ALGO_TYPE_BLOCK || cipherAlgo->blockSize != 16)
87 
88  //Save cipher algorithm context
89  context->cipherAlgo = cipherAlgo;
90  context->cipherContext = cipherContext;
91 
92  //Let H = 0
93  h[0] = 0;
94  h[1] = 0;
95  h[2] = 0;
96  h[3] = 0;
97 
98  //Generate the hash subkey H
99  context->cipherAlgo->encryptBlock(context->cipherContext,
100  (uint8_t *) h, (uint8_t *) h);
101 
102  //Pre-compute M(0) = H * 0
103  j = reverseInt4(0);
104  context->m[j][0] = 0;
105  context->m[j][1] = 0;
106  context->m[j][2] = 0;
107  context->m[j][3] = 0;
108 
109  //Pre-compute M(1) = H * 1
110  j = reverseInt4(1);
111  context->m[j][0] = betoh32(h[3]);
112  context->m[j][1] = betoh32(h[2]);
113  context->m[j][2] = betoh32(h[1]);
114  context->m[j][3] = betoh32(h[0]);
115 
116  //Pre-compute all 4-bit multiples of H
117  for(i = 2; i < 16; i++)
118  {
119  //Odd value?
120  if(i & 1)
121  {
122  //Compute M(i) = M(i - 1) + H
123  j = reverseInt4(i - 1);
124  h[0] = context->m[j][0];
125  h[1] = context->m[j][1];
126  h[2] = context->m[j][2];
127  h[3] = context->m[j][3];
128 
129  //An addition in GF(2^128) is identical to a bitwise exclusive-OR
130  //operation
131  j = reverseInt4(1);
132  h[0] ^= context->m[j][0];
133  h[1] ^= context->m[j][1];
134  h[2] ^= context->m[j][2];
135  h[3] ^= context->m[j][3];
136  }
137  //Even value?
138  else
139  {
140  //Compute M(i) = M(i / 2) * x
141  j = reverseInt4(i / 2);
142  h[0] = context->m[j][0];
143  h[1] = context->m[j][1];
144  h[2] = context->m[j][2];
145  h[3] = context->m[j][3];
146 
147  //The multiplication of a polynomial by x in GF(2^128) corresponds
148  //to a shift of indices
149  c = h[0] & 0x01;
150  h[0] = (h[0] >> 1) | (h[1] << 31);
151  h[1] = (h[1] >> 1) | (h[2] << 31);
152  h[2] = (h[2] >> 1) | (h[3] << 31);
153  h[3] >>= 1;
154 
155  //If the highest term of the result is equal to one, then perform
156  //reduction
157  h[3] ^= r[reverseInt4(1)] & ~(c - 1);
158  }
159 
160  //Save M(i)
161  j = reverseInt4(i);
162  context->m[j][0] = h[0];
163  context->m[j][1] = h[1];
164  context->m[j][2] = h[2];
165  context->m[j][3] = h[3];
166  }
167 
168  //Successful initialization
169  return NO_ERROR;
170 }
171 
172 
173 /**
174  * @brief Authenticated encryption using GCM
175  * @param[in] context Pointer to the GCM context
176  * @param[in] iv Initialization vector
177  * @param[in] ivLen Length of the initialization vector
178  * @param[in] a Additional authenticated data
179  * @param[in] aLen Length of the additional data
180  * @param[in] p Plaintext to be encrypted
181  * @param[out] c Ciphertext resulting from the encryption
182  * @param[in] length Total number of data bytes to be encrypted
183  * @param[out] t Authentication tag
184  * @param[in] tLen Length of the authentication tag
185  * @return Error code
186  **/
187 
188 error_t gcmEncrypt(GcmContext *context, const uint8_t *iv,
189  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p,
190  uint8_t *c, size_t length, uint8_t *t, size_t tLen)
191 {
192  size_t k;
193  size_t n;
194  uint8_t b[16];
195  uint8_t j[16];
196  uint8_t s[16];
197 
198  //Make sure the GCM context is valid
199  if(context == NULL)
201 
202  //The length of the IV shall meet SP 800-38D requirements
203  if(ivLen < 1)
205 
206  //Check the length of the authentication tag
207  if(tLen < 4 || tLen > 16)
209 
210  //Check whether the length of the IV is 96 bits
211  if(ivLen == 12)
212  {
213  //When the length of the IV is 96 bits, the padding string is appended
214  //to the IV to form the pre-counter block
215  cryptoMemcpy(j, iv, 12);
216  STORE32BE(1, j + 12);
217  }
218  else
219  {
220  //Initialize GHASH calculation
221  cryptoMemset(j, 0, 16);
222 
223  //Length of the IV
224  n = ivLen;
225 
226  //Process the initialization vector
227  while(n > 0)
228  {
229  //The IV processed in a block-by-block fashion
230  k = MIN(n, 16);
231 
232  //Apply GHASH function
233  gcmXorBlock(j, j, iv, k);
234  gcmMul(context, j);
235 
236  //Next block
237  iv += k;
238  n -= k;
239  }
240 
241  //The string is appended with 64 additional 0 bits, followed by the
242  //64-bit representation of the length of the IV
243  cryptoMemset(b, 0, 8);
244  STORE64BE(ivLen * 8, b + 8);
245 
246  //The GHASH function is applied to the resulting string to form the
247  //pre-counter block
248  gcmXorBlock(j, j, b, 16);
249  gcmMul(context, j);
250  }
251 
252  //Compute MSB(CIPH(J(0)))
253  context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
254  cryptoMemcpy(t, b, tLen);
255 
256  //Initialize GHASH calculation
257  cryptoMemset(s, 0, 16);
258  //Length of the AAD
259  n = aLen;
260 
261  //Process AAD
262  while(n > 0)
263  {
264  //Additional data are processed in a block-by-block fashion
265  k = MIN(n, 16);
266 
267  //Apply GHASH function
268  gcmXorBlock(s, s, a, k);
269  gcmMul(context, s);
270 
271  //Next block
272  a += k;
273  n -= k;
274  }
275 
276  //Length of the plaintext
277  n = length;
278 
279  //Process plaintext
280  while(n > 0)
281  {
282  //The encryption operates in a block-by-block fashion
283  k = MIN(n, 16);
284 
285  //Increment counter
286  gcmIncCounter(j);
287 
288  //Encrypt plaintext
289  context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
290  gcmXorBlock(c, p, b, k);
291 
292  //Apply GHASH function
293  gcmXorBlock(s, s, c, k);
294  gcmMul(context, s);
295 
296  //Next block
297  p += k;
298  c += k;
299  n -= k;
300  }
301 
302  //Append the 64-bit representation of the length of the AAD and the
303  //ciphertext
304  STORE64BE(aLen * 8, b);
305  STORE64BE(length * 8, b + 8);
306 
307  //The GHASH function is applied to the result to produce a single output
308  //block S
309  gcmXorBlock(s, s, b, 16);
310  gcmMul(context, s);
311 
312  //Let T = MSB(GCTR(J(0), S)
313  gcmXorBlock(t, t, s, tLen);
314 
315  //Successful encryption
316  return NO_ERROR;
317 }
318 
319 
320 /**
321  * @brief Authenticated decryption using GCM
322  * @param[in] context Pointer to the GCM context
323  * @param[in] iv Initialization vector
324  * @param[in] ivLen Length of the initialization vector
325  * @param[in] a Additional authenticated data
326  * @param[in] aLen Length of the additional data
327  * @param[in] c Ciphertext to be decrypted
328  * @param[out] p Plaintext resulting from the decryption
329  * @param[in] length Total number of data bytes to be decrypted
330  * @param[in] t Authentication tag
331  * @param[in] tLen Length of the authentication tag
332  * @return Error code
333  **/
334 
335 error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
336  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
337  uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
338 {
339  uint8_t mask;
340  size_t k;
341  size_t n;
342  uint8_t b[16];
343  uint8_t j[16];
344  uint8_t r[16];
345  uint8_t s[16];
346 
347  ///Make sure the GCM context is valid
348  if(context == NULL)
350 
351  //The length of the IV shall meet SP 800-38D requirements
352  if(ivLen < 1)
354 
355  //Check the length of the authentication tag
356  if(tLen < 4 || tLen > 16)
358 
359  //Check whether the length of the IV is 96 bits
360  if(ivLen == 12)
361  {
362  //When the length of the IV is 96 bits, the padding string is appended
363  //to the IV to form the pre-counter block
364  cryptoMemcpy(j, iv, 12);
365  STORE32BE(1, j + 12);
366  }
367  else
368  {
369  //Initialize GHASH calculation
370  cryptoMemset(j, 0, 16);
371 
372  //Length of the IV
373  n = ivLen;
374 
375  //Process the initialization vector
376  while(n > 0)
377  {
378  //The IV processed in a block-by-block fashion
379  k = MIN(n, 16);
380 
381  //Apply GHASH function
382  gcmXorBlock(j, j, iv, k);
383  gcmMul(context, j);
384 
385  //Next block
386  iv += k;
387  n -= k;
388  }
389 
390  //The string is appended with 64 additional 0 bits, followed by the
391  //64-bit representation of the length of the IV
392  cryptoMemset(b, 0, 8);
393  STORE64BE(ivLen * 8, b + 8);
394 
395  //The GHASH function is applied to the resulting string to form the
396  //pre-counter block
397  gcmXorBlock(j, j, b, 16);
398  gcmMul(context, j);
399  }
400 
401  //Compute MSB(CIPH(J(0)))
402  context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
403  cryptoMemcpy(r, b, tLen);
404 
405  //Initialize GHASH calculation
406  cryptoMemset(s, 0, 16);
407  //Length of the AAD
408  n = aLen;
409 
410  //Process AAD
411  while(n > 0)
412  {
413  //Additional data are processed in a block-by-block fashion
414  k = MIN(n, 16);
415 
416  //Apply GHASH function
417  gcmXorBlock(s, s, a, k);
418  gcmMul(context, s);
419 
420  //Next block
421  a += k;
422  n -= k;
423  }
424 
425  //Length of the ciphertext
426  n = length;
427 
428  //Process ciphertext
429  while(n > 0)
430  {
431  //The decryption operates in a block-by-block fashion
432  k = MIN(n, 16);
433 
434  //Apply GHASH function
435  gcmXorBlock(s, s, c, k);
436  gcmMul(context, s);
437 
438  //Increment counter
439  gcmIncCounter(j);
440 
441  //Decrypt ciphertext
442  context->cipherAlgo->encryptBlock(context->cipherContext, j, b);
443  gcmXorBlock(p, c, b, k);
444 
445  //Next block
446  c += k;
447  p += k;
448  n -= k;
449  }
450 
451  //Append the 64-bit representation of the length of the AAD and the
452  //ciphertext
453  STORE64BE(aLen * 8, b);
454  STORE64BE(length * 8, b + 8);
455 
456  //The GHASH function is applied to the result to produce a single output
457  //block S
458  gcmXorBlock(s, s, b, 16);
459  gcmMul(context, s);
460 
461  //Let R = MSB(GCTR(J(0), S))
462  gcmXorBlock(r, r, s, tLen);
463 
464  //The calculated tag is bitwise compared to the received tag. The message
465  //is authenticated if and only if the tags match
466  for(mask = 0, n = 0; n < tLen; n++)
467  {
468  mask |= r[n] ^ t[n];
469  }
470 
471  //Return status code
472  return (mask == 0) ? NO_ERROR : ERROR_FAILURE;
473 }
474 
475 
476 /**
477  * @brief Multiplication operation in GF(2^128)
478  * @param[in] context Pointer to the GCM context
479  * @param[in, out] x 16-byte block to be multiplied by H
480  **/
481 
482 void gcmMul(GcmContext *context, uint8_t *x)
483 {
484  int_t i;
485  uint8_t b;
486  uint8_t c;
487  uint32_t z[4];
488 
489  //Let Z = 0
490  z[0] = 0;
491  z[1] = 0;
492  z[2] = 0;
493  z[3] = 0;
494 
495  //Fast table-driven implementation
496  for(i = 15; i >= 0; i--)
497  {
498  //Get the lower nibble
499  b = x[i] & 0x0F;
500 
501  //Multiply 4 bits at a time
502  c = z[0] & 0x0F;
503  z[0] = (z[0] >> 4) | (z[1] << 28);
504  z[1] = (z[1] >> 4) | (z[2] << 28);
505  z[2] = (z[2] >> 4) | (z[3] << 28);
506  z[3] >>= 4;
507 
508  z[0] ^= context->m[b][0];
509  z[1] ^= context->m[b][1];
510  z[2] ^= context->m[b][2];
511  z[3] ^= context->m[b][3];
512 
513  //Perform reduction
514  z[3] ^= r[c];
515 
516  //Get the upper nibble
517  b = (x[i] >> 4) & 0x0F;
518 
519  //Multiply 4 bits at a time
520  c = z[0] & 0x0F;
521  z[0] = (z[0] >> 4) | (z[1] << 28);
522  z[1] = (z[1] >> 4) | (z[2] << 28);
523  z[2] = (z[2] >> 4) | (z[3] << 28);
524  z[3] >>= 4;
525 
526  z[0] ^= context->m[b][0];
527  z[1] ^= context->m[b][1];
528  z[2] ^= context->m[b][2];
529  z[3] ^= context->m[b][3];
530 
531  //Perform reduction
532  z[3] ^= r[c];
533  }
534 
535  //Save the result
536  STORE32BE(z[3], x);
537  STORE32BE(z[2], x + 4);
538  STORE32BE(z[1], x + 8);
539  STORE32BE(z[0], x + 12);
540 }
541 
542 
543 /**
544  * @brief XOR operation
545  * @param[out] x Block resulting from the XOR operation
546  * @param[in] a First block
547  * @param[in] b Second block
548  * @param[in] n Size of the block
549  **/
550 
551 void gcmXorBlock(uint8_t *x, const uint8_t *a, const uint8_t *b, size_t n)
552 {
553  size_t i;
554 
555  //Perform XOR operation
556  for(i = 0; i < n; i++)
557  {
558  x[i] = a[i] ^ b[i];
559  }
560 }
561 
562 
563 /**
564  * @brief Increment counter block
565  * @param[in,out] x Pointer to the counter block
566  **/
567 
568 void gcmIncCounter(uint8_t *x)
569 {
570  size_t i;
571 
572  //The function increments the right-most 32 bits of the block. The remaining
573  //left-most 96 bits remain unchanged
574  for(i = 0; i < 4; i++)
575  {
576  //Increment the current byte and propagate the carry if necessary
577  if(++(x[15 - i]) != 0)
578  {
579  break;
580  }
581  }
582 }
583 
584 #endif
#define STORE64BE(a, p)
Definition: cpu_endian.h:304
uint8_t c
Definition: ndp.h:510
#define cryptoMemcpy(dest, src, length)
Definition: crypto.h:590
Debugging facilities.
uint8_t p
Definition: ndp.h:295
error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
Definition: gcm.c:76
Generic error code.
Definition: error.h:43
CipherAlgoEncryptBlock encryptBlock
Definition: crypto.h:1082
General definitions for cryptographic algorithms.
Invalid parameter.
Definition: error.h:45
Common interface for encryption algorithms.
Definition: crypto.h:1073
uint32_t m[16][4]
Precalculated table.
Definition: gcm.h:49
void gcmMul(GcmContext *context, uint8_t *x)
Multiplication operation in GF(2^128)
Definition: gcm.c:482
uint16_t z
Definition: dns_common.h:173
#define betoh32(value)
Definition: cpu_endian.h:428
uint8_t a
Definition: ndp.h:407
void gcmXorBlock(uint8_t *x, const uint8_t *a, const uint8_t *b, size_t n)
XOR operation.
Definition: gcm.c:551
error_t gcmEncrypt(GcmContext *context, const uint8_t *iv, size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c, size_t length, uint8_t *t, size_t tLen)
Authenticated encryption using GCM.
Definition: gcm.c:188
size_t blockSize
Definition: crypto.h:1078
uint8_t mask
Definition: web_socket.h:315
#define STORE32BE(a, p)
Definition: cpu_endian.h:268
GCM context.
Definition: gcm.h:45
signed int int_t
Definition: compiler_port.h:42
void gcmIncCounter(uint8_t *x)
Increment counter block.
Definition: gcm.c:568
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: gcm.h:47
#define MIN(a, b)
Definition: os_port.h:60
void * cipherContext
Cipher algorithm context.
Definition: gcm.h:48
uint8_t s
error_t gcmDecrypt(GcmContext *context, const uint8_t *iv, size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using GCM.
Definition: gcm.c:335
Success.
Definition: error.h:42
error_t
Error codes.
Definition: error.h:40
unsigned int uint_t
Definition: compiler_port.h:43
Galois/Counter Mode (GCM)
uint32_t r
Definition: ndp.h:342
uint8_t reverseInt4(uint8_t value)
Reverse bit order in a 4-bit word.
Definition: cpu_endian.c:73
CipherAlgoType type
Definition: crypto.h:1077
#define cryptoMemset(p, value, length)
Definition: crypto.h:584
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
uint8_t h
Definition: ndp.h:297
uint8_t b[6]
Definition: dtls_misc.h:130