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

◆ gcm_offset

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

Offset of a field within GCM context.

Definition at line 113 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 121 of file gcm.c.

122  {
123  uint8_t etyb = etyb;
124  uint8_t mask;
125 
126  for ( mask = 1 ; mask ; mask <<= 1 ) {
127  etyb <<= 1;
128  if ( byte & mask )
129  etyb |= 1;
130  }
131  return etyb;
132 }
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 156 of file gcm.c.

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

References dst, and 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 173 of file gcm.c.

174  {
175 
176  /* XOR whole dwords */
177  dst->dword[0] ^= src->dword[0];
178  dst->dword[1] ^= src->dword[1];
179  dst->dword[2] ^= src->dword[2];
180  dst->dword[3] ^= src->dword[3];
181 }
static void const void void * dst
Definition: crypto.h:244
static void const void * src
Definition: crypto.h:244

References dst, 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 189 of file gcm.c.

190  {
191  unsigned int i;
192  uint8_t byte;
193  uint8_t carry;
194 
195  /* Multiply by (x) by shifting all bits rightward */
196  for ( i = 0, carry = 0 ; i < sizeof ( res->byte ) ; i++ ) {
197  byte = mult->byte[i];
198  res->byte[i] = ( ( carry << 7 ) | ( byte >> 1 ) );
199  carry = ( byte & 0x01 );
200  }
201 
202  /* If result overflows, reduce modulo the field polynomial */
203  if ( carry )
204  res->byte[0] ^= GCM_POLY;
205 }
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 213 of file gcm.c.

213  {
214  union gcm_block *mult;
215  uint16_t reduce;
216  unsigned int this;
217  unsigned int other;
218  unsigned int i;
219 
220  /* Calculate M0[1..255] and R[1..255]
221  *
222  * The R[] values are independent of the key, but the overhead
223  * of recalculating them here is negligible and saves on
224  * overall code size since the calculations are related.
225  */
226  for ( i = 1 ; i < 256 ; i++ ) {
227 
228  /* Reverse bit order to compensate for poor life choices */
229  this = gcm_reverse ( i );
230 
231  /* Construct entries */
232  mult = &gcm_cached_mult[this];
233  if ( this & 0x80 ) {
234 
235  /* Odd number: entry[i] = entry[i - 1] + poly */
236  other = ( this & 0x7f ); /* bit-reversed (i - 1) */
237  gcm_xor ( key, &gcm_cached_mult[other], mult,
238  sizeof ( *mult ) );
239  reduce = gcm_cached_reduce[other];
240  reduce ^= be16_to_cpu ( GCM_POLY << 8 );
241  gcm_cached_reduce[this] = reduce;
242 
243  } else {
244 
245  /* Even number: entry[i] = entry[i/2] * (x) */
246  other = ( this << 1 ); /* bit-reversed (i / 2) */
247  gcm_multiply_x ( &gcm_cached_mult[other], mult );
248  reduce = be16_to_cpu ( gcm_cached_reduce[other] );
249  reduce >>= 1;
250  gcm_cached_reduce[this] = cpu_to_be16 ( reduce );
251  }
252  }
253 
254  /* Record cached key */
256 }
#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:156
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:189
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: crypto.h:284

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

263  {
264  uint8_t *byte;
265  uint8_t msb;
266 
267  /* Reduction table must already have been calculated */
268  assert ( gcm_cached_key != NULL );
269 
270  /* Record most significant byte */
271  byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
272  msb = *byte;
273 
274  /* Multiply least significant bytes by shifting */
275  for ( ; byte > &poly->byte[0] ; byte-- )
276  *byte = *( byte - 1 );
277  *byte = 0;
278 
279  /* Multiply most significant byte via reduction table */
280  poly->word[0] ^= gcm_cached_reduce[msb];
281 }
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 289 of file gcm.c.

290  {
291  union gcm_block res;
292  uint8_t *byte;
293 
294  /* Construct tables, if necessary */
295  if ( gcm_cached_key != key )
296  gcm_cache ( key );
297 
298  /* Multiply using Shoup's algorithm */
299  byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
300  memcpy ( &res, &gcm_cached_mult[ *byte ], sizeof ( res ) );
301  for ( byte-- ; byte >= &poly->byte[0] ; byte-- ) {
302  gcm_multiply_x_8 ( &res );
303  gcm_xor_block ( &gcm_cached_mult[ *byte ], &res );
304  }
305 
306  /* Overwrite result */
307  memcpy ( poly, &res, sizeof ( *poly ) );
308 }
A GCM block.
Definition: gcm.h:32
static void gcm_cache(const union gcm_block *key)
Construct cached tables.
Definition: gcm.c:213
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:173
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:263
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: crypto.h:284

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

