iPXE
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.
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.
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.
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.
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.
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.
static void aes_addroundkey (union aes_matrix *state, const union aes_matrix *key)
 Perform standalone AddRoundKey.
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.
static void aes_encrypt (struct cipher_algorithm *cipher __unused, void *ctx, const void *src, void *dst, size_t len)
 Encrypt data.
static void aes_decrypt (struct cipher_algorithm *cipher __unused, void *ctx, const void *src, void *dst, size_t len)
 Decrypt data.
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).
static void aes_mixcolumns_entry (union aes_table_entry *entry)
 Fill in MixColumns lookup table entry.
static void aes_invmixcolumns_entry (union aes_table_entry *entry)
 Fill in InvMixColumns lookup table entry.
static void aes_generate (void)
 Generate AES lookup tables.
static uint32_t aes_key_rotate (uint32_t column)
 Rotate key column.
static uint32_t aes_key_sbox (uint32_t column)
 Apply S-box to key column.
static uint32_t aes_key_rcon (uint32_t column, unsigned int rcon)
 Apply schedule round constant to key column.
static int aes_setkey (struct cipher_algorithm *cipher __unused, void *ctx, const void *key, size_t keylen)
 Set key.
 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.
static struct aes_table aes_invmixcolumns
 AES InvMixColumns lookup table.
struct cipher_algorithm aes_algorithm
 Basic AES algorithm.

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};
@ AES_STRIDE_SHIFTROWS
Input stride for ShiftRows.
Definition aes.c:61
@ AES_STRIDE_INVSHIFTROWS
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()

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 {
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}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
unsigned int uint32_t
Definition stdint.h:12
unsigned char uint8_t
Definition stdint.h:10
#define __attribute__(x)
Definition compiler.h:10
uint8_t product
Product string.
Definition smbios.h:5
unsigned char byte
Definition smc9000.h:38
#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

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

Referenced by aes_column().

◆ aes_column()

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}
__be32 in[4]
Definition CIB_PRM.h:7
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
uint16_t offset
Offset to command line.
Definition bzimage.h:3
struct ena_llq_option stride
Descriptor strides.
Definition ena.h:11
union aes_table_entry entry[256]
Table entries, indexed by S(N).
Definition aes.c:143
A single AES lookup table entry.
Definition aes.c:113

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

Referenced by aes_output().

◆ aes_output()

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}
union @162305117151260234136356364136041353210355154177 key
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

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

Referenced by aes_round().

◆ aes_round()

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}
__be32 out[4]
Definition CIB_PRM.h:8
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

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

Referenced by aes_decrypt_rounds(), and aes_encrypt_rounds().

◆ aes_encrypt_rounds()

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}
static struct aes_table aes_mixcolumns
AES MixColumns lookup table.
Definition aes.c:147
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
unsigned long tmp
Definition linux_pci.h:65
AES matrix.
Definition aes.h:22

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

Referenced by aes_encrypt().

◆ aes_decrypt_rounds()

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}
static struct aes_table aes_invmixcolumns
AES InvMixColumns lookup table.
Definition aes.c:150

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

Referenced by aes_decrypt(), and aes_setkey().

◆ aes_addroundkey()

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:36

References key, and state.

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

◆ aes_final()

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 */
389}
static void aes_addroundkey(union aes_matrix *state, const union aes_matrix *key)
Perform standalone AddRoundKey.
Definition aes.c:346

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

void aes_encrypt ( struct cipher_algorithm *cipher __unused,
void * ctx,
const void * src,
void * dst,
size_t len )
static

Encrypt data.

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

Definition at line 400 of file aes.c.

401 {
402 struct aes_context *aes = ctx;
403 union aes_matrix buffer[2];
404 union aes_matrix *in = &buffer[0];
405 union aes_matrix *out = &buffer[1];
406 unsigned int rounds = aes->rounds;
407
408 /* Sanity check */
409 assert ( len == sizeof ( *in ) );
410
411 /* Initialise input state */
412 memcpy ( in, src, sizeof ( *in ) );
413
414 /* Perform initial round (AddRoundKey) */
415 aes_addroundkey ( in, &aes->encrypt.key[0] );
416
417 /* Perform intermediate rounds (ShiftRows, SubBytes,
418 * MixColumns, AddRoundKey).
419 */
420 aes_encrypt_rounds ( in, out, &aes->encrypt.key[1], ( rounds - 2 ) );
421 in = out;
422
423 /* Perform final round (ShiftRows, SubBytes, AddRoundKey) */
424 out = dst;
426 &aes->encrypt.key[ rounds - 1 ] );
427}
struct golan_eq_context ctx
Definition CIB_PRM.h: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 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
static const void * src
Definition string.h:48
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
ring len
Length.
Definition dwmac.h:226
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER).
Definition netvsc.h:5
void * memcpy(void *dest, const void *src, size_t len) __nonnull
AES context.
Definition aes.h:36
unsigned int rounds
Number of rounds.
Definition aes.h:42
struct aes_round_keys encrypt
Encryption keys.
Definition aes.h:38
union aes_matrix key[AES_MAX_ROUNDS]
Round keys.
Definition aes.h:32

