iPXE
gcm.c File Reference

Galois/Counter Mode (GCM). More...

#include <stdint.h>
#include <string.h>
#include <errno.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 50 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 59 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 81 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 115 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 124 of file gcm.c.

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

143 {
144 uint32_t *value = &ctr->ctr.value;
145
146 /* Update counter modulo 2^32 */
147 *value = cpu_to_be32 ( be32_to_cpu ( *value ) + delta );
148}
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 158 of file gcm.c.

159 {
160 uint8_t *dst_bytes = dst;
161 const uint8_t *src1_bytes = src1;
162 const uint8_t *src2_bytes = src2;
163
164 /* XOR one byte at a time */
165 while ( len-- )
166 *(dst_bytes++) = ( *(src1_bytes++) ^ *(src2_bytes++) );
167}
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 175 of file gcm.c.

176 {
177
178 /* XOR whole dwords */
179 dst->dword[0] ^= src->dword[0];
180 dst->dword[1] ^= src->dword[1];
181 dst->dword[2] ^= src->dword[2];
182 dst->dword[3] ^= src->dword[3];
183}
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 191 of file gcm.c.

192 {
193 unsigned int i;
196
197 /* Multiply by (x) by shifting all bits rightward */
198 for ( i = 0, carry = 0 ; i < sizeof ( res->byte ) ; i++ ) {
199 byte = mult->byte[i];
200 res->byte[i] = ( ( carry << 7 ) | ( byte >> 1 ) );
201 carry = ( byte & 0x01 );
202 }
203
204 /* If result overflows, reduce modulo the field polynomial */
205 if ( carry )
206 res->byte[0] ^= GCM_POLY;
207}
int carry
Definition bigint.h:33
#define GCM_POLY
GCM field polynomial.
Definition gcm.c:81
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 215 of file gcm.c.

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

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

292 {
293 union gcm_block res;
294 uint8_t *byte;
295
296 /* Construct tables, if necessary */
297 if ( gcm_cached_key != key )
298 gcm_cache ( key );
299
300 /* Multiply using Shoup's algorithm */
301 byte = &poly->byte[ sizeof ( poly->byte ) - 1 ];
302 memcpy ( &res, &gcm_cached_mult[ *byte ], sizeof ( res ) );
303 for ( byte-- ; byte >= &poly->byte[0] ; byte-- ) {
304 gcm_multiply_x_8 ( &res );
305 gcm_xor_block ( &gcm_cached_mult[ *byte ], &res );
306 }
307
308 /* Overwrite result */
309 memcpy ( poly, &res, sizeof ( *poly ) );
310}
static void gcm_xor_block(const union gcm_block *src, union gcm_block *dst)
XOR whole data block in situ.
Definition gcm.c:175
static void gcm_cache(const union gcm_block *key)
Construct cached tables.
Definition gcm.c:215
static void gcm_multiply_x_8(union gcm_block *poly)
Multiply polynomial by (x^8) in situ.
Definition gcm.c:265
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 318 of file gcm.c.

318 {
319
320 /* Construct big-endian lengths block */
321 hash->len.add = cpu_to_be64 ( context->len.len.add );
322 hash->len.data = cpu_to_be64 ( context->len.len.data );
323 DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
324 DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
325
326 /* Update hash */
327 gcm_xor_block ( &context->hash, hash );
328 gcm_multiply_key ( &context->key, hash );
329 DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
330 DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
331}
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:291
#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 343 of file gcm.c.

344 {
345 struct cipher_algorithm *raw_cipher = cipher->priv;
346 gcm_context_t ( cipher->ctxsize ) *context = ctx;
347 unsigned int flags = context->gcm.flags;
348 union gcm_block tmp;
349 uint64_t *total;
350 size_t frag_len;
351 unsigned int block;
352
353 /* Calculate block number (for debugging) */
354 block = ( ( ( context->gcm.len.len.add + 8 * sizeof ( tmp ) - 1 ) /
355 ( 8 * sizeof ( tmp ) ) ) +
356 ( ( context->gcm.len.len.data + 8 * sizeof ( tmp ) - 1 ) /
357 ( 8 * sizeof ( tmp ) ) ) + 1 );
358
359 /* Update total length (in bits) */
360 total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
361 &context->gcm.len.len.data : &context->gcm.len.len.add );
362 *total += ( len * 8 );
363
364 /* Process data */
365 for ( ; len ; src += frag_len, len -= frag_len, block++ ) {
366
367 /* Calculate fragment length */
368 frag_len = len;
369 if ( frag_len > sizeof ( tmp ) )
370 frag_len = sizeof ( tmp );
371
372 /* Update hash with input data */
373 gcm_xor ( src, &context->gcm.hash, &context->gcm.hash,
374 frag_len );
375
376 /* Encrypt/decrypt block, if applicable */
377 if ( dst ) {
378
379 /* Increment counter */
380 gcm_count ( &context->gcm.ctr, 1 );
381
382 /* Encrypt counter */
383 DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
384 DBGC2_HDA ( context, 0, &context->gcm.ctr,
385 sizeof ( context->gcm.ctr ) );
386 cipher_encrypt ( raw_cipher, &context->raw,
387 &context->gcm.ctr, &tmp,
388 sizeof ( tmp ) );
389 DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
390 context, block );
391 DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
392
393 /* Encrypt/decrypt data */
394 gcm_xor ( src, &tmp, dst, frag_len );
395 dst += frag_len;
396
397 /* Update hash with encrypted data, if applicable */
398 gcm_xor ( &tmp, &context->gcm.hash, &context->gcm.hash,
399 ( frag_len & flags ) );
400 }
401
402 /* Update hash */
403 gcm_multiply_key ( &context->gcm.key, &context->gcm.hash );
404 DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
405 DBGC2_HDA ( context, 0, &context->gcm.hash,
406 sizeof ( context->gcm.hash ) );
407 }
408}
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:143
#define GCM_FL_IV
Calculate hash over an initialisation vector value.
Definition gcm.c:59
#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 419 of file gcm.c.

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

