iPXE
Data Structures | Enumerations | Functions | Variables
aes.c File Reference

AES algorithm. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/rotate.h>
#include <ipxe/crypto.h>
#include <ipxe/ecb.h>
#include <ipxe/cbc.h>
#include <ipxe/gcm.h>
#include <ipxe/aes.h>

Go to the source code of this file.

Data Structures

union  aes_table_entry
 A single AES lookup table entry. More...
 
struct  aes_table
 An AES lookup table. More...
 

Enumerations

enum  aes_stride { AES_STRIDE_SHIFTROWS = +5, AES_STRIDE_INVSHIFTROWS = -3 }
 AES strides. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static uint32_t aes_entry_column (const union aes_table_entry *entry, unsigned int column)
 Multiply [Inv]MixColumns matrix column by scalar multiplicand. More...
 
static uint32_t aes_column (const struct aes_table *table, size_t stride, const union aes_matrix *in, size_t offset)
 Multiply [Inv]MixColumns matrix column by S-boxed input byte. More...
 
static uint32_t aes_output (const struct aes_table *table, size_t stride, const union aes_matrix *in, const union aes_matrix *key, unsigned int column)
 Calculate intermediate round output column. More...
 
static void aes_round (const struct aes_table *table, size_t stride, const union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key)
 Perform a single intermediate round. More...
 
static void aes_encrypt_rounds (union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key, unsigned int rounds)
 Perform encryption intermediate rounds. More...
 
static void aes_decrypt_rounds (union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key, unsigned int rounds)
 Perform decryption intermediate rounds. More...
 
static void aes_addroundkey (union aes_matrix *state, const union aes_matrix *key)
 Perform standalone AddRoundKey. More...
 
static void aes_final (const struct aes_table *table, size_t stride, const union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key)
 Perform final round. More...
 
static void aes_encrypt (void *ctx, const void *src, void *dst, size_t len)
 Encrypt data. More...
 
static void aes_decrypt (void *ctx, const void *src, void *dst, size_t len)
 Decrypt data. More...
 
static unsigned int aes_double (unsigned int poly)
 Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8) More...
 
static void aes_mixcolumns_entry (union aes_table_entry *entry)
 Fill in MixColumns lookup table entry. More...
 
static void aes_invmixcolumns_entry (union aes_table_entry *entry)
 Fill in InvMixColumns lookup table entry. More...
 
static void aes_generate (void)
 Generate AES lookup tables. More...
 
static uint32_t aes_key_rotate (uint32_t column)
 Rotate key column. More...
 
static uint32_t aes_key_sbox (uint32_t column)
 Apply S-box to key column. More...
 
static uint32_t aes_key_rcon (uint32_t column, unsigned int rcon)
 Apply schedule round constant to key column. More...
 
static int aes_setkey (void *ctx, const void *key, size_t keylen)
 Set key. More...
 
 ECB_CIPHER (aes_ecb, aes_ecb_algorithm, aes_algorithm, struct aes_context, AES_BLOCKSIZE)
 
 CBC_CIPHER (aes_cbc, aes_cbc_algorithm, aes_algorithm, struct aes_context, AES_BLOCKSIZE)
 
 GCM_CIPHER (aes_gcm, aes_gcm_algorithm, aes_algorithm, struct aes_context, AES_BLOCKSIZE)
 

Variables

static struct aes_table aes_mixcolumns
 AES MixColumns lookup table. More...
 
static struct aes_table aes_invmixcolumns
 AES InvMixColumns lookup table. More...
 
struct cipher_algorithm aes_algorithm
 Basic AES algorithm. More...
 

Detailed Description

AES algorithm.

Definition in file aes.c.

Enumeration Type Documentation

◆ aes_stride

enum aes_stride

AES strides.

These are the strides (modulo 16) used to walk through the AES input state bytes in order of byte position after [Inv]ShiftRows.

Enumerator
AES_STRIDE_SHIFTROWS 

Input stride for ShiftRows.

      0 4 8 c
       \ \ \
      1 5 9 d
       \ \ \
      2 6 a e
       \ \ \
      3 7 b f
AES_STRIDE_INVSHIFTROWS 

Input stride for InvShiftRows.

      0 4 8 c
       / / /
      1 5 9 d
       / / /
      2 6 a e
       / / /
      3 7 b f

Definition at line 50 of file aes.c.

50  {
51  /** Input stride for ShiftRows
52  *
53  * 0 4 8 c
54  * \ \ \
55  * 1 5 9 d
56  * \ \ \
57  * 2 6 a e
58  * \ \ \
59  * 3 7 b f
60  */
62  /** Input stride for InvShiftRows
63  *
64  * 0 4 8 c
65  * / / /
66  * 1 5 9 d
67  * / / /
68  * 2 6 a e
69  * / / /
70  * 3 7 b f
71  */
73 };
Input stride for ShiftRows.
Definition: aes.c:61
Input stride for InvShiftRows.
Definition: aes.c:72

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ aes_entry_column()

static uint32_t aes_entry_column ( const union aes_table_entry entry,
unsigned int  column 
)
inlinestatic

Multiply [Inv]MixColumns matrix column by scalar multiplicand.

Parameters
entryAES lookup table entry for scalar multiplicand
column[Inv]MixColumns matrix column index
Return values
productProduct of matrix column with scalar multiplicand