References __unused, 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()

void aes_decrypt ( struct cipher_algorithm *cipher __unused,
void * ctx,
const void * src,
void * dst,
size_t len )
static

Decrypt data.

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

Definition at line 438 of file aes.c.

439 {
440 struct aes_context *aes = ctx;
441 union aes_matrix buffer[2];
442 union aes_matrix *in = &buffer[0];
443 union aes_matrix *out = &buffer[1];
444 unsigned int rounds = aes->rounds;
445
446 /* Sanity check */
447 assert ( len == sizeof ( *in ) );
448
449 /* Initialise input state */
450 memcpy ( in, src, sizeof ( *in ) );
451
452 /* Perform initial round (AddRoundKey) */
453 aes_addroundkey ( in, &aes->decrypt.key[0] );
454
455 /* Perform intermediate rounds (InvShiftRows, InvSubBytes,
456 * InvMixColumns, AddRoundKey).
457 */
458 aes_decrypt_rounds ( in, out, &aes->decrypt.key[1], ( rounds - 2 ) );
459 in = out;
460
461 /* Perform final round (InvShiftRows, InvSubBytes, AddRoundKey) */
462 out = dst;
464 &aes->decrypt.key[ rounds - 1 ] );
465}
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
struct aes_round_keys decrypt
Decryption keys.
Definition aes.h:40

References __unused, 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()

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

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

References aes_double().

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

◆ aes_mixcolumns_entry()

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

498 {
499 unsigned int scalar_x_1;
500 unsigned int scalar_x;
501 unsigned int scalar;
502
503 /* Retrieve scalar multiplicand */
504 scalar = entry->byte[0];
505 entry->byte[1] = scalar;
506 entry->byte[2] = scalar;
507 entry->byte[5] = scalar;
508 entry->byte[6] = scalar;
509
510 /* Calculate scalar multiplied by (x) */
511 scalar_x = aes_double ( scalar );
512 entry->byte[4] = scalar_x;
513
514 /* Calculate scalar multiplied by (x + 1) */
515 scalar_x_1 = ( scalar_x ^ scalar );
516 entry->byte[3] = scalar_x_1;
517 entry->byte[7] = scalar_x_1;
518}
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:473

References aes_double(), and aes_table_entry::byte.

Referenced by aes_generate().

◆ aes_invmixcolumns_entry()

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

527 {
528 unsigned int scalar_x3_x2_x;
529 unsigned int scalar_x3_x2_1;
530 unsigned int scalar_x3_x2;
531 unsigned int scalar_x3_x_1;
532 unsigned int scalar_x3_1;
533 unsigned int scalar_x3;
534 unsigned int scalar_x2;
535 unsigned int scalar_x;
536 unsigned int scalar;
537
538 /* Retrieve scalar multiplicand */
539 scalar = entry->byte[0];
540
541 /* Calculate scalar multiplied by (x) */
542 scalar_x = aes_double ( scalar );
543
544 /* Calculate scalar multiplied by (x^2) */
545 scalar_x2 = aes_double ( scalar_x );
546
547 /* Calculate scalar multiplied by (x^3) */
548 scalar_x3 = aes_double ( scalar_x2 );
549
550 /* Calculate scalar multiplied by (x^3 + 1) */
551 scalar_x3_1 = ( scalar_x3 ^ scalar );
552 entry->byte[1] = scalar_x3_1;
553 entry->byte[5] = scalar_x3_1;
554
555 /* Calculate scalar multiplied by (x^3 + x + 1) */
556 scalar_x3_x_1 = ( scalar_x3_1 ^ scalar_x );
557 entry->byte[3] = scalar_x3_x_1;
558 entry->byte[7] = scalar_x3_x_1;
559
560 /* Calculate scalar multiplied by (x^3 + x^2) */
561 scalar_x3_x2 = ( scalar_x3 ^ scalar_x2 );
562
563 /* Calculate scalar multiplied by (x^3 + x^2 + 1) */
564 scalar_x3_x2_1 = ( scalar_x3_x2 ^ scalar );
565 entry->byte[2] = scalar_x3_x2_1;
566 entry->byte[6] = scalar_x3_x2_1;
567
568 /* Calculate scalar multiplied by (x^3 + x^2 + x) */
569 scalar_x3_x2_x = ( scalar_x3_x2 ^ scalar_x );
570 entry->byte[4] = scalar_x3_x2_x;
571}

