iPXE
Macros | Functions | Variables
gcm.c File Reference

Galois/Counter Mode (GCM) More...

#include <stdint.h>
#include <string.h>
#include <byteswap.h>
#include <ipxe/crypto.h>
#include <ipxe/gcm.h>

Go to the source code of this file.

Macros

#define GCM_FL_ENCRYPT   0x00ff
 Perform encryption. More...
 
#define GCM_FL_IV   0x0100
 Calculate hash over an initialisation vector value. More...
 
#define GCM_POLY   0xe1
 GCM field polynomial. More...
 
#define gcm_offset(field)   offsetof ( struct gcm_context, field )
 Offset of a field within GCM context. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static uint8_t gcm_reverse (const uint8_t byte)
 Reverse bits in a byte. More...
 
static void gcm_count (union gcm_block *ctr, uint32_t delta)
 Update GCM counter. More...
 
static void gcm_xor (const void *src1, const void *src2, void *dst, size_t len)
 XOR partial data block. More...
 
static void gcm_xor_block (const union gcm_block *src, union gcm_block *dst)
 XOR whole data block in situ. More...
 
static void gcm_multiply_x (const union gcm_block *mult, union gcm_block *res)
 Multiply polynomial by (x) More...
 
static void gcm_cache (const union gcm_block *key)
 Construct cached tables. More...
 
static void gcm_multiply_x_8 (union gcm_block *poly)
 Multiply polynomial by (x^8) in situ. More...
 
static void gcm_multiply_key (const union gcm_block *key, union gcm_block *poly)
 Multiply polynomial by hash key in situ. More...
 
static void gcm_process (struct gcm_context *context, const void *src, void *dst, size_t len, unsigned int flags)
 Encrypt/decrypt/authenticate data. More...
 
static void gcm_hash (struct gcm_context *context, union gcm_block *hash)
 Construct hash. More...
 
void gcm_tag (struct gcm_context *context, union gcm_block *tag)
 Construct tag. More...
 
int gcm_setkey (struct gcm_context *context, const void *key, size_t keylen, struct cipher_algorithm *raw_cipher)
 Set key. More...
 
void gcm_setiv (struct gcm_context *context, const void *iv, size_t ivlen)
 Set initialisation vector. More...
 
void gcm_encrypt (struct gcm_context *context, const void *src, void *dst, size_t len)
 Encrypt data. More...
 
void gcm_decrypt (struct gcm_context *context, const void *src, void *dst, size_t len)
 Decrypt data. More...
 

Variables

static const union gcm_blockgcm_cached_key
 Hash key for which multiplication tables are cached. More...
 
static union gcm_block gcm_cached_mult [256]
 Cached multiplication table (M0) for Shoup's method. More...
 
static uint16_t gcm_cached_reduce [256]
 Cached reduction table (R) for Shoup's method. More...
 

Detailed Description

Galois/Counter Mode (GCM)

The GCM algorithm is specified in

https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf https://csrc.nist.rip/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf

Definition in file gcm.c.

Macro Definition Documentation

◆ GCM_FL_ENCRYPT

#define GCM_FL_ENCRYPT   0x00ff

Perform encryption.

This value is chosen to allow for ANDing with a fragment length.

Definition at line 49 of file gcm.c.

◆ GCM_FL_IV

#define GCM_FL_IV   0x0100

Calculate hash over an initialisation vector value.

The hash calculation for a non 96-bit initialisation vector is identical to the calculation used for additional data, except that the non-additional data length counter is used.

Definition at line 58 of file gcm.c.

◆ GCM_POLY

#define GCM_POLY   0xe1

GCM field polynomial.

GCM treats 128-bit blocks as polynomials in GF(2^128) with the field polynomial f(x) = 1 + x + x^2 + x^7 + x^128.

In a somewhat bloody-minded interpretation of "big-endian", the constant term (with degree zero) is arbitrarily placed in the leftmost bit of the big-endian binary representation (i.e. the most significant bit of byte 0), thereby failing to correspond to the bit ordering in any CPU architecture in existence. This necessitates some wholly gratuitous byte reversals when constructing the multiplication tables, since all CPUs will treat bit 0 as being the least significant bit within a byte.

