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/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)
 
union aes_table_entry __attribute__ ((packed))
 
struct aes_table __attribute__ ((aligned(8)))
 
static __attribute__ ((always_inline))
 Multiply [Inv]MixColumns matrix column by scalar multiplicand. More...
 
static __attribute__ ((noinline))
 Perform encryption intermediate rounds. 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 __attribute__ ((const))
 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_sbox (uint32_t column)
 Apply S-box to key column. More...
 
static int aes_setkey (void *ctx, const void *key, size_t keylen)
 Set key. More...
 
static void aes_setiv (void *ctx __unused, const void *iv __unused)
 Set initialisation vector. 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)
 

Variables

uint8_t byte [8]
 Viewed as an array of bytes. More...
 
union aes_table_entry entry [256]
 Table entries, indexed by S(N) More...
 
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 48 of file aes.c.

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

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __attribute__() [1/5]

union aes_table_entry __attribute__ ( (packed)  )

Referenced by __attribute__().

◆ __attribute__() [2/5]

struct aes_table __attribute__ ( (aligned(8))  )

◆ __attribute__() [3/5]

static __attribute__ ( (always_inline)  )
inlinestatic

Multiply [Inv]MixColumns matrix column by scalar multiplicand.

Apply schedule round constant to key column.

Rotate key column.

Perform standalone AddRoundKey.

Perform a single intermediate round.

Calculate intermediate round output column.

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

Parameters
entryAES lookup table entry for scalar multiplicand
column[Inv]MixColumns matrix column index
Return values
productProduct of matrix column with scalar multiplicand
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.

Parameters
tableAES lookup table
strideAES row shift stride
inAES input state
keyAES round key
columnColumn index
Return values
outputOutput column value
Parameters
tableAES lookup table
strideAES row shift stride
inAES input state
outAES output state
keyAES round key
stateAES state
keyAES round key
columnKey column
Return values
columnUpdated key column
Parameters
columnKey column
rconRound constant
Return values
columnUpdated key column

Definition at line 157 of file aes.c.

158  {
159  const union {
160  uint8_t byte;
162  } __attribute__ (( may_alias )) *product;
163 
164  /* Locate relevant four-byte subset */
165  product = container_of ( &entry->byte[ 4 - column ],
166  typeof ( *product ), byte );
167 
168  /* Extract this four-byte subset */
169  return product->column;
170 }
union aes_table_entry __attribute__((packed))
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:26
#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:113
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
uint32_t column[4]
Viewed as an array of four-byte columns.
Definition: aes.h:14
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
uint8_t product
Product string.
Definition: smbios.h:16

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

◆ __attribute__() [4/5]

static __attribute__ ( (noinline)  )
static

Perform encryption intermediate rounds.

Perform decryption 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.

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

279  {
280  union aes_matrix *tmp;
281 
282  /* Perform intermediate rounds */
283  do {
284  /* Perform one intermediate round */
285  aes_round ( &aes_mixcolumns, AES_STRIDE_SHIFTROWS,
286  in, out, key++ );
287 
288  /* Swap input and output states for next round */
289  tmp = in;
290  in = out;
291  out = tmp;
292 
293  } while ( --rounds );
294 }
__be32 in[4]
Definition: CIB_PRM.h:35
__be32 out[4]
Definition: CIB_PRM.h:36
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:145
uint8_t * tmp
Definition: entropy.h:156
AES matrix.
Definition: aes.h:21
Input stride for ShiftRows.
Definition: aes.c:59
union @375 key
Sense key.
Definition: scsi.h:18

References aes_mixcolumns, AES_STRIDE_SHIFTROWS, in, key, out, and tmp.

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

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

References byte, aes_table_entry::byte, entry, 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 397 of file aes.c.

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

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

