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)
 
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 49 of file aes.c.

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

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ 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 159 of file aes.c.

159  {
160  const union {
161  uint8_t byte;
162  uint32_t column;
163  } __attribute__ (( may_alias )) *product;
164 
165  /* Locate relevant four-byte subset */
166  product = container_of ( &entry->byte[ 4 - column ],
167  typeof ( *product ), byte );
168 
169  /* Extract this four-byte subset */
170  return product->column;
171 }
#define __attribute__(x)
Definition: compiler.h:10
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:114
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:16
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45

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 193 of file aes.c.

194  {
195  const union aes_table_entry *entry;
196  unsigned int byte;
197 
198  /* Extract input byte corresponding to this output byte offset
199  * (i.e. perform [Inv]ShiftRows).
200  */
201  byte = in->byte[ ( stride * offset ) & 0xf ];
202 
203  /* Locate lookup table entry for this input byte (i.e. perform
204  * [Inv]SubBytes).
205  */
206  entry = &table->entry[byte];
207 
208  /* Multiply appropriate matrix column by this input byte
209  * (i.e. perform [Inv]MixColumns).
210  */
211  return aes_entry_column ( entry, ( offset & 0x3 ) );
212 }
A single AES lookup table entry.
Definition: aes.c:112
__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:159
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:142
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, and offset.

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 225 of file aes.c.

227  {
228  size_t offset = ( column * 4 );
229 
230  /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
231  * AddRoundKey for this column. The loop is unrolled to allow
232  * for the required compile-time constant optimisations.
233  */
234  return ( aes_column ( table, stride, in, ( offset + 0 ) ) ^
235  aes_column ( table, stride, in, ( offset + 1 ) ) ^
236  aes_column ( table, stride, in, ( offset + 2 ) ) ^
237  aes_column ( table, stride, in, ( offset + 3 ) ) ^
238  key->column[column] );
239 }
__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:193
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
union @383 key
Sense key.
Definition: scsi.h:18

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

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 251 of file aes.c.

253  {
254 
255  /* Perform [Inv]ShiftRows, [Inv]SubBytes, [Inv]MixColumns, and
256  * AddRoundKey for all columns. The loop is unrolled to allow
257  * for the required compile-time constant optimisations.
258  */
259  out->column[0] = aes_output ( table, stride, in, key, 0 );
260  out->column[1] = aes_output ( table, stride, in, key, 1 );
261  out->column[2] = aes_output ( table, stride, in, key, 2 );
262  out->column[3] = aes_output ( table, stride, in, key, 3 );
263 }
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:225
__be32 in[4]
Definition: CIB_PRM.h:35
__be32 out[4]
Definition: CIB_PRM.h:36
union @383 key
Sense key.
Definition: scsi.h:18

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

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 279 of file aes.c.

280  {
281  union aes_matrix *tmp;
282 
283  /* Perform intermediate rounds */
284  do {
285  /* Perform one intermediate round */
287  in, out, key++ );
288 
289  /* Swap input and output states for next round */
290  tmp = in;
291  in = out;
292  out = tmp;
293 
294  } while ( --rounds );
295 }
__be32 in[4]
Definition: CIB_PRM.h:35
unsigned long tmp
Definition: linux_pci.h:63
__be32 out[4]
Definition: CIB_PRM.h:36
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:146
AES matrix.
Definition: aes.h:21
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:251
Input stride for ShiftRows.
Definition: aes.c:60
union @383 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 320 of file aes.c.

321  {
322  union aes_matrix *tmp;
323 
324  /* Perform intermediate rounds */
325  do {
326  /* Perform one intermediate round */
328  in, out, key++ );
329 
330  /* Swap input and output states for next round */
331  tmp = in;
332  in = out;
333  out = tmp;
334 
335  } while ( --rounds );
336 }
__be32 in[4]
Definition: CIB_PRM.h:35
unsigned long tmp
Definition: linux_pci.h:63
static struct aes_table aes_invmixcolumns
AES InvMixColumns lookup table.
Definition: aes.c:149
__be32 out[4]
Definition: CIB_PRM.h:36
AES matrix.
Definition: aes.h:21
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:251
Input stride for InvShiftRows.
Definition: aes.c:71
union @383 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 345 of file aes.c.

