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... | |
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_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.
FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
|
inlinestatic |
|
inlinestatic |
XOR partial data block.
src1 | Source buffer 1 |
src2 | Source buffer 2 |
dst | Destination buffer |
len | Length |
Definition at line 153 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 170 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 186 of file gcm.c.
References gcm_block::byte, and GCM_POLY.
Referenced by gcm_cache().
|
static |
Construct cached tables.
key | Hash key |
context | Context |
Definition at line 210 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_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 260 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 286 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 316 of file gcm.c.
References gcm_lengths::add, block, cipher_encrypt, gcm_context::ctr, gcm_lengths::data, DBGC2, DBGC2_HDA, 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().
|
static |
Construct hash.
context | Context |
hash | Hash to fill in |
Definition at line 384 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_context::len, and gcm_block::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 405 of file gcm.c.
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.
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 436 of file gcm.c.
References cipher_encrypt, cipher_setkey(), cpu_to_be32, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, gcm_cache(), gcm_context::key, 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 471 of file gcm.c.
References gcm_lengths::add, assert(), cpu_to_be32, ctr, gcm_context::ctr, gcm_block::ctr, DBGC2, DBGC2_HDA, GCM_FL_IV, gcm_hash(), gcm_process(), gcm_context::hash, iv, gcm_counter::iv, gcm_context::key, key, gcm_context::len, gcm_block::len, linker_assert, memcpy(), memset(), NULL, offsetof, typeof(), 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 515 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 530 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().