The field polynomial maps to the 128-bit constant 0xe1000000000000000000000000000000 (with the x^128 term outside the 128-bit range), and can therefore be treated as a single-byte value.

Definition at line 80 of file gcm.c.

◆ gcm_offset

#define gcm_offset (   field)    offsetof ( struct gcm_context, field )

Offset of a field within GCM context.

Definition at line 114 of file gcm.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ gcm_reverse()

static uint8_t gcm_reverse ( const uint8_t  byte)
inlinestatic

Reverse bits in a byte.

Parameters
byteByte
Return values
etybBit-reversed byte

Definition at line 123 of file gcm.c.

123  {
124  uint8_t etyb = etyb;
125  uint8_t mask;
126 
127  for ( mask = 1 ; mask ; mask <<= 1 ) {
128  etyb <<= 1;
129  if ( byte & mask )
130  etyb |= 1;
131  }
132  return etyb;
133 }
unsigned char uint8_t
Definition: stdint.h:10

Referenced by gcm_cache().

◆ gcm_count()

static void gcm_count ( union gcm_block ctr,
uint32_t  delta 
)
inlinestatic

Update GCM counter.

Parameters
ctrCounter
deltaAmount to add to counter

Definition at line 142 of file gcm.c.

142  {
143  uint32_t *value = &ctr->ctr.value;
144 
145  /* Update counter modulo 2^32 */
146  *value = cpu_to_be32 ( be32_to_cpu ( *value ) + delta );
147 }
uint32_t value
Counter value.
Definition: gcm.h:21
#define be32_to_cpu(value)
Definition: byteswap.h:117
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
struct gcm_counter ctr
Counter.
Definition: gcm.h:41
unsigned int uint32_t
Definition: stdint.h:12
#define cpu_to_be32(value)
Definition: byteswap.h:111

References be32_to_cpu, cpu_to_be32, gcm_block::ctr, value, and gcm_counter::value.

Referenced by gcm_process(), and gcm_tag().

◆ gcm_xor()

static void gcm_xor ( const void *  src1,
const void *  src2,
void *  dst,
size_t  len 
)
inlinestatic

XOR partial data block.

Parameters
src1Source buffer 1
src2Source buffer 2
dstDestination buffer
lenLength

Definition at line 157 of file gcm.c.

158  {
159  uint8_t *dst_bytes = dst;
160  const uint8_t *src1_bytes = src1;
161  const uint8_t *src2_bytes = src2;
162 
163  /* XOR one byte at a time */
164  while ( len-- )
165  *(dst_bytes++) = ( *(src1_bytes++) ^ *(src2_bytes++) );
166 }
ring len
Length.
Definition: dwmac.h:231
unsigned char uint8_t
Definition: stdint.h:10

References len.

Referenced by gcm_cache(), and gcm_process().

◆ gcm_xor_block()

static void gcm_xor_block ( const union gcm_block src,
union gcm_block dst 
)
inlinestatic

XOR whole data block in situ.

Parameters
srcSource block
dstDestination block

Definition at line 174 of file gcm.c.

175  {
176 
177  /* XOR whole dwords */
178  dst->dword[0] ^= src->dword[0];
179  dst->dword[1] ^= src->dword[1];
180  dst->dword[2] ^= src->dword[2];
181  dst->dword[3] ^= src->dword[3];
182 }
static const void * src
Definition: string.h:48
uint32_t dword[4]
Raw dwords.
Definition: gcm.h:39

References gcm_block::dword, and src.

Referenced by gcm_hash(), gcm_multiply_key(), and gcm_tag().

◆ gcm_multiply_x()

static void gcm_multiply_x ( const union gcm_block mult,
union gcm_block res 
)
static

Multiply polynomial by (x)

Parameters
multMultiplicand
resResult

Definition at line 190 of file gcm.c.