345  {
346 
347  state->column[0] ^= key->column[0];
348  state->column[1] ^= key->column[1];
349  state->column[2] ^= key->column[2];
350  state->column[3] ^= key->column[3];
351 }
uint8_t state
State.
Definition: eth_slow.h:47
union @383 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 362 of file aes.c.

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

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

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 398 of file aes.c.

398  {
399  struct aes_context *aes = ctx;
400  union aes_matrix buffer[2];
401  union aes_matrix *in = &buffer[0];
402  union aes_matrix *out = &buffer[1];
403  unsigned int rounds = aes->rounds;
404 
405  /* Sanity check */
406  assert ( len == sizeof ( *in ) );
407 
408  /* Initialise input state */
409  memcpy ( in, src, sizeof ( *in ) );
410 
411  /* Perform initial round (AddRoundKey) */
412  aes_addroundkey ( in, &aes->encrypt.key[0] );
413 
414  /* Perform intermediate rounds (ShiftRows, SubBytes,
415  * MixColumns, AddRoundKey).
416  */
417  aes_encrypt_rounds ( in, out, &aes->encrypt.key[1], ( rounds - 2 ) );
418  in = out;
419 
420  /* Perform final round (ShiftRows, SubBytes, AddRoundKey) */
421  out = dst;
423  &aes->encrypt.key[ rounds - 1 ] );
424 }
unsigned int rounds
Number of rounds.
Definition: aes.h:41
static const void * src
Definition: string.h:47
__be32 in[4]
Definition: CIB_PRM.h:35
AES context.
Definition: aes.h:35
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:37
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:362
__be32 out[4]
Definition: CIB_PRM.h:36
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:146
AES matrix.
Definition: aes.h:21
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition: aes.h:31
static void aes_addroundkey(union aes_matrix *state, const union aes_matrix *key)
Perform standalone AddRoundKey.
Definition: aes.c:345
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:279
Input stride for ShiftRows.
Definition: aes.c:60
uint32_t len
Length.
Definition: ena.h:14

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 434 of file aes.c.

434  {
435  struct aes_context *aes = ctx;
436  union aes_matrix buffer[2];
437  union aes_matrix *in = &buffer[0];
438  union aes_matrix *out = &buffer[1];
439  unsigned int rounds = aes->rounds;
440 
441  /* Sanity check */
442  assert ( len == sizeof ( *in ) );
443 
444  /* Initialise input state */
445  memcpy ( in, src, sizeof ( *in ) );
446 
447  /* Perform initial round (AddRoundKey) */
448  aes_addroundkey ( in, &aes->decrypt.key[0] );
449 
450  /* Perform intermediate rounds (InvShiftRows, InvSubBytes,
451  * InvMixColumns, AddRoundKey).
452  */
453  aes_decrypt_rounds ( in, out, &aes->decrypt.key[1], ( rounds - 2 ) );
454  in = out;
455 
456  /* Perform final round (InvShiftRows, InvSubBytes, AddRoundKey) */
457  out = dst;
459  &aes->decrypt.key[ rounds - 1 ] );
460 }
unsigned int rounds
Number of rounds.
Definition: aes.h:41
static const void * src
Definition: string.h:47
__be32 in[4]
Definition: CIB_PRM.h:35
AES context.
Definition: aes.h:35
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static struct aes_table aes_invmixcolumns
AES InvMixColumns lookup table.
Definition: aes.c:149
struct aes_round_keys decrypt
Decryption keys.
Definition: aes.h:39
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:362
__be32 out[4]
Definition: CIB_PRM.h:36
AES matrix.
Definition: aes.h:21
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition: aes.h:31
static void aes_addroundkey(union aes_matrix *state, const union aes_matrix *key)
Perform standalone AddRoundKey.
Definition: aes.c:345
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:320
Input stride for InvShiftRows.
Definition: aes.c:71
uint32_t len
Length.
Definition: ena.h:14

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 468 of file aes.c.

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

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 493 of file aes.c.