Definition at line 160 of file aes.c.

160  {
161  const union {
162  uint8_t byte;
163  uint32_t column;
164  } __attribute__ (( may_alias )) *product;
165 
166  /* Locate relevant four-byte subset */
167  product = container_of ( &entry->byte[ 4 - column ],
168  typeof ( *product ), byte );
169 
170  /* Extract this four-byte subset */
171  return product->column;
172 }
#define __attribute__(x)
Definition: compiler.h:10
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:115
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
unsigned char byte
Definition: smc9000.h:38
uint8_t product
Product string.
Definition: smbios.h:17
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:48

References __attribute__, aes_table_entry::byte, container_of, product, and typeof().

Referenced by aes_column().

◆ aes_column()

static uint32_t aes_column ( const struct aes_table table,
size_t  stride,
const union aes_matrix in,
size_t  offset 
)
inlinestatic

Multiply [Inv]MixColumns matrix column by S-boxed input byte.

Parameters
tableAES lookup table
strideAES row shift stride
inAES input state
offsetOutput byte offset (after [Inv]ShiftRows)
Return values
productProduct of matrix column with S(input byte)

Note that the specified offset is not the offset of the input byte; it is the offset of the output byte which corresponds to the input byte. This output byte offset is used to calculate both the input byte offset and to select the appropriate matric column.

With a compile-time constant offset, this function will optimise down to a single "movzbl" (to extract the input byte) and will generate a single x86 memory reference expression which can then be used directly within a single "xorl" instruction.

Definition at line 194 of file aes.c.

195  {
196  const union aes_table_entry *entry;
197  unsigned int byte;
198 
199  /* Extract input byte corresponding to this output byte offset
200  * (i.e. perform [Inv]ShiftRows).
201  */
202  byte = in->byte[ ( stride * offset ) & 0xf ];
203 
204  /* Locate lookup table entry for this input byte (i.e. perform
205  * [Inv]SubBytes).
206  */
207  entry = &table->entry[byte];
208 
209  /* Multiply appropriate matrix column by this input byte
210  * (i.e. perform [Inv]MixColumns).
211  */
212  return aes_entry_column ( entry, ( offset & 0x3 ) );
213 }
A single AES lookup table entry.
Definition: aes.c:113
__be32 in[4]
Definition: CIB_PRM.h:35
static uint32_t aes_entry_column(const union aes_table_entry *entry, unsigned int column)
Multiply [Inv]MixColumns matrix column by scalar multiplicand.
Definition: aes.c:160
struct ena_llq_option stride
Descriptor strides.
Definition: ena.h:22
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:143
unsigned char byte
Definition: smc9000.h:38
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

References aes_entry_column(), aes_table::entry, in, offset, and stride.

Referenced by aes_output().

◆ aes_output()

static uint32_t aes_output ( const struct aes_table table,
size_t  stride,
const union aes_matrix in,
const union aes_matrix key,
unsigned int  column 
)
inlinestatic

Calculate intermediate round output column.

Parameters
tableAES lookup table
strideAES row shift stride
inAES input state
keyAES round key
columnColumn index
Return values
outputOutput column value

Definition at line 226 of file aes.c.

228  {
229  size_t offset = ( column * 4 );
230 
231  /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
232  * AddRoundKey for this column. The loop is unrolled to allow
233  * for the required compile-time constant optimisations.
234  */
235  return ( aes_column ( table, stride, in, ( offset + 0 ) ) ^
236  aes_column ( table, stride, in, ( offset + 1 ) ) ^
237  aes_column ( table, stride, in, ( offset + 2 ) ) ^
238  aes_column ( table, stride, in, ( offset + 3 ) ) ^
239  key->column[column] );
240 }
__be32 in[4]
Definition: CIB_PRM.h:35
static uint32_t aes_column(const struct aes_table *table, size_t stride, const union aes_matrix *in, size_t offset)
Multiply [Inv]MixColumns matrix column by S-boxed input byte.
Definition: aes.c:194
struct ena_llq_option stride
Descriptor strides.
Definition: ena.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
union @391 key
Sense key.
Definition: scsi.h:18

References aes_column(), in, key, offset, and stride.

Referenced by aes_round().

◆ aes_round()

static void aes_round ( const struct aes_table table,
size_t  stride,
const union aes_matrix in,
union aes_matrix out,
const union aes_matrix key 
)
inlinestatic

Perform a single intermediate round.

Parameters
tableAES lookup table
strideAES row shift stride
inAES input state
outAES output state
keyAES round key

Definition at line 252 of file aes.c.

254  {
255 
256  /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
257  * AddRoundKey for all columns. The loop is unrolled to allow
258  * for the required compile-time constant optimisations.
259  */
260  out->column[0] = aes_output ( table, stride, in, key, 0 );
261  out->column[1] = aes_output ( table, stride, in, key, 1 );
262  out->column[2] = aes_output ( table, stride, in, key, 2 );
263  out->column[3] = aes_output ( table, stride, in, key, 3 );
264 }
static uint32_t aes_output(const struct aes_table *table, size_t stride, const union aes_matrix *in, const union aes_matrix *key, unsigned int column)
Calculate intermediate round output column.
Definition: aes.c:226
__be32 in[4]
Definition: CIB_PRM.h:35
__be32 out[4]
Definition: CIB_PRM.h:36
struct ena_llq_option stride
Descriptor strides.
Definition: ena.h:22
union @391 key
Sense key.
Definition: scsi.h:18

