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...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static __attribute__ ((always_inline))
 Reverse bits in a byte. 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 48 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 57 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 79 of file gcm.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __attribute__()

static __attribute__ ( (always_inline)  )
inlinestatic

Reverse bits in a byte.

Update GCM counter.

Parameters
byteByte
Return values
etybBit-reversed byte
Parameters
ctrCounter
deltaAmount to add to counter

Definition at line 118 of file gcm.c.

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

◆ 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 153 of file gcm.c.

154  {
155  uint8_t *dst_bytes = dst;
156  const uint8_t *src1_bytes = src1;
157  const uint8_t *src2_bytes = src2;
158 
159  /* XOR one byte at a time */
160  while ( len-- )
161  *(dst_bytes++) = ( *(src1_bytes++) ^ *(src2_bytes++) );
162 }
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14

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 170 of file gcm.c.

171  {
172 
173  /* XOR whole dwords */
174  dst->dword[0] ^= src->dword[0];
175  dst->dword[1] ^= src->dword[1];
176  dst->dword[2] ^= src->dword[2];
177  dst->dword[3] ^= src->dword[3];
178 }
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
uint32_t dword[4]
Raw dwords.
Definition: gcm.h:38

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 186 of file gcm.c.

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

References gcm_block::byte, 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 210 of file gcm.c.

210  {
211  union gcm_block *mult;
212  uint16_t reduce;
213  unsigned int this;
214  unsigned int other;
215  unsigned int i;
216 
217  /* Calculate M0[1..255] and R[1..255]
218  *
219  * The R[] values are independent of the key, but the overhead
220  * of recalculating them here is negligible and saves on
221  * overall code size since the calculations are related.
222  */
223  for ( i = 1 ; i < 256 ; i++ ) {
224 
225  /* Reverse bit order to compensate for poor life choices */
226  this = gcm_reverse ( i );
227 
228  /* Construct entries */
229  mult = &gcm_cached_mult[this];
230  if ( this & 0x80 ) {
231 
232  /* Odd number: entry[i] = entry[i - 1] + poly */
233  other = ( this & 0x7f ); /* bit-reversed (i - 1) */
234  gcm_xor ( key, &gcm_cached_mult[other], mult,
235  sizeof ( *mult ) );
236  reduce = gcm_cached_reduce[other];
237  reduce ^= be16_to_cpu ( GCM_POLY << 8 );
238  gcm_cached_reduce[this] = reduce;
239 
240  } else {
241 
242  /* Even number: entry[i] = entry[i/2] * (x) */
243  other = ( this << 1 ); /* bit-reversed (i / 2) */
244  gcm_multiply_x ( &gcm_cached_mult[other], mult );
245  reduce = be16_to_cpu ( gcm_cached_reduce[other] );
246  reduce >>= 1;
247  gcm_cached_reduce[this] = cpu_to_be16 ( reduce );
248  }
249  }
250 
251  /* Record cached key */
253 }
#define cpu_to_be16(value)
Definition: byteswap.h:109
A GCM block.
Definition: gcm.h:32
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:100
#define be16_to_cpu(value)
Definition: byteswap.h:115
static void gcm_xor(const void *src1, const void *src2, void *dst, size_t len)
XOR partial data block.
Definition: gcm.c:153
static const union gcm_block * gcm_cached_key
Hash key for which multiplication tables are cached.
Definition: gcm.c:92
#define GCM_POLY
GCM field polynomial.
Definition: gcm.c:79
static void gcm_multiply_x(const union gcm_block *mult, union gcm_block *res)
Multiply polynomial by (x)
Definition: gcm.c:186
static uint16_t gcm_cached_reduce[256]
Cached reduction table (R) for Shoup's method.
Definition: gcm.c:110
union @382 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_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 260 of file gcm.c.

260  {
261  uint8_t *byte;
262  uint8_t msb;
263 
264  /* Reduction table must already have been calculated */
265  assert ( gcm_cached_key != NULL );
266 
267  /* Record most significant byte */
268  byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
269  msb = *byte;
270 
271  /* Multiply least significant bytes by shifting */
272  for ( ; byte > &poly->byte[0] ; byte-- )
273  *byte = *( byte - 1 );
274  *byte = 0;
275 
276  /* Multiply most significant byte via reduction table */
277  poly->word[0] ^= gcm_cached_reduce[msb];
278 }
uint8_t byte[16]
Raw bytes.
Definition: gcm.h:34
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint16_t word[8]
Raw words.
Definition: gcm.h:36
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:92
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static uint16_t gcm_cached_reduce[256]
Cached reduction table (R) for Shoup's method.
Definition: gcm.c:110

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 286 of file gcm.c.