191  {
192  unsigned int i;
193  uint8_t byte;
194  uint8_t carry;
195 
196  /* Multiply by (x) by shifting all bits rightward */
197  for ( i = 0, carry = 0 ; i < sizeof ( res->byte ) ; i++ ) {
198  byte = mult->byte[i];
199  res->byte[i] = ( ( carry << 7 ) | ( byte >> 1 ) );
200  carry = ( byte & 0x01 );
201  }
202 
203  /* If result overflows, reduce modulo the field polynomial */
204  if ( carry )
205  res->byte[0] ^= GCM_POLY;
206 }
int carry
Definition: bigint.h:68
uint8_t byte[16]
Raw bytes.
Definition: gcm.h:35
unsigned char uint8_t
Definition: stdint.h:10
unsigned char byte
Definition: smc9000.h:38
#define GCM_POLY
GCM field polynomial.
Definition: gcm.c:80

References gcm_block::byte, carry, and GCM_POLY.

Referenced by gcm_cache().

◆ gcm_cache()

static void gcm_cache ( const union gcm_block key)
static

Construct cached tables.

Parameters
keyHash key
contextContext

Definition at line 214 of file gcm.c.

214  {
215  union gcm_block *mult;
216  uint16_t reduce;
217  unsigned int this;
218  unsigned int other;
219  unsigned int i;
220 
221  /* Calculate M0[1..255] and R[1..255]
222  *
223  * The R[] values are independent of the key, but the overhead
224  * of recalculating them here is negligible and saves on
225  * overall code size since the calculations are related.
226  */
227  for ( i = 1 ; i < 256 ; i++ ) {
228 
229  /* Reverse bit order to compensate for poor life choices */
230  this = gcm_reverse ( i );
231 
232  /* Construct entries */
233  mult = &gcm_cached_mult[this];
234  if ( this & 0x80 ) {
235 
236  /* Odd number: entry[i] = entry[i - 1] + poly */
237  other = ( this & 0x7f ); /* bit-reversed (i - 1) */
238  gcm_xor ( key, &gcm_cached_mult[other], mult,
239  sizeof ( *mult ) );
240  reduce = gcm_cached_reduce[other];
241  reduce ^= be16_to_cpu ( GCM_POLY << 8 );
242  gcm_cached_reduce[this] = reduce;
243 
244  } else {
245 
246  /* Even number: entry[i] = entry[i/2] * (x) */
247  other = ( this << 1 ); /* bit-reversed (i / 2) */
248  gcm_multiply_x ( &gcm_cached_mult[other], mult );
249  reduce = be16_to_cpu ( gcm_cached_reduce[other] );
250  reduce >>= 1;
251  gcm_cached_reduce[this] = cpu_to_be16 ( reduce );
252  }
253  }
254 
255  /* Record cached key */
257 }
#define cpu_to_be16(value)
Definition: byteswap.h:110
A GCM block.
Definition: gcm.h:33
unsigned short uint16_t
Definition: stdint.h:11
static union gcm_block gcm_cached_mult[256]
Cached multiplication table (M0) for Shoup's method.
Definition: gcm.c:101
#define be16_to_cpu(value)
Definition: byteswap.h:116
static uint8_t gcm_reverse(const uint8_t byte)
Reverse bits in a byte.
Definition: gcm.c:123
static void gcm_xor(const void *src1, const void *src2, void *dst, size_t len)
XOR partial data block.
Definition: gcm.c:157
static const union gcm_block * gcm_cached_key
Hash key for which multiplication tables are cached.
Definition: gcm.c:93
#define GCM_POLY
GCM field polynomial.
Definition: gcm.c:80
static void gcm_multiply_x(const union gcm_block *mult, union gcm_block *res)
Multiply polynomial by (x)
Definition: gcm.c:190
static uint16_t gcm_cached_reduce[256]
Cached reduction table (R) for Shoup's method.
Definition: gcm.c:111
union @391 key
Sense key.
Definition: scsi.h:18

References be16_to_cpu, cpu_to_be16, gcm_cached_key, gcm_cached_mult, gcm_cached_reduce, gcm_multiply_x(), GCM_POLY, gcm_reverse(), gcm_xor(), and key.

Referenced by gcm_multiply_key(), and gcm_setkey().

◆ gcm_multiply_x_8()

static void gcm_multiply_x_8 ( union gcm_block poly)
static

Multiply polynomial by (x^8) in situ.

Parameters
polyMultiplicand and result

Definition at line 264 of file gcm.c.