References aes_output(), in, key, out, and stride.

Referenced by aes_decrypt_rounds(), and aes_encrypt_rounds().

◆ aes_encrypt_rounds()

static void aes_encrypt_rounds ( union aes_matrix in,
union aes_matrix out,
const union aes_matrix key,
unsigned int  rounds 
)
static

Perform encryption intermediate rounds.

Parameters
inAES input state
outAES output state
keyRound keys
roundsNumber of rounds (must be odd)

This function is deliberately marked as non-inlinable to ensure maximal availability of registers for GCC's register allocator, which has a tendency to otherwise spill performance-critical registers to the stack.

Definition at line 280 of file aes.c.

281  {
282  union aes_matrix *tmp;
283 
284  /* Perform intermediate rounds */
285  do {
286  /* Perform one intermediate round */
288  in, out, key++ );
289 
290  /* Swap input and output states for next round */
291  tmp = in;
292  in = out;
293  out = tmp;
294 
295  } while ( --rounds );
296 }
__be32 in[4]
Definition: CIB_PRM.h:35
__be32 out[4]
Definition: CIB_PRM.h:36
unsigned long tmp
Definition: linux_pci.h:65
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:147
AES matrix.
Definition: aes.h:22
static void aes_round(const struct aes_table *table, size_t stride, const union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key)
Perform a single intermediate round.
Definition: aes.c:252
Input stride for ShiftRows.
Definition: aes.c:61
union @391 key
Sense key.
Definition: scsi.h:18

References aes_mixcolumns, aes_round(), AES_STRIDE_SHIFTROWS, in, key, out, and tmp.

Referenced by aes_encrypt().

◆ aes_decrypt_rounds()

static void aes_decrypt_rounds ( union aes_matrix in,
union aes_matrix out,
const union aes_matrix key,
unsigned int  rounds 
)
static

Perform decryption intermediate rounds.

Parameters
inAES input state
outAES output state
keyRound keys
roundsNumber of rounds (must be odd)

As with aes_encrypt_rounds(), this function is deliberately marked as non-inlinable.

This function could potentially use the same binary code as is used for encryption. To compensate for the difference between ShiftRows and InvShiftRows, half of the input byte offsets would have to be modifiable at runtime (half by an offset of +4/-4, half by an offset of -4/+4 for ShiftRows/InvShiftRows). This can be accomplished in x86 assembly within the number of available registers, but GCC's register allocator struggles to do so, resulting in a significant performance decrease due to registers being spilled to the stack. We therefore use two separate but very similar binary functions based on the same C source.

Definition at line 321 of file aes.c.

322  {
323  union aes_matrix *tmp;
324 
325  /* Perform intermediate rounds */
326  do {
327  /* Perform one intermediate round */
329  in, out, key++ );
330 
331  /* Swap input and output states for next round */
332  tmp = in;
333  in = out;
334  out = tmp;
335 
336  } while ( --rounds );
337 }
__be32 in[4]
Definition: CIB_PRM.h:35
__be32 out[4]
Definition: CIB_PRM.h:36
unsigned long tmp
Definition: linux_pci.h:65
static struct aes_table aes_invmixcolumns
AES InvMixColumns lookup table.
Definition: aes.c:150
AES matrix.
Definition: aes.h:22
static void aes_round(const struct aes_table *table, size_t stride, const union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key)
Perform a single intermediate round.
Definition: aes.c:252
Input stride for InvShiftRows.
Definition: aes.c:72
union @391 key
Sense key.
Definition: scsi.h:18

References aes_invmixcolumns, aes_round(), AES_STRIDE_INVSHIFTROWS, in, key, out, and tmp.

Referenced by aes_decrypt(), and aes_setkey().

◆ aes_addroundkey()

static void aes_addroundkey ( union aes_matrix state,
const union aes_matrix key 
)
inlinestatic

Perform standalone AddRoundKey.

Parameters
stateAES state
keyAES round key

Definition at line 346 of file aes.c.

346  {
347 
348  state->column[0] ^= key->column[0];
349  state->column[1] ^= key->column[1];
350  state->column[2] ^= key->column[2];
351  state->column[3] ^= key->column[3];
352 }
uint8_t state
State.
Definition: eth_slow.h:48
union @391 key
Sense key.
Definition: scsi.h:18

References key, and state.

Referenced by aes_decrypt(), aes_encrypt(), and aes_final().

◆ aes_final()

static void aes_final ( const struct aes_table table,
size_t  stride,
const union aes_matrix in,
union aes_matrix out,
const union aes_matrix key 
)
static

Perform final round.

Parameters
tableAES lookup table
strideAES row shift stride
inAES input state
outAES output state
keyAES round key

Definition at line 363 of file aes.c.

