iPXE
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.
#define GCM_FL_IV   0x0100
 Calculate hash over an initialisation vector value.
#define GCM_POLY   0xe1
 GCM field polynomial.
#define gcm_offset(field)
 Offset of a field within GCM context.

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

Variables

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

Detailed Description

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.

Referenced by gcm_encrypt().

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

Referenced by gcm_process(), and gcm_setiv().

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

Referenced by gcm_cache(), and gcm_multiply_x().

◆ gcm_offset

#define gcm_offset ( field)
Value:
offsetof ( struct gcm_context, field )
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
GCM context.
Definition gcm.h:47

Offset of a field within GCM context.

Definition at line 114 of file gcm.c.

Referenced by gcm_setiv().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ gcm_reverse()

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

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}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned int uint32_t
Definition stdint.h:12
#define be32_to_cpu(value)
Definition byteswap.h:117
#define cpu_to_be32(value)
Definition byteswap.h:111
uint32_t value
Counter value.
Definition gcm.h:21
struct gcm_counter ctr
Counter.
Definition gcm.h:41

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

Referenced by gcm_process(), and gcm_tag().

◆ gcm_xor()

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:226

References len.

Referenced by gcm_cache(), and gcm_process().

◆ gcm_xor_block()

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

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;
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
#define GCM_POLY
GCM field polynomial.
Definition gcm.c:80
unsigned char byte
Definition smc9000.h:38
uint8_t byte[16]
Raw bytes.
Definition gcm.h:35

References gcm_block::byte, carry, and GCM_POLY.

Referenced by gcm_cache().

◆ gcm_cache()

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}
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
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
static const union gcm_block * gcm_cached_key
Hash key for which multiplication tables are cached.
Definition gcm.c:93
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 uint16_t gcm_cached_reduce[256]
Cached reduction table (R) for Shoup's method.
Definition gcm.c:111
static void gcm_multiply_x(const union gcm_block *mult, union gcm_block *res)
Multiply polynomial by (x)
Definition gcm.c:190
#define cpu_to_be16(value)
Definition byteswap.h:110
#define be16_to_cpu(value)
Definition byteswap.h:116
A GCM block.
Definition gcm.h:33

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

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 */
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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint16_t word[8]
Raw words.
Definition gcm.h:37

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

Referenced by gcm_multiply_key().

◆ gcm_multiply_key()

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}
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition gcm.c:174
static void gcm_cache(const union gcm_block *key)
Construct cached tables.
Definition gcm.c:214
static void gcm_multiply_x_8(union gcm_block *poly)
Multiply polynomial by (x^8) in situ.
Definition gcm.c:264
void * memcpy(void *dest, const void *src, size_t len) __nonnull

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

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}
unsigned long long uint64_t
Definition stdint.h:13
uint8_t flags
Flags.
Definition ena.h:7
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 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
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HDA(...)
Definition compiler.h:523
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition crypto.h:251
unsigned long tmp
Definition linux_pci.h:65
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
union gcm_block key
Hash key (H)
Definition gcm.h:55
struct cipher_algorithm * raw_cipher
Underlying block cipher.
Definition gcm.h:57
uint8_t raw_ctx[0]
Underlying block cipher context.
Definition gcm.h:59
union gcm_block ctr
Counter (Y)
Definition gcm.h:53
union gcm_block hash
Accumulated hash (X)
Definition gcm.h:49
union gcm_block len
Accumulated lengths.
Definition gcm.h:51
uint64_t data
Data length.
Definition gcm.h:29
uint64_t add
Additional data length.
Definition gcm.h:27
struct gcm_lengths len
Lengths.
Definition gcm.h:43

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

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:2
#define cpu_to_be64(value)
Definition byteswap.h:112

References gcm_lengths::add, cpu_to_be64, gcm_lengths::data, DBGC2, DBGC2_HDA, gcm_multiply_key(), gcm_xor_block(), gcm_context::hash, 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}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint64_t tag
Identity tag.
Definition edd.h:1
static void gcm_hash(struct gcm_context *context, union gcm_block *hash)
Construct hash.
Definition gcm.c:388

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:3
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_block::ctr, gcm_context::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 475 of file gcm.c.

475 {
476
477 /* Reset non-key state */
478 memset ( context, 0, gcm_offset ( key ) );
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}
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition assert.h:77
#define gcm_offset(field)
Offset of a field within GCM context.
Definition gcm.c:114
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
uint8_t iv[12]
Initialisation vector.
Definition gcm.h:19
u8 iv[16]
Initialization vector.
Definition wpa.h:33

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

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}

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