iPXE
|
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 uint8_t | gcm_reverse (const uint8_t byte) |
Reverse bits in a byte. More... | |
static void | gcm_count (union gcm_block *ctr, uint32_t delta) |
Update GCM counter. 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_block * | gcm_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... | |
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.
#define GCM_FL_ENCRYPT 0x00ff |
#define GCM_FL_IV 0x0100 |
#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.
#define gcm_offset | ( | field | ) | offsetof ( struct gcm_context, field ) |
FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
Reverse bits in a byte.
byte | Byte |
etyb | Bit-reversed byte |
Definition at line 122 of file gcm.c.
Referenced by gcm_cache().
Update GCM counter.
ctr | Counter |
delta | Amount to add to counter |
Definition at line 141 of file gcm.c.
References be32_to_cpu, cpu_to_be32, gcm_block::ctr, value, and gcm_counter::value.
Referenced by gcm_process(), and gcm_tag().
|
inlinestatic |
XOR partial data block.
src1 | Source buffer 1 |
src2 | Source buffer 2 |
dst | Destination buffer |
len | Length |
Definition at line 156 of file gcm.c.
References len.
Referenced by gcm_cache(), and gcm_process().
XOR whole data block in situ.
src | Source block |
dst | Destination block |
Definition at line 173 of file gcm.c.
References gcm_block::dword, and src.
Referenced by gcm_hash(), gcm_multiply_key(), and gcm_tag().
Multiply polynomial by (x)
mult | Multiplicand |
res | Result |
Definition at line 189 of file gcm.c.
References gcm_block::byte, carry, and GCM_POLY.
Referenced by gcm_cache().
|
static |
Construct cached tables.
key | Hash key |
context | Context |
Definition at line 213 of file gcm.c.
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().
|
static |
Multiply polynomial by (x^8) in situ.
poly | Multiplicand and result |
Definition at line 263 of file gcm.c.
References assert(), gcm_block::byte, gcm_cached_key, gcm_cached_reduce, NULL, and gcm_block::word.
Referenced by gcm_multiply_key().
Multiply polynomial by hash key in situ.
key | Hash key |
poly | Multiplicand and result |
Definition at line 289 of file gcm.c.
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().
|
static |
Encrypt/decrypt/authenticate data.
context | Context |
src | Input data |
dst | Output data, or NULL to process additional data |
len | Length of data |
flags | Operation flags |
Definition at line 319 of file gcm.c.
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, len, gcm_block::len, gcm_context::len, gcm_context::raw_cipher, gcm_context::raw_ctx, src, and tmp.
Referenced by gcm_decrypt(), gcm_encrypt(), and gcm_setiv().
|
static |
Construct hash.
context | Context |
hash | Hash to fill in |
Definition at line 387 of file gcm.c.
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_block::len, and gcm_context::len.
Referenced by gcm_setiv(), and gcm_tag().
void gcm_tag | ( | struct gcm_context * | context, |
union gcm_block * | tag | ||
) |
Construct tag.
context | Context |
tag | Tag |
Definition at line 408 of file gcm.c.
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.
int gcm_setkey | ( | struct gcm_context * | context, |
const void * | key, | ||
size_t | keylen, | ||
struct cipher_algorithm * | raw_cipher | ||
) |
Set key.
context | Context |
key | Key |
keylen | Key length |
raw_cipher | Underlying cipher |
rc | Return status code |
Definition at line 439 of file gcm.c.
References cipher_encrypt, cipher_setkey(), cpu_to_be32, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, gcm_cache(), key, gcm_context::key, memset(), gcm_context::raw_cipher, gcm_context::raw_ctx, rc, and gcm_counter::value.
void gcm_setiv | ( | struct gcm_context * | context, |
const void * | iv, | ||
size_t | ivlen | ||
) |
Set initialisation vector.
ctx | Context |
iv | Initialisation vector |
ivlen | Initialisation vector length |
Definition at line 474 of file gcm.c.
References gcm_lengths::add, assert(), build_assert, cpu_to_be32, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, GCM_FL_IV, gcm_hash(), gcm_offset, gcm_process(), hash, gcm_counter::iv, iv, key, len, gcm_context::len, gcm_block::len, memcpy(), memset(), NULL, and gcm_counter::value.
void gcm_encrypt | ( | struct gcm_context * | context, |
const void * | src, | ||
void * | dst, | ||
size_t | len | ||
) |
Encrypt data.
context | Context |
src | Data to encrypt |
dst | Buffer for encrypted data, or NULL for additional data |
len | Length of data |
Definition at line 521 of file gcm.c.
References GCM_FL_ENCRYPT, gcm_process(), len, and src.
void gcm_decrypt | ( | struct gcm_context * | context, |
const void * | src, | ||
void * | dst, | ||
size_t | len | ||
) |
Decrypt data.
context | Context |
src | Data to decrypt |
dst | Buffer for decrypted data, or NULL for additional data |
len | Length of data |
Definition at line 536 of file gcm.c.
References gcm_process(), len, and src.
|
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().
|
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().
|
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().