365  {
366  const union aes_table_entry *entry;
367  unsigned int byte;
368  size_t out_offset;
369  size_t in_offset;
370 
371  /* Perform [Inv]ShiftRows and [Inv]SubBytes */
372  for ( out_offset = 0, in_offset = 0 ; out_offset < 16 ;
373  out_offset++, in_offset = ( ( in_offset + stride ) & 0xf ) ) {
374 
375  /* Extract input byte (i.e. perform [Inv]ShiftRows) */
376  byte = in->byte[in_offset];
377 
378  /* Locate lookup table entry for this input byte
379  * (i.e. perform [Inv]SubBytes).
380  */
381  entry = &table->entry[byte];
382 
383  /* Store output byte */
384  out->byte[out_offset] = entry->byte[0];
385  }
386 
387  /* Perform AddRoundKey */
388  aes_addroundkey ( out, key );
389 }
A single AES lookup table entry.
Definition: aes.c:113
__be32 in[4]
Definition: CIB_PRM.h:35
__be32 out[4]
Definition: CIB_PRM.h:36
struct ena_llq_option stride
Descriptor strides.
Definition: ena.h:22
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:115
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:143
static void aes_addroundkey(union aes_matrix *state, const union aes_matrix *key)
Perform standalone AddRoundKey.
Definition: aes.c:346
unsigned char byte
Definition: smc9000.h:38
union @391 key
Sense key.
Definition: scsi.h:18

References aes_addroundkey(), aes_table_entry::byte, aes_table::entry, in, key, out, and stride.

Referenced by aes_decrypt(), aes_encrypt(), and aes_setkey().

◆ aes_encrypt()

static void aes_encrypt ( void *  ctx,
const void *  src,
void *  dst,
size_t  len 
)
static

Encrypt data.

Parameters
ctxContext
srcData to encrypt
dstBuffer for encrypted data
lenLength of data

Definition at line 399 of file aes.c.

399  {
400  struct aes_context *aes = ctx;
401  union aes_matrix buffer[2];
402  union aes_matrix *in = &buffer[0];
403  union aes_matrix *out = &buffer[1];
404  unsigned int rounds = aes->rounds;
405 
406  /* Sanity check */
407  assert ( len == sizeof ( *in ) );
408 
409  /* Initialise input state */
410  memcpy ( in, src, sizeof ( *in ) );
411 
412  /* Perform initial round (AddRoundKey) */
413  aes_addroundkey ( in, &aes->encrypt.key[0] );
414 
415  /* Perform intermediate rounds (ShiftRows, SubBytes,
416  * MixColumns, AddRoundKey).
417  */
418  aes_encrypt_rounds ( in, out, &aes->encrypt.key[1], ( rounds - 2 ) );
419  in = out;
420 
421  /* Perform final round (ShiftRows, SubBytes, AddRoundKey) */
422  out = dst;
424  &aes->encrypt.key[ rounds - 1 ] );
425 }
unsigned int rounds
Number of rounds.
Definition: aes.h:42
__be32 in[4]
Definition: CIB_PRM.h:35
AES context.
Definition: aes.h:36
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct aes_round_keys encrypt
Encryption keys.
Definition: aes.h:38
__be32 out[4]
Definition: CIB_PRM.h:36
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void aes_final(const struct aes_table *table, size_t stride, const union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key)
Perform final round.
Definition: aes.c:363
static const void * src
Definition: string.h:48
ring len
Length.
Definition: dwmac.h:231
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:147
AES matrix.
Definition: aes.h:22
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition: aes.h:32
static void aes_addroundkey(union aes_matrix *state, const union aes_matrix *key)
Perform standalone AddRoundKey.
Definition: aes.c:346
static void aes_encrypt_rounds(union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key, unsigned int rounds)
Perform encryption intermediate rounds.
Definition: aes.c:280
Input stride for ShiftRows.
Definition: aes.c:61

References aes_addroundkey(), aes_encrypt_rounds(), aes_final(), aes_mixcolumns, AES_STRIDE_SHIFTROWS, assert(), buffer, ctx, aes_context::encrypt, in, aes_round_keys::key, len, memcpy(), out, aes_context::rounds, and src.

◆ aes_decrypt()

static void aes_decrypt ( void *  ctx,
const void *  src,
void *  dst,
size_t  len 
)
static

Decrypt data.

Parameters
ctxContext
srcData to decrypt
dstBuffer for decrypted data
lenLength of data

Definition at line 435 of file aes.c.

435  {
436  struct aes_context *aes = ctx;
437  union aes_matrix buffer[2];
438  union aes_matrix *in = &buffer[0];
439  union aes_matrix *out = &buffer[1];
440  unsigned int rounds = aes->rounds;
441 
442  /* Sanity check */
443  assert ( len == sizeof ( *in ) );
444 
445  /* Initialise input state */
446  memcpy ( in, src, sizeof ( *in ) );
447 
448  /* Perform initial round (AddRoundKey) */
449  aes_addroundkey ( in, &aes->decrypt.key[0] );
450 
451  /* Perform intermediate rounds (InvShiftRows, InvSubBytes,
452  * InvMixColumns, AddRoundKey).
453  */
454  aes_decrypt_rounds ( in, out, &aes->decrypt.key[1], ( rounds - 2 ) );
455  in = out;
456 
457  /* Perform final round (InvShiftRows, InvSubBytes, AddRoundKey) */
458  out = dst;
460  &aes->decrypt.key[ rounds - 1 ] );
461 }
unsigned int rounds
Number of rounds.
Definition: aes.h:42
__be32 in[4]
Definition: CIB_PRM.h:35
AES context.
Definition: aes.h:36
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
__be32 out[4]
Definition: CIB_PRM.h:36
static struct aes_table aes_invmixcolumns
AES InvMixColumns lookup table.
Definition: aes.c:150
struct aes_round_keys decrypt
Decryption keys.
Definition: aes.h:40
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void aes_final(const struct aes_table *table, size_t stride, const union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key)
Perform final round.
Definition: aes.c:363
static const void * src
Definition: string.h:48
ring len
Length.
Definition: dwmac.h:231
AES matrix.
Definition: aes.h:22
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition: aes.h:32
static void aes_addroundkey(union aes_matrix *state, const union aes_matrix *key)
Perform standalone AddRoundKey.
Definition: aes.c:346
static void aes_decrypt_rounds(union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key, unsigned int rounds)
Perform decryption intermediate rounds.
Definition: aes.c:321
Input stride for InvShiftRows.
Definition: aes.c:72