459 {
460 gcm_context_t ( cipher->ctxsize ) *context = ctx;
461
462 /* Reset non-key state */
463 memset ( &context->gcm, 0, gcm_offset ( key ) );
466 build_assert ( gcm_offset ( key ) > gcm_offset ( ctr ) );
467
468 /* Reset counter */
469 context->gcm.ctr.ctr.value = cpu_to_be32 ( 1 );
470
471 /* Process initialisation vector */
472 if ( ivlen == sizeof ( context->gcm.ctr.ctr.iv ) ) {
473
474 /* Initialisation vector is exactly 96 bits, use it as-is */
475 memcpy ( context->gcm.ctr.ctr.iv, iv, ivlen );
476
477 } else if ( ivlen ) {
478
479 /* Calculate hash over initialisation vector */
480 context->gcm.flags = GCM_FL_IV;
481 gcm_process ( cipher, ctx, iv, NULL, ivlen );
482 gcm_hash ( &context->gcm, &context->gcm.ctr );
483 assert ( context->gcm.len.len.add == 0 );
484
485 /* Reset non-key, non-counter state */
486 memset ( &context->gcm, 0, gcm_offset ( ctr ) );
487 build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) );
488 build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) );
489 build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) );
490
491 } else {
492
493 /* Zero-length IVs are not permitted */
494 return -ENOTSUP;
495 }
496
497 DBGC2 ( context, "GCM %p Y[0]:\n", context );
498 DBGC2_HDA ( context, 0, &context->gcm.ctr,
499 sizeof ( context->gcm.ctr ) );
500 return 0;
501}
#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:318
#define gcm_offset(field)
Offset of a field within GCM context.
Definition gcm.c:115
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:343
#define ENOTSUP
Operation not supported.
Definition errno.h:633
u8 iv[16]
Initialization vector.
Definition wpa.h:33

References assert, build_assert, cpu_to_be32, ctx, cipher_algorithm::ctxsize, DBGC2, DBGC2_HDA, ENOTSUP, 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 512 of file gcm.c.

513 {
514 gcm_context_t ( cipher->ctxsize ) *context = ctx;
515
516 /* Process data */
517 context->gcm.flags = GCM_FL_ENCRYPT;
518 gcm_process ( cipher, ctx, src, dst, len );
519}
#define GCM_FL_ENCRYPT
Perform encryption.
Definition gcm.c:50

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

531 {
532 gcm_context_t ( cipher->ctxsize ) *context = ctx;
533
534 /* Process data */
535 context->gcm.flags = 0;
536 gcm_process ( cipher, ctx, src, dst, len );
537}

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

546 {
547 struct cipher_algorithm *raw_cipher = cipher->priv;
548 gcm_context_t ( cipher->ctxsize ) *context = ctx;
549 union gcm_block *tag = auth;
550 union gcm_block tmp;
552
553 /* Construct hash */
554 gcm_hash ( &context->gcm, tag );
555
556 /* Construct encrypted initial counter value */
557 memcpy ( &tmp, &context->gcm.ctr, sizeof ( tmp ) );
558 offset = ( ( -context->gcm.len.len.data ) / ( 8 * sizeof ( tmp ) ) );
559 gcm_count ( &tmp, offset );
560 cipher_encrypt ( raw_cipher, &context->raw, &tmp, &tmp,
561 sizeof ( tmp ) );
562 DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
563 DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
564
565 /* Construct tag */
566 gcm_xor_block ( &tmp, tag );
567 DBGC2 ( context, "GCM %p T:\n", context );
568 DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
569}
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 94 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 102 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 112 of file gcm.c.

Referenced by gcm_cache(), and gcm_multiply_x_8().