References aes_double(), and aes_table_entry::byte.

Referenced by aes_generate().

◆ aes_generate()

void aes_generate ( void )
static

Generate AES lookup tables.

Definition at line 577 of file aes.c.

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

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

Referenced by aes_setkey().

◆ aes_key_rotate()

uint32_t aes_key_rotate ( uint32_t column)
inlinestatic

Rotate key column.

Parameters
columnKey column
Return values
columnUpdated key column

Definition at line 639 of file aes.c.

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

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

Referenced by aes_setkey().

◆ aes_key_sbox()

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

651 {
652 unsigned int i;
654
655 for ( i = 0 ; i < 4 ; i++ ) {
656 byte = ( column & 0xff );
657 byte = aes_mixcolumns.entry[byte].byte[0];
658 column = ( ( column & ~0xff ) | byte );
659 column = rol32 ( column, 8 );
660 }
661 return column;
662}

References aes_mixcolumns, and rol32().

Referenced by aes_setkey().

◆ aes_key_rcon()

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

672 {
673
674 return ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ?
675 ( column ^ rcon ) : ( column ^ ( rcon << 24 ) ) );
676}

References __BYTE_ORDER, and __LITTLE_ENDIAN.

Referenced by aes_setkey().

◆ aes_setkey()

int aes_setkey ( struct cipher_algorithm *cipher __unused,
void * ctx,
const void * key,
size_t keylen )
static

Set key.

Parameters
cipherCipher algorithm
ctxContext
keyKey
keylenKey length
Return values
rcReturn status code

Definition at line 687 of file aes.c.