References aes_addroundkey(), aes_decrypt_rounds(), aes_final(), aes_invmixcolumns, AES_STRIDE_INVSHIFTROWS, assert(), buffer, ctx, aes_context::decrypt, in, aes_round_keys::key, len, memcpy(), out, aes_context::rounds, and src.

◆ aes_double()

static unsigned int aes_double ( unsigned int  poly)
static

Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8)

Parameters
polyPolynomial to be multiplied
Return values
resultResult

Definition at line 469 of file aes.c.

469  {
470 
471  /* Multiply polynomial by (x), placing the resulting x^8
472  * coefficient in the LSB (i.e. rotate byte left by one).
473  */
474  poly = rol8 ( poly, 1 );
475 
476  /* If coefficient of x^8 (in LSB) is non-zero, then reduce by
477  * subtracting (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8).
478  */
479  if ( poly & 0x01 ) {
480  poly ^= 0x01; /* Subtract x^8 (currently in LSB) */
481  poly ^= 0x1b; /* Subtract (x^4 + x^3 + x^2 + 1) */
482  }
483 
484  return poly;
485 }

Referenced by aes_generate(), aes_invmixcolumns_entry(), aes_mixcolumns_entry(), and aes_setkey().

◆ aes_mixcolumns_entry()

static void aes_mixcolumns_entry ( union aes_table_entry entry)
static

Fill in MixColumns lookup table entry.

Parameters
entryAES lookup table entry for scalar multiplicand

The MixColumns lookup table vector multiplier is {1,1,1,3,2,1,1,3}.

Definition at line 494 of file aes.c.

494  {
495  unsigned int scalar_x_1;
496  unsigned int scalar_x;
497  unsigned int scalar;
498 
499  /* Retrieve scalar multiplicand */
500  scalar = entry->byte[0];
501  entry->byte[1] = scalar;
502  entry->byte[2] = scalar;
503  entry->byte[5] = scalar;
504  entry->byte[6] = scalar;
505 
506  /* Calculate scalar multiplied by (x) */
507  scalar_x = aes_double ( scalar );
508  entry->byte[4] = scalar_x;
509 
510  /* Calculate scalar multiplied by (x + 1) */
511  scalar_x_1 = ( scalar_x ^ scalar );
512  entry->byte[3] = scalar_x_1;
513  entry->byte[7] = scalar_x_1;
514 }
static unsigned int aes_double(unsigned int poly)
Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8)
Definition: aes.c:469
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:115

References aes_double(), and aes_table_entry::byte.

Referenced by aes_generate().

◆ aes_invmixcolumns_entry()

static void aes_invmixcolumns_entry ( union aes_table_entry entry)
static

Fill in InvMixColumns lookup table entry.

Parameters
entryAES lookup table entry for scalar multiplicand

The InvMixColumns lookup table vector multiplier is {1,9,13,11,14,9,13,11}.

Definition at line 523 of file aes.c.

523  {
524  unsigned int scalar_x3_x2_x;
525  unsigned int scalar_x3_x2_1;
526  unsigned int scalar_x3_x2;
527  unsigned int scalar_x3_x_1;
528  unsigned int scalar_x3_1;
529  unsigned int scalar_x3;
530  unsigned int scalar_x2;
531  unsigned int scalar_x;
532  unsigned int scalar;
533 
534  /* Retrieve scalar multiplicand */
535  scalar = entry->byte[0];
536 
537  /* Calculate scalar multiplied by (x) */
538  scalar_x = aes_double ( scalar );
539 
540  /* Calculate scalar multiplied by (x^2) */
541  scalar_x2 = aes_double ( scalar_x );
542 
543  /* Calculate scalar multiplied by (x^3) */
544  scalar_x3 = aes_double ( scalar_x2 );
545 
546  /* Calculate scalar multiplied by (x^3 + 1) */
547  scalar_x3_1 = ( scalar_x3 ^ scalar );
548  entry->byte[1] = scalar_x3_1;
549  entry->byte[5] = scalar_x3_1;
550 
551  /* Calculate scalar multiplied by (x^3 + x + 1) */
552  scalar_x3_x_1 = ( scalar_x3_1 ^ scalar_x );
553  entry->byte[3] = scalar_x3_x_1;
554  entry->byte[7] = scalar_x3_x_1;
555 
556  /* Calculate scalar multiplied by (x^3 + x^2) */
557  scalar_x3_x2 = ( scalar_x3 ^ scalar_x2 );
558 
559  /* Calculate scalar multiplied by (x^3 + x^2 + 1) */
560  scalar_x3_x2_1 = ( scalar_x3_x2 ^ scalar );
561  entry->byte[2] = scalar_x3_x2_1;
562  entry->byte[6] = scalar_x3_x2_1;
563 
564  /* Calculate scalar multiplied by (x^3 + x^2 + x) */
565  scalar_x3_x2_x = ( scalar_x3_x2 ^ scalar_x );
566  entry->byte[4] = scalar_x3_x2_x;
567 }
static unsigned int aes_double(unsigned int poly)
Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8)
Definition: aes.c:469
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:115