264  {
265  uint8_t *byte;
266  uint8_t msb;
267 
268  /* Reduction table must already have been calculated */
269  assert ( gcm_cached_key != NULL );
270 
271  /* Record most significant byte */
272  byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
273  msb = *byte;
274 
275  /* Multiply least significant bytes by shifting */
276  for ( ; byte > &poly->byte[0] ; byte-- )
277  *byte = *( byte - 1 );
278  *byte = 0;
279 
280  /* Multiply most significant byte via reduction table */
281  poly->word[0] ^= gcm_cached_reduce[msb];
282 }
uint8_t byte[16]
Raw bytes.
Definition: gcm.h:35
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint16_t word[8]
Raw words.
Definition: gcm.h:37
unsigned char uint8_t
Definition: stdint.h:10
unsigned char byte
Definition: smc9000.h:38
static const union gcm_block * gcm_cached_key
Hash key for which multiplication tables are cached.
Definition: gcm.c:93
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static uint16_t gcm_cached_reduce[256]
Cached reduction table (R) for Shoup's method.
Definition: gcm.c:111

References assert(), gcm_block::byte, gcm_cached_key, gcm_cached_reduce, NULL, and gcm_block::word.

Referenced by gcm_multiply_key().

◆ gcm_multiply_key()

static void gcm_multiply_key ( const union gcm_block key,
union gcm_block poly 
)
static

Multiply polynomial by hash key in situ.

Parameters
keyHash key
polyMultiplicand and result

Definition at line 290 of file gcm.c.

291  {
292  union gcm_block res;
293  uint8_t *byte;
294 
295  /* Construct tables, if necessary */
296  if ( gcm_cached_key != key )
297  gcm_cache ( key );
298 
299  /* Multiply using Shoup's algorithm */
300  byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
301  memcpy ( &res, &gcm_cached_mult[ *byte ], sizeof ( res ) );
302  for ( byte-- ; byte >= &poly->byte[0] ; byte-- ) {
303  gcm_multiply_x_8 ( &res );
304  gcm_xor_block ( &gcm_cached_mult[ *byte ], &res );
305  }
306 
307  /* Overwrite result */
308  memcpy ( poly, &res, sizeof ( *poly ) );
309 }
A GCM block.
Definition: gcm.h:33
static void gcm_cache(const union gcm_block *key)
Construct cached tables.
Definition: gcm.c:214
uint8_t byte[16]
Raw bytes.
Definition: gcm.h:35
static union gcm_block gcm_cached_mult[256]
Cached multiplication table (M0) for Shoup's method.
Definition: gcm.c:101
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition: gcm.c:174
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned char uint8_t
Definition: stdint.h:10
unsigned char byte
Definition: smc9000.h:38
static void gcm_multiply_x_8(union gcm_block *poly)
Multiply polynomial by (x^8) in situ.
Definition: gcm.c:264
static const union gcm_block * gcm_cached_key
Hash key for which multiplication tables are cached.
Definition: gcm.c:93
union @391 key
Sense key.
Definition: scsi.h:18

References gcm_block::byte, gcm_cache(), gcm_cached_key, gcm_cached_mult, gcm_multiply_x_8(), gcm_xor_block(), key, and memcpy().

Referenced by gcm_hash(), and gcm_process().

◆ gcm_process()

static void gcm_process ( struct gcm_context context,
const void *  src,
void *  dst,
size_t  len,
unsigned int  flags 
)
static

Encrypt/decrypt/authenticate data.

Parameters
contextContext
srcInput data
dstOutput data, or NULL to process additional data
lenLength of data
flagsOperation flags

Definition at line 320 of file gcm.c.

