1#include "key_expansion.h"2 3#define Nb 44#define Nk 45#define Nr 106 7extern uint8_t sbox[256];8extern int rcon[Nr + 1];9 10#define get_sbox_value(num) (sbox[(num)])11 12void key_expansion(uint8_t* round_key, const uint8_t* key) {13 unsigned i, j, k;14 uint8_t tempa[4];15 16 for (i = 0; i < Nk; ++i) {17 round_key[(i * 4) + 0] = key[(i * 4) + 0];18 round_key[(i * 4) + 1] = key[(i * 4) + 1];19 round_key[(i * 4) + 2] = key[(i * 4) + 2];20 round_key[(i * 4) + 3] = key[(i * 4) + 3];21 }22 23 for (i = Nk; i < Nb * (Nr + 1); ++i) {24 {25 k = (i - 1) * 4;26 tempa[0] = round_key[k + 0];27 tempa[1] = round_key[k + 1];28 tempa[2] = round_key[k + 2];29 tempa[3] = round_key[k + 3];30 }31 32 if (i % Nk == 0) {33 // Function RotWord()34 {35 const uint8_t u8tmp = tempa[0];36 tempa[0] = tempa[1];37 tempa[1] = tempa[2];38 tempa[2] = tempa[3];39 tempa[3] = u8tmp;40 }41 42 // Function Subword()43 {44 tempa[0] = get_sbox_value(tempa[0]);45 tempa[1] = get_sbox_value(tempa[1]);46 tempa[2] = get_sbox_value(tempa[2]);47 tempa[3] = get_sbox_value(tempa[3]);48 }49 50 tempa[0] = tempa[0] ^ rcon[i / Nk];51 }52 53 j = i * 4;54 k = (i - Nk) * 4;55 round_key[j + 0] = round_key[k + 0] ^ tempa[0];56 round_key[j + 1] = round_key[k + 1] ^ tempa[1];57 round_key[j + 2] = round_key[k + 2] ^ tempa[2];58 round_key[j + 3] = round_key[k + 3] ^ tempa[3];59 }60}
1#ifndef _KEY_EXPANSION_H_2#define _KEY_EXPANSION_H_3 4#include <stdint.h>5 6void key_expansion(uint8_t* round_key, const uint8_t* key);7 8#endif // _KEY_EXPANSION_H_
1#include <stdio.h>2#include <string.h>3 4#include "key_expansion.h"5#include "rcon.h"6#include "sbox.h"7 8#define Nb 49#define Nk 410#define Nr 1011 12static const uint8_t test_key[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE,13 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88,14 0x09, 0xCF, 0x4F, 0x3C};15static const uint8_t test_round_key[176] = {16 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88,17 0x09, 0xCF, 0x4F, 0x3C, 0xA0, 0xFA, 0xFE, 0x17, 0x88, 0x54, 0x2C, 0xB1,18 0x23, 0xA3, 0x39, 0x39, 0x2A, 0x6C, 0x76, 0x05, 0xF2, 0xC2, 0x95, 0xF2,19 0x7A, 0x96, 0xB9, 0x43, 0x59, 0x35, 0x80, 0x7A, 0x73, 0x59, 0xF6, 0x7F,20 0x3D, 0x80, 0x47, 0x7D, 0x47, 0x16, 0xFE, 0x3E, 0x1E, 0x23, 0x7E, 0x44,21 0x6D, 0x7A, 0x88, 0x3B, 0xEF, 0x44, 0xA5, 0x41, 0xA8, 0x52, 0x5B, 0x7F,22 0xB6, 0x71, 0x25, 0x3B, 0xDB, 0x0B, 0xAD, 0x00, 0xD4, 0xD1, 0xC6, 0xF8,23 0x7C, 0x83, 0x9D, 0x87, 0xCA, 0xF2, 0xB8, 0xBC, 0x11, 0xF9, 0x15, 0xBC,24 0x6D, 0x88, 0xA3, 0x7A, 0x11, 0x0B, 0x3E, 0xFD, 0xDB, 0xF9, 0x86, 0x41,25 0xCA, 0x00, 0x93, 0xFD, 0x4E, 0x54, 0xF7, 0x0E, 0x5F, 0x5F, 0xC9, 0xF3,26 0x84, 0xA6, 0x4F, 0xB2, 0x4E, 0xA6, 0xDC, 0x4F, 0xEA, 0xD2, 0x73, 0x21,27 0xB5, 0x8D, 0xBA, 0xD2, 0x31, 0x2B, 0xF5, 0x60, 0x7F, 0x8D, 0x29, 0x2F,28 0xAC, 0x77, 0x66, 0xF3, 0x19, 0xFA, 0xDC, 0x21, 0x28, 0xD1, 0x29, 0x41,29 0x57, 0x5C, 0x00, 0x6E, 0xD0, 0x14, 0xF9, 0xA8, 0xC9, 0xEE, 0x25, 0x89,30 0xE1, 0x3F, 0x0C, 0xC8, 0xB6, 0x63, 0x0C, 0xA6};31 32extern uint8_t sbox[256];33extern int rcon[Nr + 1];34 35static int test_key_expansion(void);36 37int main(void) {38 int exit;39 40 int num_rounds = Nr + 1;41 initialize_aes_sbox(sbox);42 calculate_rcon(num_rounds, rcon);43 44 exit = test_key_expansion();45 46 return exit;47}48 49static int test_key_expansion(void) {50 uint8_t out[176];51 52 key_expansion(out, test_key);53 54 printf("AES KeyExpansion test: ");55 56 if (0 == memcmp((char*)out, (char*)test_round_key, sizeof test_round_key)) {57 printf("SUCCESS!\n");58 return (0);59 } else {60 printf("FAILURE!\n");61 return (1);62 }63}
1#include "sbox.h"2 3uint8_t sbox[256];4uint8_t inv_sbox[256];5 6#define ROTL8(x, shift) ((uint8_t)((x) << (shift)) | ((x) >> (8 - (shift))))7 8void initialize_aes_sbox(uint8_t sbox[256]) {9 uint8_t p = 1, q = 1;10 11 do {12 p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0);13 14 q ^= q << 1;15 q ^= q << 2;16 q ^= q << 4;17 q ^= q & 0x80 ? 0x09 : 0;18 19 uint8_t xformed =20 q ^ ROTL8(q, 1) ^ ROTL8(q, 2) ^ ROTL8(q, 3) ^ ROTL8(q, 4);21 22 sbox[p] = xformed ^ 0x63;23 } while (p != 1);24 25 sbox[0] = 0x63;26}27 28void initialize_inverse_aes_sbox(uint8_t inv_sbox[256],29 const uint8_t sbox[256]) {30 for (int i = 0; i < 256; i++) {31 inv_sbox[sbox[i]] = i;32 }33}
1#ifndef _SBOX_H_2#define _SBOX_H_3 4#include <stdint.h>5 6void initialize_aes_sbox(uint8_t sbox[256]);7void initialize_inverse_aes_sbox(uint8_t inv_sbox[256],8 const uint8_t sbox[256]);9 10#endif // _SBOX_H_
1#define Nr 102 3int rcon[Nr + 1];4 5void calculate_rcon(int num_rounds, int* rcon) {6 rcon[0] = 0x8d;7 for (int i = 1; i < num_rounds; ++i) {8 rcon[i] = rcon[i - 1] << 1;9 if (rcon[i] & 0x100) {10 rcon[i] ^= 0x11B;11 }12 }13}
1#ifndef _RCON_H_2#define _RCON_H_3 4void calculate_rcon(int num_rounds, int* rcon);5 6#endif // _RCON_H_
gcc key_expansion.c test_key_expansion.c sbox.c rcon.c && ./a.out
AES KeyExpansion test: SUCCESS!