References aes_double(), and aes_table_entry::byte.

Referenced by aes_generate().

◆ aes_generate()

static void aes_generate ( void  )
static

Generate AES lookup tables.

Definition at line 573 of file aes.c.

573  {
574  union aes_table_entry *entry;
575  union aes_table_entry *inventry;
576  unsigned int poly = 0x01;
577  unsigned int invpoly = 0x01;
578  unsigned int transformed;
579  unsigned int i;
580 
581  /* Iterate over non-zero values of GF(2^8) using generator (x + 1) */
582  do {
583 
584  /* Multiply polynomial by (x + 1) */
585  poly ^= aes_double ( poly );
586 
587  /* Divide inverse polynomial by (x + 1). This code
588  * fragment is taken directly from the Wikipedia page
589  * on the Rijndael S-box. An explanation of why it
590  * works would be greatly appreciated.
591  */
592  invpoly ^= ( invpoly << 1 );
593  invpoly ^= ( invpoly << 2 );
594  invpoly ^= ( invpoly << 4 );
595  if ( invpoly & 0x80 )
596  invpoly ^= 0x09;
597  invpoly &= 0xff;
598 
599  /* Apply affine transformation */
600  transformed = ( 0x63 ^ invpoly ^ rol8 ( invpoly, 1 ) ^
601  rol8 ( invpoly, 2 ) ^ rol8 ( invpoly, 3 ) ^
602  rol8 ( invpoly, 4 ) );
603 
604  /* Populate S-box (within MixColumns lookup table) */
605  aes_mixcolumns.entry[poly].byte[0] = transformed;
606 
607  } while ( poly != 0x01 );
608 
609  /* Populate zeroth S-box entry (which has no inverse) */
610  aes_mixcolumns.entry[0].byte[0] = 0x63;
611 
612  /* Fill in MixColumns and InvMixColumns lookup tables */
613  for ( i = 0 ; i < 256 ; i++ ) {
614 
615  /* Fill in MixColumns lookup table entry */
616  entry = &aes_mixcolumns.entry[i];
617  aes_mixcolumns_entry ( entry );
618 
619  /* Populate inverse S-box (within InvMixColumns lookup table) */
620  inventry = &aes_invmixcolumns.entry[ entry->byte[0] ];
621  inventry->byte[0] = i;
622 
623  /* Fill in InvMixColumns lookup table entry */
624  aes_invmixcolumns_entry ( inventry );
625  }
626 }
A single AES lookup table entry.
Definition: aes.c:113
static unsigned int aes_double(unsigned int poly)
Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8)
Definition: aes.c:469
static struct aes_table aes_invmixcolumns
AES InvMixColumns lookup table.
Definition: aes.c:150
static void aes_invmixcolumns_entry(union aes_table_entry *entry)
Fill in InvMixColumns lookup table entry.
Definition: aes.c:523
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:115
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:147
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:143
static void aes_mixcolumns_entry(union aes_table_entry *entry)
Fill in MixColumns lookup table entry.
Definition: aes.c:494

References aes_double(), aes_invmixcolumns, aes_invmixcolumns_entry(), aes_mixcolumns, aes_mixcolumns_entry(), aes_table_entry::byte, and aes_table::entry.

Referenced by aes_setkey().

◆ aes_key_rotate()

static uint32_t aes_key_rotate ( uint32_t  column)
inlinestatic

Rotate key column.

Parameters
columnKey column
Return values
columnUpdated key column

Definition at line 635 of file aes.c.

635  {
636 
637  return ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ?
638  ror32 ( column, 8 ) : rol32 ( column, 8 ) );
639 }
static u32 rol32(u32 v, int bits)
Rotate 32-bit value left.
Definition: wpa_tkip.c:174
#define __LITTLE_ENDIAN
Constant representing little-endian byte order.
Definition: endian.h:13
#define __BYTE_ORDER
Definition: endian.h:7
static u32 ror32(u32 v, int bits)
Rotate 32-bit value right.
Definition: wpa_tkip.c:162

References __BYTE_ORDER, __LITTLE_ENDIAN, rol32(), and ror32().

Referenced by aes_setkey().

◆ aes_key_sbox()

static uint32_t aes_key_sbox ( uint32_t  column)
static

Apply S-box to key column.

Parameters
columnKey column
Return values
columnUpdated key column

Definition at line 647 of file aes.c.