287  {
288  union gcm_block res;
289  uint8_t *byte;
290 
291  /* Construct tables, if necessary */
292  if ( gcm_cached_key != key )
293  gcm_cache ( key );
294 
295  /* Multiply using Shoup's algorithm */
296  byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
297  memcpy ( &res, &gcm_cached_mult[ *byte ], sizeof ( res ) );
298  for ( byte-- ; byte >= &poly->byte[0] ; byte-- ) {
299  gcm_multiply_x_8 ( &res );
300  gcm_xor_block ( &gcm_cached_mult[ *byte ], &res );
301  }
302 
303  /* Overwrite result */
304  memcpy ( poly, &res, sizeof ( *poly ) );
305 }
A GCM block.
Definition: gcm.h:32
static void gcm_cache(const union gcm_block *key)
Construct cached tables.
Definition: gcm.c:210
uint8_t byte[16]
Raw bytes.
Definition: gcm.h:34
static union gcm_block gcm_cached_mult[256]
Cached multiplication table (M0) for Shoup's method.
Definition: gcm.c:100
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition: gcm.c:170
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:260
static const union gcm_block * gcm_cached_key
Hash key for which multiplication tables are cached.
Definition: gcm.c:92
union @382 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 316 of file gcm.c.

317  {
318  union gcm_block tmp;
319  uint64_t *total;
320  size_t frag_len;
321  unsigned int block;
322 
323  /* Calculate block number (for debugging) */
324  block = ( ( ( context->len.len.add + 8 * sizeof ( tmp ) - 1 ) /
325  ( 8 * sizeof ( tmp ) ) ) +
326  ( ( context->len.len.data + 8 * sizeof ( tmp ) - 1 ) /
327  ( 8 * sizeof ( tmp ) ) ) + 1 );
328 
329  /* Update total length (in bits) */
330  total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
331  &context->len.len.data : &context->len.len.add );
332  *total += ( len * 8 );
333 
334  /* Process data */
335  for ( ; len ; src += frag_len, len -= frag_len, block++ ) {
336 
337  /* Calculate fragment length */
338  frag_len = len;
339  if ( frag_len > sizeof ( tmp ) )
340  frag_len = sizeof ( tmp );
341 
342  /* Update hash with input data */
343  gcm_xor ( src, &context->hash, &context->hash, frag_len );
344 
345  /* Encrypt/decrypt block, if applicable */
346  if ( dst ) {
347 
348  /* Increment counter */
349  gcm_count ( &context->ctr, 1 );
350 
351  /* Encrypt counter */
352  DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
353  DBGC2_HDA ( context, 0, &context->ctr,
354  sizeof ( context->ctr ) );
355  cipher_encrypt ( context->raw_cipher, &context->raw_ctx,
356  &context->ctr, &tmp, sizeof ( tmp ) );
357  DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
358  context, block );
359  DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
360 
361  /* Encrypt/decrypt data */
362  gcm_xor ( src, &tmp, dst, frag_len );
363  dst += frag_len;
364 
365  /* Update hash with encrypted data, if applicable */
366  gcm_xor ( &tmp, &context->hash, &context->hash,
367  ( frag_len & flags ) );
368  }
369 
370  /* Update hash */
371  gcm_multiply_key ( &context->key, &context->hash );
372  DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
373  DBGC2_HDA ( context, 0, &context->hash,
374  sizeof ( context->hash ) );
375  }
376 }
A GCM block.
Definition: gcm.h:32
union gcm_block len
Accumulated lengths.
Definition: gcm.h:50
uint8_t raw_ctx[0]
Underlying block cipher context.
Definition: gcm.h:58
struct gcm_lengths len
Lengths.
Definition: gcm.h:42
uint16_t block
Definition: tftp.h:12
#define GCM_FL_IV
Calculate hash over an initialisation vector value.
Definition: gcm.c:57
unsigned long long uint64_t
Definition: stdint.h:13
union gcm_block hash
Accumulated hash (X)
Definition: gcm.h:48
struct cipher_algorithm * raw_cipher
Underlying block cipher.
Definition: gcm.h:56
unsigned long tmp
Definition: linux_pci.h:53
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:228
static void gcm_multiply_key(const union gcm_block *key, union gcm_block *poly)
Multiply polynomial by hash key in situ.
Definition: gcm.c:286
union gcm_block key
Hash key (H)
Definition: gcm.h:54
uint64_t data
Data length.
Definition: gcm.h:28
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void gcm_xor(const void *src1, const void *src2, void *dst, size_t len)
XOR partial data block.
Definition: gcm.c:153
union gcm_block ctr
Counter (Y)
Definition: gcm.h:52
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
uint64_t add
Additional data length.
Definition: gcm.h:26
uint8_t flags
Flags.
Definition: ena.h:18