320  {
321  union gcm_block tmp;
322  uint64_t *total;
323  size_t frag_len;
324  unsigned int block;
325 
326  /* Calculate block number (for debugging) */
327  block = ( ( ( context->len.len.add + 8 * sizeof ( tmp ) - 1 ) /
328  ( 8 * sizeof ( tmp ) ) ) +
329  ( ( context->len.len.data + 8 * sizeof ( tmp ) - 1 ) /
330  ( 8 * sizeof ( tmp ) ) ) + 1 );
331 
332  /* Update total length (in bits) */
333  total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
334  &context->len.len.data : &context->len.len.add );
335  *total += ( len * 8 );
336 
337  /* Process data */
338  for ( ; len ; src += frag_len, len -= frag_len, block++ ) {
339 
340  /* Calculate fragment length */
341  frag_len = len;
342  if ( frag_len > sizeof ( tmp ) )
343  frag_len = sizeof ( tmp );
344 
345  /* Update hash with input data */
346  gcm_xor ( src, &context->hash, &context->hash, frag_len );
347 
348  /* Encrypt/decrypt block, if applicable */
349  if ( dst ) {
350 
351  /* Increment counter */
352  gcm_count ( &context->ctr, 1 );
353 
354  /* Encrypt counter */
355  DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
356  DBGC2_HDA ( context, 0, &context->ctr,
357  sizeof ( context->ctr ) );
358  cipher_encrypt ( context->raw_cipher, &context->raw_ctx,
359  &context->ctr, &tmp, sizeof ( tmp ) );
360  DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
361  context, block );
362  DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
363 
364  /* Encrypt/decrypt data */
365  gcm_xor ( src, &tmp, dst, frag_len );
366  dst += frag_len;
367 
368  /* Update hash with encrypted data, if applicable */
369  gcm_xor ( &tmp, &context->hash, &context->hash,
370  ( frag_len & flags ) );
371  }
372 
373  /* Update hash */
374  gcm_multiply_key ( &context->key, &context->hash );
375  DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
376  DBGC2_HDA ( context, 0, &context->hash,
377  sizeof ( context->hash ) );
378  }
379 }
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 const void void * dst
Definition: crypto.h:244
static void const void * src
Definition: crypto.h:244
#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:248
static void gcm_multiply_key(const union gcm_block *key, union gcm_block *poly)
Multiply polynomial by hash key in situ.
Definition: gcm.c:289
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
static void gcm_xor(const void *src1, const void *src2, void *dst, size_t len)
XOR partial data block.
Definition: gcm.c:156
union gcm_block ctr
Counter (Y)
Definition: gcm.h:52
uint32_t len
Length.
Definition: ena.h:14
#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: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, dst, 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 387 of file gcm.c.

387  {
388 
389  /* Construct big-endian lengths block */
390  hash->len.add = cpu_to_be64 ( context->len.len.add );
391  hash->len.data = cpu_to_be64 ( context->len.len.data );
392  DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
393  DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
394 
395  /* Update hash */
396  gcm_xor_block ( &context->hash, hash );
397  gcm_multiply_key ( &context->key, hash );
398  DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
399  DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
400 }
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:173
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:289
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 408 of file gcm.c.

408  {
409  union gcm_block tmp;
411 
412  /* Construct hash */
413  gcm_hash ( context, tag );
414 
415  /* Construct encrypted initial counter value */
416  memcpy ( &tmp, &context->ctr, sizeof ( tmp ) );
417  offset = ( ( -context->len.len.data ) / ( 8 * sizeof ( tmp ) ) );
418  gcm_count ( &tmp, offset );
419  cipher_encrypt ( context->raw_cipher, &context->raw_ctx, &tmp,
420  &tmp, sizeof ( tmp ) );
421  DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
422  DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
423 
424  /* Construct tag */
425  gcm_xor_block ( &tmp, tag );
426  DBGC2 ( context, "GCM %p T:\n", context );
427  DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
428 }
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:387
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition: gcm.c:173
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:248
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 439 of file gcm.c.