321  {
322  union gcm_block tmp;
323  uint64_t *total;
324  size_t frag_len;
325  unsigned int block;
326 
327  /* Calculate block number (for debugging) */
328  block = ( ( ( context->len.len.add + 8 * sizeof ( tmp ) - 1 ) /
329  ( 8 * sizeof ( tmp ) ) ) +
330  ( ( context->len.len.data + 8 * sizeof ( tmp ) - 1 ) /
331  ( 8 * sizeof ( tmp ) ) ) + 1 );
332 
333  /* Update total length (in bits) */
334  total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
335  &context->len.len.data : &context->len.len.add );
336  *total += ( len * 8 );
337 
338  /* Process data */
339  for ( ; len ; src += frag_len, len -= frag_len, block++ ) {
340 
341  /* Calculate fragment length */
342  frag_len = len;
343  if ( frag_len > sizeof ( tmp ) )
344  frag_len = sizeof ( tmp );
345 
346  /* Update hash with input data */
347  gcm_xor ( src, &context->hash, &context->hash, frag_len );
348 
349  /* Encrypt/decrypt block, if applicable */
350  if ( dst ) {
351 
352  /* Increment counter */
353  gcm_count ( &context->ctr, 1 );
354 
355  /* Encrypt counter */
356  DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
357  DBGC2_HDA ( context, 0, &context->ctr,
358  sizeof ( context->ctr ) );
359  cipher_encrypt ( context->raw_cipher, &context->raw_ctx,
360  &context->ctr, &tmp, sizeof ( tmp ) );
361  DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
362  context, block );
363  DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
364 
365  /* Encrypt/decrypt data */
366  gcm_xor ( src, &tmp, dst, frag_len );
367  dst += frag_len;
368 
369  /* Update hash with encrypted data, if applicable */
370  gcm_xor ( &tmp, &context->hash, &context->hash,
371  ( frag_len & flags ) );
372  }
373 
374  /* Update hash */
375  gcm_multiply_key ( &context->key, &context->hash );
376  DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
377  DBGC2_HDA ( context, 0, &context->hash,
378  sizeof ( context->hash ) );
379  }
380 }
A GCM block.
Definition: gcm.h:33
union gcm_block len
Accumulated lengths.
Definition: gcm.h:51
uint8_t raw_ctx[0]
Underlying block cipher context.
Definition: gcm.h:59
struct gcm_lengths len
Lengths.
Definition: gcm.h:43
static void gcm_count(union gcm_block *ctr, uint32_t delta)
Update GCM counter.
Definition: gcm.c:142
#define GCM_FL_IV
Calculate hash over an initialisation vector value.
Definition: gcm.c:58
unsigned long long uint64_t
Definition: stdint.h:13
union gcm_block hash
Accumulated hash (X)
Definition: gcm.h:49
struct cipher_algorithm * raw_cipher
Underlying block cipher.
Definition: gcm.h:57
unsigned long tmp
Definition: linux_pci.h:65
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:251
static void gcm_multiply_key(const union gcm_block *key, union gcm_block *poly)
Multiply polynomial by hash key in situ.
Definition: gcm.c:290
static const void * src
Definition: string.h:48
ring len
Length.
Definition: dwmac.h:231
union gcm_block key
Hash key (H)
Definition: gcm.h:55
uint64_t data
Data length.
Definition: gcm.h:29
#define DBGC2_HDA(...)
Definition: compiler.h:523
uint8_t flags
Flags.
Definition: ena.h:18
static void gcm_xor(const void *src1, const void *src2, void *dst, size_t len)
XOR partial data block.
Definition: gcm.c:157
union gcm_block ctr
Counter (Y)
Definition: gcm.h:53
#define DBGC2(...)
Definition: compiler.h:522
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
uint64_t add
Additional data length.
Definition: gcm.h:27

References gcm_lengths::add, block, cipher_encrypt, gcm_context::ctr, gcm_lengths::data, DBGC2, DBGC2_HDA, flags, gcm_count(), GCM_FL_IV, gcm_multiply_key(), gcm_xor(), gcm_context::hash, gcm_context::key, gcm_block::len, gcm_context::len, len, gcm_context::raw_cipher, gcm_context::raw_ctx, src, and tmp.

Referenced by gcm_decrypt(), gcm_encrypt(), and gcm_setiv().

◆ gcm_hash()

static void gcm_hash ( struct gcm_context context,
union gcm_block hash 
)
static

Construct hash.

Parameters
contextContext
hashHash to fill in

Definition at line 388 of file gcm.c.