647  {
648  unsigned int i;
649  uint8_t byte;
650 
651  for ( i = 0 ; i < 4 ; i++ ) {
652  byte = ( column & 0xff );
653  byte = aes_mixcolumns.entry[byte].byte[0];
654  column = ( ( column & ~0xff ) | byte );
655  column = rol32 ( column, 8 );
656  }
657  return column;
658 }
static u32 rol32(u32 v, int bits)
Rotate 32-bit value left.
Definition: wpa_tkip.c:174
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:115
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:147
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:143
unsigned char uint8_t
Definition: stdint.h:10
unsigned char byte
Definition: smc9000.h:38

References aes_mixcolumns, aes_table_entry::byte, aes_table::entry, and rol32().

Referenced by aes_setkey().

◆ aes_key_rcon()

static uint32_t aes_key_rcon ( uint32_t  column,
unsigned int  rcon 
)
inlinestatic

Apply schedule round constant to key column.

Parameters
columnKey column
rconRound constant
Return values
columnUpdated key column

Definition at line 668 of file aes.c.

668  {
669 
670  return ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ?
671  ( column ^ rcon ) : ( column ^ ( rcon << 24 ) ) );
672 }
#define __LITTLE_ENDIAN
Constant representing little-endian byte order.
Definition: endian.h:13
#define __BYTE_ORDER
Definition: endian.h:7

References __BYTE_ORDER, and __LITTLE_ENDIAN.

Referenced by aes_setkey().

◆ aes_setkey()

static int aes_setkey ( void *  ctx,
const void *  key,
size_t  keylen 
)
static

Set key.

Parameters
ctxContext
keyKey
keylenKey length
Return values
rcReturn status code

Definition at line 682 of file aes.c.

682  {
683  struct aes_context *aes = ctx;
684  union aes_matrix *enc;
685  union aes_matrix *dec;
686  union aes_matrix temp;
687  union aes_matrix zero;
688  unsigned int rcon = 0x01;
689  unsigned int rounds;
690  size_t offset = 0;
691  uint32_t *prev;
692  uint32_t *next;
693  uint32_t *end;
694  uint32_t tmp;
695 
696  /* Generate lookup tables, if not already done */
697  if ( ! aes_mixcolumns.entry[0].byte[0] )
698  aes_generate();
699 
700  /* Validate key length and calculate number of intermediate rounds */
701  switch ( keylen ) {
702  case ( 128 / 8 ) :
703  rounds = 11;
704  break;
705  case ( 192 / 8 ) :
706  rounds = 13;
707  break;
708  case ( 256 / 8 ) :
709  rounds = 15;
710  break;
711  default:
712  DBGC ( aes, "AES %p unsupported key length (%zd bits)\n",
713  aes, ( keylen * 8 ) );
714  return -EINVAL;
715  }
716  aes->rounds = rounds;
717  enc = aes->encrypt.key;
718  end = enc[rounds].column;
719 
720  /* Copy raw key */
721  memcpy ( enc, key, keylen );
722  prev = enc->column;
723  next = ( ( ( void * ) prev ) + keylen );
724  tmp = next[-1];
725 
726  /* Construct expanded key */
727  while ( next < end ) {
728 
729  /* If this is the first column of an expanded key
730  * block, or the middle column of an AES-256 key
731  * block, then apply the S-box.
732  */
733  if ( ( offset == 0 ) || ( ( offset | keylen ) == 48 ) )
734  tmp = aes_key_sbox ( tmp );
735 
736  /* If this is the first column of an expanded key
737  * block then rotate and apply the round constant.
738  */
739  if ( offset == 0 ) {
740  tmp = aes_key_rotate ( tmp );
741  tmp = aes_key_rcon ( tmp, rcon );
742  rcon = aes_double ( rcon );
743  }
744 
745  /* XOR with previous key column */
746  tmp ^= *prev;
747 
748  /* Store column */
749  *next = tmp;
750 
751  /* Move to next column */
752  offset += sizeof ( *next );
753  if ( offset == keylen )
754  offset = 0;
755  next++;
756  prev++;
757  }
758  DBGC2 ( aes, "AES %p expanded %zd-bit key:\n", aes, ( keylen * 8 ) );
759  DBGC2_HDA ( aes, 0, &aes->encrypt, ( rounds * sizeof ( *enc ) ) );
760 
761  /* Convert to decryption key */
762  memset ( &zero, 0, sizeof ( zero ) );
763  dec = &aes->decrypt.key[ rounds - 1 ];
764  memcpy ( dec--, enc++, sizeof ( *dec ) );
765  while ( dec > aes->decrypt.key ) {
766  /* Perform InvMixColumns (by reusing the encryption
767  * final-round code to perform ShiftRows+SubBytes and
768  * reusing the decryption intermediate-round code to
769  * perform InvShiftRows+InvSubBytes+InvMixColumns, all
770  * with a zero encryption key).
771  */
773  enc++, &temp, &zero );
774  aes_decrypt_rounds ( &temp, dec--, &zero, 1 );
775  }
776  memcpy ( dec--, enc++, sizeof ( *dec ) );
777  DBGC2 ( aes, "AES %p inverted %zd-bit key:\n", aes, ( keylen * 8 ) );
778  DBGC2_HDA ( aes, 0, &aes->decrypt, ( rounds * sizeof ( *dec ) ) );
779 
780  return 0;
781 }
unsigned int rounds
Number of rounds.
Definition: aes.h:42
#define EINVAL
Invalid argument.
Definition: errno.h:429
#define DBGC(...)
Definition: compiler.h:505
AES context.
Definition: aes.h:36
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct aes_round_keys encrypt
Encryption keys.
Definition: aes.h:38
static unsigned int aes_double(unsigned int poly)
Multiply a polynomial by (x) modulo (x^8 + x^4 + x^3 + x^2 + 1) in GF(2^8)
Definition: aes.c:469
static uint32_t aes_key_rcon(uint32_t column, unsigned int rcon)
Apply schedule round constant to key column.
Definition: aes.c:668
unsigned long tmp
Definition: linux_pci.h:65
struct aes_round_keys decrypt
Decryption keys.
Definition: aes.h:40
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static uint32_t aes_key_sbox(uint32_t column)
Apply S-box to key column.
Definition: aes.c:647
static void aes_final(const struct aes_table *table, size_t stride, const union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key)
Perform final round.
Definition: aes.c:363
#define DBGC2_HDA(...)
Definition: compiler.h:523
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:115
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:147
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:143
static void aes_generate(void)
Generate AES lookup tables.
Definition: aes.c:573
AES matrix.
Definition: aes.h:22
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition: aes.h:32
unsigned int uint32_t
Definition: stdint.h:12
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
static uint32_t aes_key_rotate(uint32_t column)
Rotate key column.
Definition: aes.c:635
#define DBGC2(...)
Definition: compiler.h:522
uint32_t column[4]
Viewed as an array of four-byte columns.
Definition: aes.h:26
uint32_t end
Ending offset.
Definition: netvsc.h:18
Input stride for ShiftRows.
Definition: aes.c:61
static void aes_decrypt_rounds(union aes_matrix *in, union aes_matrix *out, const union aes_matrix *key, unsigned int rounds)
Perform decryption intermediate rounds.
Definition: aes.c:321
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
union @391 key
Sense key.
Definition: scsi.h:18
void * memset(void *dest, int character, size_t len) __nonnull