493  {
494  unsigned int scalar_x_1;
495  unsigned int scalar_x;
496  unsigned int scalar;
497 
498  /* Retrieve scalar multiplicand */
499  scalar = entry->byte[0];
500  entry->byte[1] = scalar;
501  entry->byte[2] = scalar;
502  entry->byte[5] = scalar;
503  entry->byte[6] = scalar;
504 
505  /* Calculate scalar multiplied by (x) */
506  scalar_x = aes_double ( scalar );
507  entry->byte[4] = scalar_x;
508 
509  /* Calculate scalar multiplied by (x + 1) */
510  scalar_x_1 = ( scalar_x ^ scalar );
511  entry->byte[3] = scalar_x_1;
512  entry->byte[7] = scalar_x_1;
513 }
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:468
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:114

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 522 of file aes.c.

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

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 572 of file aes.c.

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

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 634 of file aes.c.

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

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 646 of file aes.c.

646  {
647  unsigned int i;
648  uint8_t byte;
649 
650  for ( i = 0 ; i < 4 ; i++ ) {
651  byte = ( column & 0xff );
652  byte = aes_mixcolumns.entry[byte].byte[0];
653  column = ( ( column & ~0xff ) | byte );
654  column = rol32 ( column, 8 );
655  }
656  return column;
657 }
static u32 rol32(u32 v, int bits)
Rotate 32-bit value left.
Definition: wpa_tkip.c:173
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:114
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:146
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:142
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 667 of file aes.c.

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

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 681 of file aes.c.