388  {
389 
390  /* Construct big-endian lengths block */
391  hash->len.add = cpu_to_be64 ( context->len.len.add );
392  hash->len.data = cpu_to_be64 ( context->len.len.data );
393  DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
394  DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
395 
396  /* Update hash */
397  gcm_xor_block ( &context->hash, hash );
398  gcm_multiply_key ( &context->key, hash );
399  DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
400  DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
401 }
pseudo_bit_t hash[0x00010]
Definition: arbel.h:13
union gcm_block len
Accumulated lengths.
Definition: gcm.h:51
struct gcm_lengths len
Lengths.
Definition: gcm.h:43
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition: gcm.c:174
union gcm_block hash
Accumulated hash (X)
Definition: gcm.h:49
static void gcm_multiply_key(const union gcm_block *key, union gcm_block *poly)
Multiply polynomial by hash key in situ.
Definition: gcm.c:290
union gcm_block key
Hash key (H)
Definition: gcm.h:55
uint64_t data
Data length.
Definition: gcm.h:29
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define DBGC2(...)
Definition: compiler.h:522
#define cpu_to_be64(value)
Definition: byteswap.h:112
uint64_t add
Additional data length.
Definition: gcm.h:27

References gcm_lengths::add, cpu_to_be64, gcm_lengths::data, DBGC2, DBGC2_HDA, gcm_multiply_key(), gcm_xor_block(), hash, gcm_context::hash, gcm_context::key, gcm_block::len, and gcm_context::len.

Referenced by gcm_setiv(), and gcm_tag().

◆ gcm_tag()

void gcm_tag ( struct gcm_context context,
union gcm_block tag 
)

Construct tag.

Parameters
contextContext
tagTag

Definition at line 409 of file gcm.c.

409  {
410  union gcm_block tmp;
412 
413  /* Construct hash */
414  gcm_hash ( context, tag );
415 
416  /* Construct encrypted initial counter value */
417  memcpy ( &tmp, &context->ctr, sizeof ( tmp ) );
418  offset = ( ( -context->len.len.data ) / ( 8 * sizeof ( tmp ) ) );
419  gcm_count ( &tmp, offset );
420  cipher_encrypt ( context->raw_cipher, &context->raw_ctx, &tmp,
421  &tmp, sizeof ( tmp ) );
422  DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
423  DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
424 
425  /* Construct tag */
426  gcm_xor_block ( &tmp, tag );
427  DBGC2 ( context, "GCM %p T:\n", context );
428  DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
429 }
A GCM block.
Definition: gcm.h:33
union gcm_block len
Accumulated lengths.
Definition: gcm.h:51
uint8_t raw_ctx[0]
Underlying block cipher context.
Definition: gcm.h:59
struct gcm_lengths len
Lengths.
Definition: gcm.h:43
static void gcm_hash(struct gcm_context *context, union gcm_block *hash)
Construct hash.
Definition: gcm.c:388
static void gcm_count(union gcm_block *ctr, uint32_t delta)
Update GCM counter.
Definition: gcm.c:142
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition: gcm.c:174
struct cipher_algorithm * raw_cipher
Underlying block cipher.
Definition: gcm.h:57
unsigned long tmp
Definition: linux_pci.h:65
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:251
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint64_t data
Data length.
Definition: gcm.h:29
#define DBGC2_HDA(...)
Definition: compiler.h:523
unsigned int uint32_t
Definition: stdint.h:12
union gcm_block ctr
Counter (Y)
Definition: gcm.h:53
#define DBGC2(...)
Definition: compiler.h:522
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
uint64_t tag
Identity tag.
Definition: edd.h:31

References cipher_encrypt, gcm_context::ctr, gcm_lengths::data, DBGC2, DBGC2_HDA, gcm_count(), gcm_hash(), gcm_xor_block(), gcm_block::len, gcm_context::len, memcpy(), offset, gcm_context::raw_cipher, gcm_context::raw_ctx, tag, and tmp.

◆ gcm_setkey()

int gcm_setkey ( struct gcm_context context,
const void *  key,
size_t  keylen,
struct cipher_algorithm raw_cipher 
)

Set key.

Parameters
contextContext
keyKey
keylenKey length
raw_cipherUnderlying cipher
Return values
rcReturn status code

Definition at line 440 of file gcm.c.