433  {
434  struct aes_context *aes = ctx;
435  union aes_matrix buffer[2];
436  union aes_matrix *in = &buffer[0];
437  union aes_matrix *out = &buffer[1];
438  unsigned int rounds = aes->rounds;
439 
440  /* Sanity check */
441  assert ( len == sizeof ( *in ) );
442 
443  /* Initialise input state */
444  memcpy ( in, src, sizeof ( *in ) );
445 
446  /* Perform initial round (AddRoundKey) */
447  aes_addroundkey ( in, &aes->decrypt.key[0] );
448 
449  /* Perform intermediate rounds (InvShiftRows, InvSubBytes,
450  * InvMixColumns, AddRoundKey).
451  */
452  aes_decrypt_rounds ( in, out, &aes->decrypt.key[1], ( rounds - 2 ) );
453  in = out;
454 
455  /* Perform final round (InvShiftRows, InvSubBytes, AddRoundKey) */
456  out = dst;
458  &aes->decrypt.key[ rounds - 1 ] );
459 }
unsigned int rounds
Number of rounds.
Definition: aes.h:41
__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:148
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:361
__be32 out[4]
Definition: CIB_PRM.h:36
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
AES matrix.
Definition: aes.h:21
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition: aes.h:31
uint32_t len
Length.
Definition: ena.h:14
Input stride for InvShiftRows.
Definition: aes.c:70

References 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.

◆ __attribute__() [5/5]

static __attribute__ ( (const)  )
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 467 of file aes.c.

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

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

492  {
493  unsigned int scalar_x_1;
494  unsigned int scalar_x;
495  unsigned int scalar;
496 
497  /* Retrieve scalar multiplicand */
498  scalar = entry->byte[0];
499  entry->byte[1] = scalar;
500  entry->byte[2] = scalar;
501  entry->byte[5] = scalar;
502  entry->byte[6] = scalar;
503 
504  /* Calculate scalar multiplied by (x) */
505  scalar_x = aes_double ( scalar );
506  entry->byte[4] = scalar_x;
507 
508  /* Calculate scalar multiplied by (x + 1) */
509  scalar_x_1 = ( scalar_x ^ scalar );
510  entry->byte[3] = scalar_x_1;
511  entry->byte[7] = scalar_x_1;
512 }
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:113
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26

References aes_table_entry::byte, and entry.

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

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

References aes_table_entry::byte, and entry.

Referenced by aes_generate().

◆ aes_generate()

static void aes_generate ( void  )
static

Generate AES lookup tables.

Definition at line 571 of file aes.c.

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

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

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

645  {
646  unsigned int i;
647  uint8_t byte;
648 
649  for ( i = 0 ; i < 4 ; i++ ) {
650  byte = ( column & 0xff );
651  byte = aes_mixcolumns.entry[byte].byte[0];
652  column = ( ( column & ~0xff ) | byte );
653  column = rol32 ( column, 8 );
654  }
655  return column;
656 }
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:26
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:113
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:145
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:141
uint32_t column[4]
Viewed as an array of four-byte columns.
Definition: aes.h:14
unsigned char uint8_t
Definition: stdint.h:10

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

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

