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_hash (struct gcm_context *context, union gcm_block *hash)
 Construct hash.
static void gcm_process (struct cipher_algorithm *cipher, void *ctx, const void *src, void *dst, size_t len)
 Encrypt/decrypt/authenticate data.
int gcm_setkey (struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
 Set key.
int gcm_setiv (struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
 Set initialisation vector.
void gcm_encrypt (struct cipher_algorithm *cipher, void *ctx, const void *src, void *dst, size_t len)
 Encrypt data.
void gcm_decrypt (struct cipher_algorithm *cipher, void *ctx, const void *src, void *dst, size_t len)
 Decrypt data.
void gcm_auth (struct cipher_algorithm *cipher, void *ctx, void *auth)
 Generate authentication tag.

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_auth(), and gcm_process().

◆ 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_auth(), gcm_hash(), and gcm_multiply_key().

◆ 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:33
#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
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:321
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
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_hash()

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

Construct hash.

Parameters
contextContext
hashHash to fill in

Definition at line 317 of file gcm.c.

317 {
318
319 /* Construct big-endian lengths block */
320 hash->len.add = cpu_to_be64 ( context->len.len.add );
321 hash->len.data = cpu_to_be64 ( context->len.len.data );
322 DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
323 DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
324
325 /* Update hash */
326 gcm_xor_block ( &context->hash, hash );
327 gcm_multiply_key ( &context->key, hash );
328 DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
329 DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
330}
pseudo_bit_t hash[0x00010]
Definition arbel.h:2
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
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
#define cpu_to_be64(value)
Definition byteswap.h:112
union gcm_block key
Hash key (H).
Definition gcm.h:55
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, 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_auth(), and gcm_setiv().

◆ gcm_process()

void gcm_process ( struct cipher_algorithm * cipher,
void * ctx,
const void * src,
void * dst,
size_t len )
static

Encrypt/decrypt/authenticate data.

Parameters
cipherCipher algorithm
ctxContext
srcInput data
dstOutput data, or NULL to process additional data
lenLength of data
flagsOperation flags

Definition at line 342 of file gcm.c.

343 {
344 struct cipher_algorithm *raw_cipher = cipher->priv;
345 gcm_context_t ( cipher->ctxsize ) *context = ctx;
346 unsigned int flags = context->gcm.flags;
347 union gcm_block tmp;
348 uint64_t *total;
349 size_t frag_len;
350 unsigned int block;
351
352 /* Calculate block number (for debugging) */
353 block = ( ( ( context->gcm.len.len.add + 8 * sizeof ( tmp ) - 1 ) /
354 ( 8 * sizeof ( tmp ) ) ) +
355 ( ( context->gcm.len.len.data + 8 * sizeof ( tmp ) - 1 ) /
356 ( 8 * sizeof ( tmp ) ) ) + 1 );
357
358 /* Update total length (in bits) */
359 total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
360 &context->gcm.len.len.data : &context->gcm.len.len.add );
361 *total += ( len * 8 );
362
363 /* Process data */
364 for ( ; len ; src += frag_len, len -= frag_len, block++ ) {
365
366 /* Calculate fragment length */
367 frag_len = len;
368 if ( frag_len > sizeof ( tmp ) )
369 frag_len = sizeof ( tmp );
370
371 /* Update hash with input data */
372 gcm_xor ( src, &context->gcm.hash, &context->gcm.hash,
373 frag_len );
374
375 /* Encrypt/decrypt block, if applicable */
376 if ( dst ) {
377
378 /* Increment counter */
379 gcm_count ( &context->gcm.ctr, 1 );
380
381 /* Encrypt counter */
382 DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
383 DBGC2_HDA ( context, 0, &context->gcm.ctr,
384 sizeof ( context->gcm.ctr ) );
385 cipher_encrypt ( raw_cipher, &context->raw,
386 &context->gcm.ctr, &tmp,
387 sizeof ( tmp ) );
388 DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
389 context, block );
390 DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
391
392 /* Encrypt/decrypt data */
393 gcm_xor ( src, &tmp, dst, frag_len );
394 dst += frag_len;
395
396 /* Update hash with encrypted data, if applicable */
397 gcm_xor ( &tmp, &context->gcm.hash, &context->gcm.hash,
398 ( frag_len & flags ) );
399 }
400
401 /* Update hash */
402 gcm_multiply_key ( &context->gcm.key, &context->gcm.hash );
403 DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
404 DBGC2_HDA ( context, 0, &context->gcm.hash,
405 sizeof ( context->gcm.hash ) );
406 }
407}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
unsigned long long uint64_t
Definition stdint.h:13
uint8_t flags
Flags.
Definition ena.h:7
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 gcm_context_t(ctxsize)
A GCM mode context.
Definition gcm.h:61
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition crypto.h:326
unsigned long tmp
Definition linux_pci.h:65
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
A cipher algorithm.
Definition crypto.h:58
void * priv
Algorithm private data.
Definition crypto.h:138
size_t ctxsize
Context size.
Definition crypto.h:62