688 {
689 struct aes_context *aes = ctx;
690 union aes_matrix *enc;
691 union aes_matrix *dec;
692 union aes_matrix temp;
693 union aes_matrix zero;
694 unsigned int rcon = 0x01;
695 unsigned int rounds;
696 size_t offset = 0;
697 uint32_t *prev;
698 uint32_t *next;
699 uint32_t *end;
701
702 /* Generate lookup tables, if not already done */
703 if ( ! aes_mixcolumns.entry[0].byte[0] )
704 aes_generate();
705
706 /* Validate key length and calculate number of intermediate rounds */
707 switch ( keylen ) {
708 case ( 128 / 8 ) :
709 rounds = 11;
710 break;
711 case ( 192 / 8 ) :
712 rounds = 13;
713 break;
714 case ( 256 / 8 ) :
715 rounds = 15;
716 break;
717 default:
718 DBGC ( aes, "AES %p unsupported key length (%zd bits)\n",
719 aes, ( keylen * 8 ) );
720 return -EINVAL;
721 }
722 aes->rounds = rounds;
723 enc = aes->encrypt.key;
724 end = enc[rounds].column;
725
726 /* Copy raw key */
727 memcpy ( enc, key, keylen );
728 prev = enc->column;
729 next = ( ( ( void * ) prev ) + keylen );
730 tmp = next[-1];
731
732 /* Construct expanded key */
733 while ( next < end ) {
734
735 /* If this is the first column of an expanded key
736 * block, or the middle column of an AES-256 key
737 * block, then apply the S-box.
738 */
739 if ( ( offset == 0 ) || ( ( offset | keylen ) == 48 ) )
740 tmp = aes_key_sbox ( tmp );
741
742 /* If this is the first column of an expanded key
743 * block then rotate and apply the round constant.
744 */
745 if ( offset == 0 ) {
746 tmp = aes_key_rotate ( tmp );
747 tmp = aes_key_rcon ( tmp, rcon );
748 rcon = aes_double ( rcon );
749 }
750
751 /* XOR with previous key column */
752 tmp ^= *prev;
753
754 /* Store column */
755 *next = tmp;
756
757 /* Move to next column */
758 offset += sizeof ( *next );
759 if ( offset == keylen )
760 offset = 0;
761 next++;
762 prev++;
763 }
764 DBGC2 ( aes, "AES %p expanded %zd-bit key:\n", aes, ( keylen * 8 ) );
765 DBGC2_HDA ( aes, 0, &aes->encrypt, ( rounds * sizeof ( *enc ) ) );
766
767 /* Convert to decryption key */
768 memset ( &zero, 0, sizeof ( zero ) );
769 dec = &aes->decrypt.key[ rounds - 1 ];
770 memcpy ( dec--, enc++, sizeof ( *dec ) );
771 while ( dec > aes->decrypt.key ) {
772 /* Perform InvMixColumns (by reusing the encryption
773 * final-round code to perform ShiftRows+SubBytes and
774 * reusing the decryption intermediate-round code to
775 * perform InvShiftRows+InvSubBytes+InvMixColumns, all
776 * with a zero encryption key).
777 */
779 enc++, &temp, &zero );
780 aes_decrypt_rounds ( &temp, dec--, &zero, 1 );
781 }
782 memcpy ( dec--, enc++, sizeof ( *dec ) );
783 DBGC2 ( aes, "AES %p inverted %zd-bit key:\n", aes, ( keylen * 8 ) );
784 DBGC2_HDA ( aes, 0, &aes->decrypt, ( rounds * sizeof ( *dec ) ) );
785
786 return 0;
787}
static uint32_t aes_key_sbox(uint32_t column)
Apply S-box to key column.
Definition aes.c:651
static void aes_generate(void)
Generate AES lookup tables.
Definition aes.c:577
static uint32_t aes_key_rcon(uint32_t column, unsigned int rcon)
Apply schedule round constant to key column.
Definition aes.c:672
static uint32_t aes_key_rotate(uint32_t column)
Rotate key column.
Definition aes.c:639
uint32_t next
Next descriptor address.
Definition dwmac.h:11
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
#define DBGC(...)
Definition compiler.h:530
#define EINVAL
Invalid argument.
Definition errno.h:472
void * memset(void *dest, int character, size_t len) __nonnull
uint32_t end
Ending offset.
Definition netvsc.h:7
uint32_t column[4]
Viewed as an array of four-byte columns.
Definition aes.h:26

References __unused, aes_decrypt_rounds(), aes_double(), aes_final(), aes_generate(), aes_key_rcon(), aes_key_rotate(), aes_key_sbox(), aes_mixcolumns, AES_STRIDE_SHIFTROWS, aes_matrix::column, ctx, DBGC, DBGC2, DBGC2_HDA, aes_context::decrypt, EINVAL, aes_context::encrypt, end, 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,
.confidential = 1,
.setkey = aes_setkey,
.encrypt = aes_encrypt,
.decrypt = aes_decrypt,
}
static void aes_encrypt(struct cipher_algorithm *cipher __unused, void *ctx, const void *src, void *dst, size_t len)
Encrypt data.
Definition aes.c:400
static void aes_decrypt(struct cipher_algorithm *cipher __unused, void *ctx, const void *src, void *dst, size_t len)
Decrypt data.
Definition aes.c:438
static int aes_setkey(struct cipher_algorithm *cipher __unused, void *ctx, const void *key, size_t keylen)
Set key.
Definition aes.c:687
#define AES_BLOCKSIZE
AES blocksize.
Definition aes.h:16
int cipher_null_setiv(struct cipher_algorithm *cipher __unused, void *ctx __unused, const void *iv __unused, size_t ivlen __unused)
Definition crypto_null.c:70
void cipher_null_auth(struct cipher_algorithm *cipher __unused, void *ctx __unused, void *auth __unused)
Definition crypto_null.c:89

Basic AES algorithm.

Definition at line 790 of file aes.c.

790 {
791 .name = "aes",
792 .ctxsize = sizeof ( struct aes_context ),
793 .blocksize = AES_BLOCKSIZE,
794 .alignsize = 0,
795 .authsize = 0,
796 .confidential = 1,
797 .setkey = aes_setkey,
798 .setiv = cipher_null_setiv,
799 .encrypt = aes_encrypt,
800 .decrypt = aes_decrypt,
801 .auth = cipher_null_auth,
802};

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