440  {
441  int rc;
442 
443  /* Initialise GCM context */
444  memset ( context, 0, sizeof ( *context ) );
445  context->raw_cipher = raw_cipher;
446 
447  /* Set underlying block cipher key */
448  if ( ( rc = cipher_setkey ( raw_cipher, context->raw_ctx, key,
449  keylen ) ) != 0 )
450  return rc;
451 
452  /* Construct GCM hash key */
453  cipher_encrypt ( raw_cipher, context->raw_ctx, &context->ctr,
454  &context->key, sizeof ( context->key ) );
455  DBGC2 ( context, "GCM %p H:\n", context );
456  DBGC2_HDA ( context, 0, &context->key, sizeof ( context->key ) );
457 
458  /* Reset counter */
459  context->ctr.ctr.value = cpu_to_be32 ( 1 );
460 
461  /* Construct cached tables */
462  gcm_cache ( &context->key );
463 
464  return 0;
465 }
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:213
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:248
static void const void size_t keylen
Definition: crypto.h:233
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: crypto.h:284
void * memset(void *dest, int character, size_t len) __nonnull

References cipher_encrypt, cpu_to_be32, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, gcm_cache(), gcm_context::key, key, keylen, 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 474 of file gcm.c.

474  {
475 
476  /* Reset non-key state */
477  memset ( context, 0, gcm_offset ( key ) );
478  build_assert ( gcm_offset ( key ) > gcm_offset ( hash ) );
479  build_assert ( gcm_offset ( key ) > gcm_offset ( len ) );
480  build_assert ( gcm_offset ( key ) > gcm_offset ( ctr ) );
481  build_assert ( gcm_offset ( key ) < gcm_offset ( raw_cipher ) );
482  build_assert ( gcm_offset ( key ) < gcm_offset ( raw_ctx ) );
483 
484  /* Reset counter */
485  context->ctr.ctr.value = cpu_to_be32 ( 1 );
486 
487  /* Process initialisation vector */
488  if ( ivlen == sizeof ( context->ctr.ctr.iv ) ) {
489 
490  /* Initialisation vector is exactly 96 bits, use it as-is */
491  memcpy ( context->ctr.ctr.iv, iv, ivlen );
492 
493  } else {
494 
495  /* Calculate hash over initialisation vector */
496  gcm_process ( context, iv, NULL, ivlen, GCM_FL_IV );
497  gcm_hash ( context, &context->ctr );
498  assert ( context->len.len.add == 0 );
499 
500  /* Reset non-key, non-counter state */
501  memset ( context, 0, gcm_offset ( ctr ) );
502  build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) );
503  build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) );
504  build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) );
505  build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_cipher ) );
506  build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_ctx ) );
507  }
508 
509  DBGC2 ( context, "GCM %p Y[0]:\n", context );
510  DBGC2_HDA ( context, 0, &context->ctr, sizeof ( context->ctr ) );
511 }
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:387
#define GCM_FL_IV
Calculate hash over an initialisation vector value.
Definition: gcm.c:57
uint32_t value
Counter value.
Definition: gcm.h:20
static void const void size_t ivlen
Definition: crypto.h:239
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition: assert.h:76
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:319
struct gcm_counter ctr
Counter.
Definition: gcm.h:40
#define DBGC2_HDA(...)
Definition: compiler.h:523
pseudo_bit_t hash[0x00010]
Hash algorithm.
Definition: arbel.h:13
#define gcm_offset(field)
Offset of a field within GCM context.
Definition: gcm.c:113
#define cpu_to_be32(value)
Definition: byteswap.h:110
union gcm_block ctr
Counter (Y)
Definition: gcm.h:52
uint32_t len
Length.
Definition: ena.h:14
static void const void * iv
Definition: crypto.h:238
#define DBGC2(...)
Definition: compiler.h:522
struct gcm_counter ctr
Counter.
Definition: gcm.h:18
uint64_t add
Additional data length.
Definition: gcm.h:26
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @382 key
Sense key.
Definition: crypto.h:284
void * memset(void *dest, int character, size_t len) __nonnull

References gcm_lengths::add, assert(), build_assert, cpu_to_be32, gcm_context::ctr, ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, GCM_FL_IV, gcm_hash(), gcm_offset, gcm_process(), hash, gcm_counter::iv, iv, ivlen, key, len, gcm_context::len, gcm_block::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 521 of file gcm.c.

522  {
523 
524  /* Process data */
525  gcm_process ( context, src, dst, len, GCM_FL_ENCRYPT );
526 }
#define GCM_FL_ENCRYPT
Perform encryption.
Definition: gcm.c:48
static void const void void * dst
Definition: crypto.h:244
static void const void * src
Definition: crypto.h:244
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:319
uint32_t len
Length.
Definition: ena.h:14

References dst, 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 536 of file gcm.c.

537  {
538 
539  /* Process data */
540  gcm_process ( context, src, dst, len, 0 );
541 }
static void const void void * dst
Definition: crypto.h:244
static void const void * src
Definition: crypto.h:244
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:319
uint32_t len
Length.
Definition: ena.h:14

References dst, 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().