References block, cipher_encrypt, ctx, cipher_algorithm::ctxsize, DBGC2, DBGC2_HDA, flags, gcm_context_t, gcm_count(), GCM_FL_IV, gcm_multiply_key(), gcm_xor(), len, cipher_algorithm::priv, src, and tmp.

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

◆ gcm_setkey()

int gcm_setkey ( struct cipher_algorithm * cipher,
void * ctx,
const void * key,
size_t keylen )

Set key.

Parameters
cipherCipher algorithm
ctxContext
keyKey
keylenKey length
Return values
rcReturn status code

Definition at line 418 of file gcm.c.

419 {
420 struct cipher_algorithm *raw_cipher = cipher->priv;
421 gcm_context_t ( cipher->ctxsize ) *context = ctx;
422 int rc;
423
424 /* Initialise GCM context */
425 memset ( &context->gcm, 0, sizeof ( context->gcm ) );
426
427 /* Set underlying block cipher key */
428 if ( ( rc = cipher_setkey ( raw_cipher, context->raw, key,
429 keylen ) ) != 0 )
430 return rc;
431
432 /* Construct GCM hash key */
433 cipher_encrypt ( raw_cipher, context->raw, &context->gcm.ctr,
434 &context->gcm.key, sizeof ( context->gcm.key ) );
435 DBGC2 ( context, "GCM %p H:\n", context );
436 DBGC2_HDA ( context, 0, &context->gcm.key,
437 sizeof ( context->gcm.key ) );
438
439 /* Reset counter */
440 context->gcm.ctr.ctr.value = cpu_to_be32 ( 1 );
441
442 /* Construct cached tables */
443 gcm_cache ( &context->gcm.key );
444
445 return 0;
446}
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:310
void * memset(void *dest, int character, size_t len) __nonnull

References cipher_encrypt, cipher_setkey(), cpu_to_be32, ctx, cipher_algorithm::ctxsize, DBGC2, DBGC2_HDA, gcm_cache(), gcm_context_t, key, memset(), cipher_algorithm::priv, and rc.

◆ gcm_setiv()

int gcm_setiv ( struct cipher_algorithm * cipher,
void * ctx,
const void * iv,
size_t ivlen )

Set initialisation vector.

Parameters
cipherCipher algorithm
ctxContext
ivInitialisation vector
ivlenInitialisation vector length
Return values
rcReturn status code

Definition at line 457 of file gcm.c.

458 {
459 gcm_context_t ( cipher->ctxsize ) *context = ctx;
460
461 /* Reset non-key state */
462 memset ( &context->gcm, 0, gcm_offset ( key ) );
465 build_assert ( gcm_offset ( key ) > gcm_offset ( ctr ) );
466
467 /* Reset counter */
468 context->gcm.ctr.ctr.value = cpu_to_be32 ( 1 );
469
470 /* Process initialisation vector */
471 if ( ivlen == sizeof ( context->gcm.ctr.ctr.iv ) ) {
472
473 /* Initialisation vector is exactly 96 bits, use it as-is */
474 memcpy ( context->gcm.ctr.ctr.iv, iv, ivlen );
475
476 } else {
477
478 /* Calculate hash over initialisation vector */
479 context->gcm.flags = GCM_FL_IV;
480 gcm_process ( cipher, ctx, iv, NULL, ivlen );
481 gcm_hash ( &context->gcm, &context->gcm.ctr );
482 assert ( context->gcm.len.len.add == 0 );
483
484 /* Reset non-key, non-counter state */
485 memset ( &context->gcm, 0, gcm_offset ( ctr ) );
486 build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) );
487 build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) );
488 build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) );
489 }
490
491 DBGC2 ( context, "GCM %p Y[0]:\n", context );
492 DBGC2_HDA ( context, 0, &context->gcm.ctr,
493 sizeof ( context->gcm.ctr ) );
494 return 0;
495}
#define build_assert(condition)
Assert a condition at build time (after dead code elimination).
Definition assert.h:88
static void gcm_hash(struct gcm_context *context, union gcm_block *hash)
Construct hash.
Definition gcm.c:317
#define gcm_offset(field)
Offset of a field within GCM context.
Definition gcm.c:114
static void gcm_process(struct cipher_algorithm *cipher, void *ctx, const void *src, void *dst, size_t len)
Encrypt/decrypt/authenticate data.
Definition gcm.c:342
u8 iv[16]
Initialization vector.
Definition wpa.h:33