680  {
681  struct aes_context *aes = ctx;
682  union aes_matrix *enc;
683  union aes_matrix *dec;
684  union aes_matrix temp;
685  union aes_matrix zero;
686  unsigned int rcon = 0x01;
687  unsigned int rounds;
688  size_t offset = 0;
689  uint32_t *prev;
690  uint32_t *next;
691  uint32_t *end;
692  uint32_t tmp;
693 
694  /* Generate lookup tables, if not already done */
695  if ( ! aes_mixcolumns.entry[0].byte[0] )
696  aes_generate();
697 
698  /* Validate key length and calculate number of intermediate rounds */
699  switch ( keylen ) {
700  case ( 128 / 8 ) :
701  rounds = 11;
702  break;
703  case ( 192 / 8 ) :
704  rounds = 13;
705  break;
706  case ( 256 / 8 ) :
707  rounds = 15;
708  break;
709  default:
710  DBGC ( aes, "AES %p unsupported key length (%zd bits)\n",
711  aes, ( keylen * 8 ) );
712  return -EINVAL;
713  }
714  aes->rounds = rounds;
715  enc = aes->encrypt.key;
716  end = enc[rounds].column;
717 
718  /* Copy raw key */
719  memcpy ( enc, key, keylen );
720  prev = enc->column;
721  next = ( ( ( void * ) prev ) + keylen );
722  tmp = next[-1];
723 
724  /* Construct expanded key */
725  while ( next < end ) {
726 
727  /* If this is the first column of an expanded key
728  * block, or the middle column of an AES-256 key
729  * block, then apply the S-box.
730  */
731  if ( ( offset == 0 ) || ( ( offset | keylen ) == 48 ) )
732  tmp = aes_key_sbox ( tmp );
733 
734  /* If this is the first column of an expanded key
735  * block then rotate and apply the round constant.
736  */
737  if ( offset == 0 ) {
738  tmp = aes_key_rotate ( tmp );
739  tmp = aes_key_rcon ( tmp, rcon );
740  rcon = aes_double ( rcon );
741  }
742 
743  /* XOR with previous key column */
744  tmp ^= *prev;
745 
746  /* Store column */
747  *next = tmp;
748 
749  /* Move to next column */
750  offset += sizeof ( *next );
751  if ( offset == keylen )
752  offset = 0;
753  next++;
754  prev++;
755  }
756  DBGC2 ( aes, "AES %p expanded %zd-bit key:\n", aes, ( keylen * 8 ) );
757  DBGC2_HDA ( aes, 0, &aes->encrypt, ( rounds * sizeof ( *enc ) ) );
758 
759  /* Convert to decryption key */
760  memset ( &zero, 0, sizeof ( zero ) );
761  dec = &aes->decrypt.key[ rounds - 1 ];
762  memcpy ( dec--, enc++, sizeof ( *dec ) );
763  while ( dec > aes->decrypt.key ) {
764  /* Perform InvMixColumns (by reusing the encryption
765  * final-round code to perform ShiftRows+SubBytes and
766  * reusing the decryption intermediate-round code to
767  * perform InvShiftRows+InvSubBytes+InvMixColumns, all
768  * with a zero encryption key).
769  */
771  enc++, &temp, &zero );
772  aes_decrypt_rounds ( &temp, dec--, &zero, 1 );
773  }
774  memcpy ( dec--, enc++, sizeof ( *dec ) );
775  DBGC2 ( aes, "AES %p inverted %zd-bit key:\n", aes, ( keylen * 8 ) );
776  DBGC2_HDA ( aes, 0, &aes->decrypt, ( rounds * sizeof ( *dec ) ) );
777 
778  return 0;
779 }
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
uint32_t zero
Must be zero.
Definition: ntlm.h:24
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct aes_round_keys encrypt
Encryption keys.
Definition: aes.h:37
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:645
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:361
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define DBGC2_HDA(...)
Definition: compiler.h:523
uint8_t byte[8]
Viewed as an array of bytes.
Definition: aes.c:113
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition: aes.c:145
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:141
static void aes_generate(void)
Generate AES lookup tables.
Definition: aes.c:571
uint8_t * tmp
Definition: entropy.h:156
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
#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:59
union @375 key
Sense key.
Definition: scsi.h:18
void * memset(void *dest, int character, size_t len) __nonnull

References aes_final(), aes_generate(), 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, tmp, and zero.

◆ aes_setiv()

static void aes_setiv ( void *ctx  __unused,
const void *iv  __unused 
)
static

Set initialisation vector.

Parameters
ctxContext
ivInitialisation vector

Definition at line 787 of file aes.c.

787  {
788  /* Nothing to do */
789 }

◆ 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   
)

Variable Documentation

◆ byte

Viewed as an array of bytes.

Definition at line 26 of file aes.c.

Referenced by __attribute__(), aes_final(), and aes_key_sbox().

◆ entry

union aes_table_entry entry[256]

◆ aes_mixcolumns

struct aes_table aes_mixcolumns
static

AES MixColumns lookup table.

Definition at line 145 of file aes.c.

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

◆ aes_invmixcolumns

struct aes_table aes_invmixcolumns
static

AES InvMixColumns lookup table.

Definition at line 148 of file aes.c.

Referenced by aes_decrypt(), and aes_generate().

◆ aes_algorithm

struct cipher_algorithm aes_algorithm
Initial value:
= {
.name = "aes",
.ctxsize = sizeof ( struct aes_context ),
.blocksize = AES_BLOCKSIZE,
.setkey = aes_setkey,
.setiv = aes_setiv,
.encrypt = aes_encrypt,
.decrypt = aes_decrypt,
}
static void aes_setiv(void *ctx __unused, const void *iv __unused)
Set initialisation vector.
Definition: aes.c:787
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:433
static void aes_encrypt(void *ctx, const void *src, void *dst, size_t len)
Encrypt data.
Definition: aes.c:397
#define AES_BLOCKSIZE
AES blocksize.
Definition: aes.h:15
static int aes_setkey(void *ctx, const void *key, size_t keylen)
Set key.
Definition: aes.c:680

Basic AES algorithm.

Definition at line 792 of file aes.c.

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