References aes_decrypt_rounds(), aes_double(), aes_final(), aes_generate(), aes_key_rcon(), aes_key_rotate(), aes_key_sbox(), aes_mixcolumns, AES_STRIDE_SHIFTROWS, aes_table_entry::byte, aes_matrix::column, ctx, DBGC, DBGC2, DBGC2_HDA, aes_context::decrypt, EINVAL, aes_context::encrypt, end, aes_table::entry, aes_round_keys::key, key, memcpy(), memset(), next, offset, aes_context::rounds, and tmp.

◆ ECB_CIPHER()

ECB_CIPHER ( aes_ecb  ,
aes_ecb_algorithm  ,
aes_algorithm  ,
struct aes_context  ,
AES_BLOCKSIZE   
)

◆ CBC_CIPHER()

CBC_CIPHER ( aes_cbc  ,
aes_cbc_algorithm  ,
aes_algorithm  ,
struct aes_context  ,
AES_BLOCKSIZE   
)

◆ GCM_CIPHER()

GCM_CIPHER ( aes_gcm  ,
aes_gcm_algorithm  ,
aes_algorithm  ,
struct aes_context  ,
AES_BLOCKSIZE   
)

Variable Documentation

◆ aes_mixcolumns

struct aes_table aes_mixcolumns
static

AES MixColumns lookup table.

Definition at line 147 of file aes.c.

Referenced by aes_encrypt(), aes_encrypt_rounds(), aes_generate(), aes_key_sbox(), and aes_setkey().

◆ aes_invmixcolumns

struct aes_table aes_invmixcolumns
static

AES InvMixColumns lookup table.

Definition at line 150 of file aes.c.

Referenced by aes_decrypt(), aes_decrypt_rounds(), and aes_generate().

◆ aes_algorithm

struct cipher_algorithm aes_algorithm
Initial value:
= {
.name = "aes",
.ctxsize = sizeof ( struct aes_context ),
.blocksize = AES_BLOCKSIZE,
.alignsize = 0,
.authsize = 0,
.setkey = aes_setkey,
.encrypt = aes_encrypt,
.decrypt = aes_decrypt,
}
void cipher_null_setiv(void *ctx __unused, const void *iv __unused, size_t ivlen __unused)
Definition: crypto_null.c:65
AES context.
Definition: aes.h:36
static void aes_decrypt(void *ctx, const void *src, void *dst, size_t len)
Decrypt data.
Definition: aes.c:435
static void aes_encrypt(void *ctx, const void *src, void *dst, size_t len)
Encrypt data.
Definition: aes.c:399
#define AES_BLOCKSIZE
AES blocksize.
Definition: aes.h:16
void cipher_null_auth(void *ctx __unused, void *auth __unused)
Definition: crypto_null.c:80
static int aes_setkey(void *ctx, const void *key, size_t keylen)
Set key.
Definition: aes.c:682

Basic AES algorithm.

Definition at line 784 of file aes.c.

Referenced by aes_unwrap(), aes_wrap(), ccmp_cbc_mac(), ccmp_ctr_xor(), ccmp_feed_cbc_mac(), and ccmp_init().