References assert, build_assert, cpu_to_be32, ctx, cipher_algorithm::ctxsize, DBGC2, DBGC2_HDA, gcm_context_t, GCM_FL_IV, gcm_hash(), gcm_offset, gcm_process(), hash, iv, key, len, memcpy(), memset(), and NULL.

◆ gcm_encrypt()

void gcm_encrypt ( struct cipher_algorithm * cipher,
void * ctx,
const void * src,
void * dst,
size_t len )

Encrypt data.

Parameters
cipherCipher algorithm
ctxContext
srcData to encrypt
dstBuffer for encrypted data, or NULL for additional data
lenLength of data

Definition at line 506 of file gcm.c.

507 {
508 gcm_context_t ( cipher->ctxsize ) *context = ctx;
509
510 /* Process data */
511 context->gcm.flags = GCM_FL_ENCRYPT;
512 gcm_process ( cipher, ctx, src, dst, len );
513}
#define GCM_FL_ENCRYPT
Perform encryption.
Definition gcm.c:49

References ctx, cipher_algorithm::ctxsize, gcm_context_t, GCM_FL_ENCRYPT, gcm_process(), len, and src.

◆ gcm_decrypt()

void gcm_decrypt ( struct cipher_algorithm * cipher,
void * ctx,
const void * src,
void * dst,
size_t len )

Decrypt data.

Parameters
cipherCipher algorithm
ctxContext
srcData to decrypt
dstBuffer for decrypted data, or NULL for additional data
lenLength of data

Definition at line 524 of file gcm.c.

525 {
526 gcm_context_t ( cipher->ctxsize ) *context = ctx;
527
528 /* Process data */
529 context->gcm.flags = 0;
530 gcm_process ( cipher, ctx, src, dst, len );
531}

References ctx, cipher_algorithm::ctxsize, gcm_context_t, gcm_process(), len, and src.

◆ gcm_auth()

void gcm_auth ( struct cipher_algorithm * cipher,
void * ctx,
void * auth )

Generate authentication tag.

Parameters
cipherCipher algorithm
ctxContext
authAuthentication tag

Definition at line 540 of file gcm.c.

540 {
541 struct cipher_algorithm *raw_cipher = cipher->priv;
542 gcm_context_t ( cipher->ctxsize ) *context = ctx;
543 union gcm_block *tag = auth;
544 union gcm_block tmp;
546
547 /* Construct hash */
548 gcm_hash ( &context->gcm, tag );
549
550 /* Construct encrypted initial counter value */
551 memcpy ( &tmp, &context->gcm.ctr, sizeof ( tmp ) );
552 offset = ( ( -context->gcm.len.len.data ) / ( 8 * sizeof ( tmp ) ) );
553 gcm_count ( &tmp, offset );
554 cipher_encrypt ( raw_cipher, &context->raw, &tmp, &tmp,
555 sizeof ( tmp ) );
556 DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
557 DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
558
559 /* Construct tag */
560 gcm_xor_block ( &tmp, tag );
561 DBGC2 ( context, "GCM %p T:\n", context );
562 DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
563}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint64_t tag
Identity tag.
Definition edd.h:1

References cipher_encrypt, ctx, cipher_algorithm::ctxsize, DBGC2, DBGC2_HDA, gcm_context_t, gcm_count(), gcm_hash(), gcm_xor_block(), memcpy(), offset, cipher_algorithm::priv, tag, and tmp.

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