441  {
442  int rc;
443 
444  /* Initialise GCM context */
445  memset ( context, 0, sizeof ( *context ) );
446  context->raw_cipher = raw_cipher;
447 
448  /* Set underlying block cipher key */
449  if ( ( rc = cipher_setkey ( raw_cipher, context->raw_ctx, key,
450  keylen ) ) != 0 )
451  return rc;
452 
453  /* Construct GCM hash key */
454  cipher_encrypt ( raw_cipher, context->raw_ctx, &context->ctr,
455  &context->key, sizeof ( context->key ) );
456  DBGC2 ( context, "GCM %p H:\n", context );
457  DBGC2_HDA ( context, 0, &context->key, sizeof ( context->key ) );
458 
459  /* Reset counter */
460  context->ctr.ctr.value = cpu_to_be32 ( 1 );
461 
462  /* Construct cached tables */
463  gcm_cache ( &context->key );
464 
465  return 0;
466 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t raw_ctx[0]
Underlying block cipher context.
Definition: gcm.h:59
static void gcm_cache(const union gcm_block *key)
Construct cached tables.
Definition: gcm.c:214
uint32_t value
Counter value.
Definition: gcm.h:21
struct cipher_algorithm * raw_cipher
Underlying block cipher.
Definition: gcm.h:57
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:251
union gcm_block key
Hash key (H)
Definition: gcm.h:55
struct gcm_counter ctr
Counter.
Definition: gcm.h:41
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define cpu_to_be32(value)
Definition: byteswap.h:111
union gcm_block ctr
Counter (Y)
Definition: gcm.h:53
#define DBGC2(...)
Definition: compiler.h:522
union @391 key
Sense key.
Definition: scsi.h:18
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:235
void * memset(void *dest, int character, size_t len) __nonnull

References cipher_encrypt, cipher_setkey(), cpu_to_be32, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, gcm_cache(), key, gcm_context::key, memset(), gcm_context::raw_cipher, gcm_context::raw_ctx, rc, and gcm_counter::value.

◆ gcm_setiv()

void gcm_setiv ( struct gcm_context context,
const void *  iv,
size_t  ivlen 
)

Set initialisation vector.

Parameters
ctxContext
ivInitialisation vector
ivlenInitialisation vector length

Definition at line 475 of file gcm.c.

475  {
476 
477  /* Reset non-key state */
478  memset ( context, 0, gcm_offset ( key ) );
479  build_assert ( gcm_offset ( key ) > gcm_offset ( hash ) );
480  build_assert ( gcm_offset ( key ) > gcm_offset ( len ) );
481  build_assert ( gcm_offset ( key ) > gcm_offset ( ctr ) );
482  build_assert ( gcm_offset ( key ) < gcm_offset ( raw_cipher ) );
483  build_assert ( gcm_offset ( key ) < gcm_offset ( raw_ctx ) );
484 
485  /* Reset counter */
486  context->ctr.ctr.value = cpu_to_be32 ( 1 );
487 
488  /* Process initialisation vector */
489  if ( ivlen == sizeof ( context->ctr.ctr.iv ) ) {
490 
491  /* Initialisation vector is exactly 96 bits, use it as-is */
492  memcpy ( context->ctr.ctr.iv, iv, ivlen );
493 
494  } else {
495 
496  /* Calculate hash over initialisation vector */
497  gcm_process ( context, iv, NULL, ivlen, GCM_FL_IV );
498  gcm_hash ( context, &context->ctr );
499  assert ( context->len.len.add == 0 );
500 
501  /* Reset non-key, non-counter state */
502  memset ( context, 0, gcm_offset ( ctr ) );
503  build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) );
504  build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) );
505  build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) );
506  build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_cipher ) );
507  build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_ctx ) );
508  }
509 
510  DBGC2 ( context, "GCM %p Y[0]:\n", context );
511  DBGC2_HDA ( context, 0, &context->ctr, sizeof ( context->ctr ) );
512 }
pseudo_bit_t hash[0x00010]
Definition: arbel.h:13
union gcm_block len
Accumulated lengths.
Definition: gcm.h:51
struct gcm_lengths len
Lengths.
Definition: gcm.h:43
uint8_t iv[12]
Initialisation vector.
Definition: gcm.h:19
static void gcm_hash(struct gcm_context *context, union gcm_block *hash)
Construct hash.
Definition: gcm.c:388
#define GCM_FL_IV
Calculate hash over an initialisation vector value.
Definition: gcm.c:58
uint32_t value
Counter value.
Definition: gcm.h:21
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition: assert.h:77
static void gcm_process(struct gcm_context *context, const void *src, void *dst, size_t len, unsigned int flags)
Encrypt/decrypt/authenticate data.
Definition: gcm.c:320
struct gcm_counter ctr
Counter.
Definition: gcm.h:41
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define gcm_offset(field)
Offset of a field within GCM context.
Definition: gcm.c:114
#define cpu_to_be32(value)
Definition: byteswap.h:111
union gcm_block ctr
Counter (Y)
Definition: gcm.h:53
#define DBGC2(...)
Definition: compiler.h:522
uint64_t add
Additional data length.
Definition: gcm.h:27
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
union @391 key
Sense key.
Definition: scsi.h:18
void * memset(void *dest, int character, size_t len) __nonnull