681  {
682  struct aes_context *aes = ctx;
683  union aes_matrix *enc;
684  union aes_matrix *dec;
685  union aes_matrix temp;
686  union aes_matrix zero;
687  unsigned int rcon = 0x01;
688  unsigned int rounds;
689  size_t offset = 0;
690  uint32_t *prev;
691  uint32_t *next;
692  uint32_t *end;
693  uint32_t tmp;
694 
695  /* Generate lookup tables, if not already done */
696  if ( ! aes_mixcolumns.entry[0].byte[0] )
697  aes_generate();
698 
699  /* Validate key length and calculate number of intermediate rounds */
700  switch ( keylen ) {
701  case ( 128 / 8 ) :
702  rounds = 11;
703  break;
704  case ( 192 / 8 ) :
705  rounds = 13;
706  break;
707  case ( 256 / 8 ) :
708  rounds = 15;
709  break;
710  default:
711  DBGC ( aes, "AES %p unsupported key length (%zd bits)\n",
712  aes, ( keylen * 8 ) );
713  return -EINVAL;
714  }
715  aes->rounds = rounds;
716  enc = aes->encrypt.key;
717  end = enc[rounds].column;
718 
719  /* Copy raw key */
720  memcpy ( enc, key, keylen );
721  prev = enc->column;
722  next = ( ( ( void * ) prev ) + keylen );
723  tmp = next[-1];
724 
725  /* Construct expanded key */
726  while ( next < end ) {
727 
728  /* If this is the first column of an expanded key
729  * block, or the middle column of an AES-256 key
730  * block, then apply the S-box.
731  */
732  if ( ( offset == 0 ) || ( ( offset | keylen ) == 48 ) )
733  tmp = aes_key_sbox ( tmp );
734 
735  /* If this is the first column of an expanded key
736  * block then rotate and apply the round constant.
737  */
738  if ( offset == 0 ) {
739  tmp = aes_key_rotate ( tmp );
740  tmp = aes_key_rcon ( tmp, rcon );
741  rcon = aes_double ( rcon );
742  }
743 
744  /* XOR with previous key column */
745  tmp ^= *prev;
746 
747  /* Store column */
748  *next = tmp;
749 
750  /* Move to next column */
751  offset += sizeof ( *next );
752  if ( offset == keylen )
753  offset = 0;
754  next++;
755  prev++;
756  }
757  DBGC2 ( aes, "AES %p expanded %zd-bit key:\n", aes, ( keylen * 8 ) );
758  DBGC2_HDA ( aes, 0, &aes->encrypt, ( rounds * sizeof ( *enc ) ) );
759 
760  /* Convert to decryption key */
761  memset ( &zero, 0, sizeof ( zero ) );
762  dec = &aes->decrypt.key[ rounds - 1 ];
763  memcpy ( dec--, enc++, sizeof ( *dec ) );
764  while ( dec > aes->decrypt.key ) {
765  /* Perform InvMixColumns (by reusing the encryption
766  * final-round code to perform ShiftRows+SubBytes and
767  * reusing the decryption intermediate-round code to
768  * perform InvShiftRows+InvSubBytes+InvMixColumns, all
769  * with a zero encryption key).
770  */
772  enc++, &temp, &zero );
773  aes_decrypt_rounds ( &temp, dec--, &zero, 1 );
774  }
775  memcpy ( dec--, enc++, sizeof ( *dec ) );
776  DBGC2 ( aes, "AES %p inverted %zd-bit key:\n", aes, ( keylen * 8 ) );
777  DBGC2_HDA ( aes, 0, &aes->decrypt, ( rounds * sizeof ( *dec ) ) );
778 
779  return 0;
780 }
unsigned int rounds
Number of rounds.
Definition: aes.h:41
#define EINVAL
Invalid argument.
Definition: errno.h:428
uint32_t next
Next descriptor address.
Definition: myson.h:18
#define DBGC(...)
Definition: compiler.h:505
AES context.
Definition: aes.h:35
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct aes_round_keys encrypt
Encryption keys.
Definition: aes.h:37
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:468
static uint32_t aes_key_rcon(uint32_t column, unsigned int rcon)
Apply schedule round constant to key column.
Definition: aes.c:667
unsigned long tmp
Definition: linux_pci.h:63
struct aes_round_keys decrypt
Decryption keys.
Definition: aes.h:39
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:646
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:362
#define DBGC2_HDA(...)
Definition: compiler.h:523
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:114
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:146
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:142
static void aes_generate(void)
Generate AES lookup tables.
Definition: aes.c:572
AES matrix.
Definition: aes.h:21
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition: aes.h:31
unsigned int uint32_t
Definition: stdint.h:12
static uint32_t aes_key_rotate(uint32_t column)
Rotate key column.
Definition: aes.c:634
#define DBGC2(...)
Definition: compiler.h:522
uint32_t column[4]
Viewed as an array of four-byte columns.
Definition: aes.h:25
uint32_t end
Ending offset.
Definition: netvsc.h:18
Input stride for ShiftRows.
Definition: aes.c:60
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
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:320
union @383 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 146 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 149 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:64
AES context.
Definition: aes.h:35
static void aes_decrypt(void *ctx, const void *src, void *dst, size_t len)
Decrypt data.
Definition: aes.c:434
static void aes_encrypt(void *ctx, const void *src, void *dst, size_t len)
Encrypt data.
Definition: aes.c:398
#define AES_BLOCKSIZE
AES blocksize.
Definition: aes.h:15
void cipher_null_auth(void *ctx __unused, void *auth __unused)
Definition: crypto_null.c:79
static int aes_setkey(void *ctx, const void *key, size_t keylen)
Set key.
Definition: aes.c:681

Basic AES algorithm.

Definition at line 783 of file aes.c.

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