References gcm_lengths::add, block, cipher_encrypt, gcm_context::ctr, gcm_lengths::data, DBGC2, DBGC2_HDA, flags, GCM_FL_IV, gcm_multiply_key(), gcm_xor(), gcm_context::hash, gcm_context::key, len, gcm_context::len, gcm_block::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 384 of file gcm.c.

384  {
385 
386  /* Construct big-endian lengths block */
387  hash->len.add = cpu_to_be64 ( context->len.len.add );
388  hash->len.data = cpu_to_be64 ( context->len.len.data );
389  DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
390  DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
391 
392  /* Update hash */
393  gcm_xor_block ( &context->hash, hash );
394  gcm_multiply_key ( &context->key, hash );
395  DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
396  DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
397 }
union gcm_block len
Accumulated lengths.
Definition: gcm.h:50
struct gcm_lengths len
Lengths.
Definition: gcm.h:42
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition: gcm.c:170
union gcm_block hash
Accumulated hash (X)
Definition: gcm.h:48
static void gcm_multiply_key(const union gcm_block *key, union gcm_block *poly)
Multiply polynomial by hash key in situ.
Definition: gcm.c:286
union gcm_block key
Hash key (H)
Definition: gcm.h:54
uint64_t data
Data length.
Definition: gcm.h:28
#define DBGC2_HDA(...)
Definition: compiler.h:523
pseudo_bit_t hash[0x00010]
Hash algorithm.
Definition: arbel.h:13
#define DBGC2(...)
Definition: compiler.h:522
#define cpu_to_be64(value)
Definition: byteswap.h:111
uint64_t add
Additional data length.
Definition: gcm.h:26

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_context::len, and gcm_block::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 405 of file gcm.c.

405  {
406  union gcm_block tmp;
408 
409  /* Construct hash */
410  gcm_hash ( context, tag );
411 
412  /* Construct encrypted initial counter value */
413  memcpy ( &tmp, &context->ctr, sizeof ( tmp ) );
414  offset = ( ( -context->len.len.data ) / ( 8 * sizeof ( tmp ) ) );
415  gcm_count ( &tmp, offset );
416  cipher_encrypt ( context->raw_cipher, &context->raw_ctx, &tmp,
417  &tmp, sizeof ( tmp ) );
418  DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
419  DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
420 
421  /* Construct tag */
422  gcm_xor_block ( &tmp, tag );
423  DBGC2 ( context, "GCM %p T:\n", context );
424  DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
425 }
A GCM block.
Definition: gcm.h:32
union gcm_block len
Accumulated lengths.
Definition: gcm.h:50
uint8_t raw_ctx[0]
Underlying block cipher context.
Definition: gcm.h:58
struct gcm_lengths len
Lengths.
Definition: gcm.h:42
static void gcm_hash(struct gcm_context *context, union gcm_block *hash)
Construct hash.
Definition: gcm.c:384
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition: gcm.c:170
struct cipher_algorithm * raw_cipher
Underlying block cipher.
Definition: gcm.h:56
unsigned long tmp
Definition: linux_pci.h:53
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:228
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
uint64_t data
Data length.
Definition: gcm.h:28
#define DBGC2_HDA(...)
Definition: compiler.h:523
unsigned int uint32_t
Definition: stdint.h:12
union gcm_block ctr
Counter (Y)
Definition: gcm.h:52
#define DBGC2(...)
Definition: compiler.h:522
uint64_t tag
Identity tag.
Definition: edd.h:30

References cipher_encrypt, gcm_context::ctr, gcm_lengths::data, DBGC2, DBGC2_HDA, gcm_hash(), gcm_xor_block(), gcm_context::len, gcm_block::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 436 of file gcm.c.