References gcm_lengths::add, assert(), build_assert, cpu_to_be32, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, GCM_FL_IV, gcm_hash(), gcm_offset, gcm_process(), hash, gcm_counter::iv, iv, key, gcm_context::len, gcm_block::len, len, memcpy(), memset(), NULL, and gcm_counter::value.

◆ gcm_encrypt()

void gcm_encrypt ( struct gcm_context context,
const void *  src,
void *  dst,
size_t  len 
)

Encrypt data.

Parameters
contextContext
srcData to encrypt
dstBuffer for encrypted data, or NULL for additional data
lenLength of data

Definition at line 522 of file gcm.c.

523  {
524 
525  /* Process data */
526  gcm_process ( context, src, dst, len, GCM_FL_ENCRYPT );
527 }
#define GCM_FL_ENCRYPT
Perform encryption.
Definition: gcm.c:49
static const void * src
Definition: string.h:48
ring len
Length.
Definition: dwmac.h:231
static void gcm_process(struct gcm_context *context, const void *src, void *dst, size_t len, unsigned int flags)
Encrypt/decrypt/authenticate data.
Definition: gcm.c:320

References GCM_FL_ENCRYPT, gcm_process(), len, and src.

◆ gcm_decrypt()

void gcm_decrypt ( struct gcm_context context,
const void *  src,
void *  dst,
size_t  len 
)

Decrypt data.

Parameters
contextContext
srcData to decrypt
dstBuffer for decrypted data, or NULL for additional data
lenLength of data

Definition at line 537 of file gcm.c.

538  {
539 
540  /* Process data */
541  gcm_process ( context, src, dst, len, 0 );
542 }
static const void * src
Definition: string.h:48
ring len
Length.
Definition: dwmac.h:231
static void gcm_process(struct gcm_context *context, const void *src, void *dst, size_t len, unsigned int flags)
Encrypt/decrypt/authenticate data.
Definition: gcm.c:320

References gcm_process(), len, and src.

Variable Documentation

◆ gcm_cached_key

const union gcm_block* gcm_cached_key
static

Hash key for which multiplication tables are cached.

GCM operates much more efficiently with a cached multiplication table, which costs 4kB per hash key. Since this exceeds the available stack space, we place a single 4kB cache in .bss and recalculate the cached values as required. In the common case of a single HTTPS connection being used to download a (relatively) large file, the same key will be used repeatedly for almost all GCM operations, and so the overhead of recalculation is negligible.

Definition at line 93 of file gcm.c.

Referenced by gcm_cache(), gcm_multiply_key(), and gcm_multiply_x_8().

◆ gcm_cached_mult

union gcm_block gcm_cached_mult[256]
static

Cached multiplication table (M0) for Shoup's method.

Each entry within this table represents the result of multiplying the cached hash key by an arbitrary 8-bit polynomial.

Definition at line 101 of file gcm.c.

Referenced by gcm_cache(), and gcm_multiply_key().

◆ gcm_cached_reduce

uint16_t gcm_cached_reduce[256]
static

Cached reduction table (R) for Shoup's method.

Each entry within this table represents the result of multiplying the fixed polynomial x^128 by an arbitrary 8-bit polynomial. Only the leftmost 16 bits are stored, since all other bits within the result will always be zero.

Definition at line 111 of file gcm.c.

Referenced by gcm_cache(), and gcm_multiply_x_8().