437  {
438  int rc;
439 
440  /* Initialise GCM context */
441  memset ( context, 0, sizeof ( *context ) );
442  context->raw_cipher = raw_cipher;
443 
444  /* Set underlying block cipher key */
445  if ( ( rc = cipher_setkey ( raw_cipher, context->raw_ctx, key,
446  keylen ) ) != 0 )
447  return rc;
448 
449  /* Construct GCM hash key */
450  cipher_encrypt ( raw_cipher, context->raw_ctx, &context->ctr,
451  &context->key, sizeof ( context->key ) );
452  DBGC2 ( context, "GCM %p H:\n", context );
453  DBGC2_HDA ( context, 0, &context->key, sizeof ( context->key ) );
454 
455  /* Reset counter */
456  context->ctr.ctr.value = cpu_to_be32 ( 1 );
457 
458  /* Construct cached tables */
459  gcm_cache ( &context->key );
460 
461  return 0;
462 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t raw_ctx[0]
Underlying block cipher context.
Definition: gcm.h:58
static void gcm_cache(const union gcm_block *key)
Construct cached tables.
Definition: gcm.c:210
uint32_t value
Counter value.
Definition: gcm.h:20
struct cipher_algorithm * raw_cipher
Underlying block cipher.
Definition: gcm.h:56
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:228
union gcm_block key
Hash key (H)
Definition: gcm.h:54
struct gcm_counter ctr
Counter.
Definition: gcm.h:40
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define cpu_to_be32(value)
Definition: byteswap.h:110
union gcm_block ctr
Counter (Y)
Definition: gcm.h:52
#define DBGC2(...)
Definition: compiler.h:522
union @382 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:213
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(), gcm_context::key, 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 471 of file gcm.c.

471  {
472  union gcm_block *check = ( ( void * ) context );
473 
474  /* Sanity checks */
475  linker_assert ( &context->hash == check, gcm_bad_layout );
476  linker_assert ( &context->len == check + 1, gcm_bad_layout );
477  linker_assert ( &context->ctr == check + 2, gcm_bad_layout );
478  linker_assert ( &context->key == check + 3, gcm_bad_layout );
479 
480  /* Reset non-key state */
481  memset ( context, 0, offsetof ( typeof ( *context ), key ) );
482 
483  /* Reset counter */
484  context->ctr.ctr.value = cpu_to_be32 ( 1 );
485 
486  /* Process initialisation vector */
487  if ( ivlen == sizeof ( context->ctr.ctr.iv ) ) {
488 
489  /* Initialisation vector is exactly 96 bits, use it as-is */
490  memcpy ( context->ctr.ctr.iv, iv, ivlen );
491 
492  } else {
493 
494  /* Calculate hash over initialisation vector */
495  gcm_process ( context, iv, NULL, ivlen, GCM_FL_IV );
496  gcm_hash ( context, &context->ctr );
497  assert ( context->len.len.add == 0 );
498 
499  /* Reset non-key, non-counter state */
500  memset ( context, 0, offsetof ( typeof ( *context ), ctr ) );
501  }
502 
503  DBGC2 ( context, "GCM %p Y[0]:\n", context );
504  DBGC2_HDA ( context, 0, &context->ctr, sizeof ( context->ctr ) );
505 }
A GCM block.
Definition: gcm.h:32
union gcm_block len
Accumulated lengths.
Definition: gcm.h:50
struct gcm_lengths len
Lengths.
Definition: gcm.h:42
uint8_t iv[12]
Initialisation vector.
Definition: gcm.h:18
static void gcm_hash(struct gcm_context *context, union gcm_block *hash)
Construct hash.
Definition: gcm.c:384
#define GCM_FL_IV
Calculate hash over an initialisation vector value.
Definition: gcm.c:57
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
union gcm_block hash
Accumulated hash (X)
Definition: gcm.h:48
uint32_t value
Counter value.
Definition: gcm.h:20
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
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:316
union gcm_block key
Hash key (H)
Definition: gcm.h:54
struct gcm_counter ctr
Counter.
Definition: gcm.h:40
#define DBGC2_HDA(...)
Definition: compiler.h:523
#define cpu_to_be32(value)
Definition: byteswap.h:110
union gcm_block ctr
Counter (Y)
Definition: gcm.h:52
#define DBGC2(...)
Definition: compiler.h:522
uint8_t iv[12]
Initialisation vector.
Definition: gcm.h:12
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
struct gcm_counter ctr
Counter.
Definition: gcm.h:18
uint64_t add
Additional data length.
Definition: gcm.h:26
#define linker_assert(condition, error_symbol)
Assert a condition at link-time.
Definition: assert.h:68
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @382 key
Sense key.
Definition: scsi.h:18
void * memset(void *dest, int character, size_t len) __nonnull

References gcm_lengths::add, assert(), cpu_to_be32, ctr, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, GCM_FL_IV, gcm_hash(), gcm_process(), gcm_context::hash, iv, gcm_counter::iv, gcm_context::key, key, gcm_context::len, gcm_block::len, linker_assert, memcpy(), memset(), NULL, offsetof, typeof(), 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 515 of file gcm.c.

516  {
517 
518  /* Process data */
519  gcm_process ( context, src, dst, len, GCM_FL_ENCRYPT );
520 }
#define GCM_FL_ENCRYPT
Perform encryption.
Definition: gcm.c:48
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:316
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
uint32_t len
Length.
Definition: ena.h:14

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 530 of file gcm.c.

531  {
532 
533  /* Process data */
534  gcm_process ( context, src, dst, len, 0 );
535 }
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:316
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
uint32_t len
Length.
Definition: ena.h:14

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 92 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 100 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 110 of file gcm.c.

Referenced by gcm_cache(), and gcm_multiply_x_8().