0% found this document useful (0 votes)
101 views24 pages

Aes Algorithm CBC Mode Source Code:: Roll No:17Mci0021 Name: Bhanu Tejayada

The document contains C source code for implementing AES encryption and decryption in both ECB and CBC modes using 128-bit keys. It includes function definitions for AES_ECB_encrypt, AES_ECB_decrypt, AES_CBC_encrypt_buffer, and AES_CBC_decrypt_buffer. It also contains AES algorithm details like the key schedule, S-box, Rcon values, and AES block/key sizes.

Uploaded by

Akhil Venkata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
101 views24 pages

Aes Algorithm CBC Mode Source Code:: Roll No:17Mci0021 Name: Bhanu Tejayada

The document contains C source code for implementing AES encryption and decryption in both ECB and CBC modes using 128-bit keys. It includes function definitions for AES_ECB_encrypt, AES_ECB_decrypt, AES_CBC_encrypt_buffer, and AES_CBC_decrypt_buffer. It also contains AES algorithm details like the key schedule, S-box, Rcon values, and AES block/key sizes.

Uploaded by

Akhil Venkata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 24

Roll No:17MCI0021

Name: Bhanu TejaYada

AES Algorithm CBC Mode


Source Code:
#ifndef _AES_H_

#define _AES_H_

#include <stdint.h>

#ifndef CBC

#define CBC 1

#endif

#ifndef ECB

#define ECB 1

#endif

#define AES128 1

#if defined(ECB) && (ECB == 1)

void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const

uint32_t length);

void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const

uint32_t length);

#endif // #if defined(ECB) && (ECB == !)

#if defined(CBC) && (CBC == 1)

void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const

uint8_t* key, const uint8_t* iv);

void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const

uint8_t* key, const uint8_t* iv);

#endif // #if defined(CBC) && (CBC == 1)

#endif //_AES_H_

#include <stdint.h>

#include <string.h> // CBC mode, for memset


#include "aes.h"

Value=4

#define Nb 4

#define BLOCKLEN 16 //Block length in bytes AES is 128b block only

#if defined(AES256) && (AES256 == 1)

#define Nk 8

#define KEYLEN 32

#define Nr 14

#define keyExpSize 240

#elif defined(AES192) && (AES192 == 1)

#define Nk 6

#define KEYLEN 24

#define Nr 12

#define keyExpSize 208

#else

#define Nk 4 // The number of 32 bit words in a key.

#define KEYLEN 16 // Key length in bytes

#define Nr 10 // The number of rounds in AES Cipher.

#define keyExpSize 176

#endif

#ifndef MULTIPLY_AS_A_FUNCTION

#define MULTIPLY_AS_A_FUNCTION 0

#endif

typedef uint8_t state_t[4][4];

static state_t* state;

static uint8_t RoundKey[keyExpSize];

static const uint8_t* Key;

#if defined(CBC) && CBC

// Initial Vector used only for CBC mode

static uint8_t* Iv;

#endif
static const uint8_t sbox[256] = {

//0 1 2 3 4 5 6 7 8 9 A B C D E F

0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,

0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,0xd0,
0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,

0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16

};

static const uint8_t rsbox[256] = {

0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,

0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,

0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,

0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1,

0x25,

0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,

0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,

0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,

0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,

0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,

0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,

0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,

0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,

0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,0xa0,
0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,

0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d

};

static const uint8_t Rcon[11] = {

0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };

#if 0

static const uint8_t Rcon[256] = {

0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,

0x9a,

0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,

0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,

0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,

0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,

0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,

0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,

0x1b,

0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,

0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,

0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,

0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,

0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,

0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,

0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,

0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,

0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d

};

#endif
static uint8_t getSBoxValue(uint8_t num)

return sbox[num];

static uint8_t getSBoxInvert(uint8_t num)

return rsbox[num];

static void KeyExpansion(void)

uint32_t i, k;

uint8_t tempa[4]; // Used for the column/row operations

for (i = 0; i < Nk; ++i)

RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];

RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];

RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];

RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];

//i == Nk

for (; i < Nb * (Nr + 1); ++i)

tempa[0]=RoundKey[(i-1) * 4 + 0];

tempa[1]=RoundKey[(i-1) * 4 + 1];

tempa[2]=RoundKey[(i-1) * 4 + 2];

tempa[3]=RoundKey[(i-1) * 4 + 3];

if (i % Nk == 0)

{
// Function RotWord()

k = tempa[0];

tempa[0] = tempa[1];

tempa[1] = tempa[2];

tempa[2] = tempa[3];

tempa[3] = k;

// Function Subword()

tempa[0] = getSBoxValue(tempa[0]);

tempa[1] = getSBoxValue(tempa[1]);

tempa[2] = getSBoxValue(tempa[2]);

tempa[3] = getSBoxValue(tempa[3]);

tempa[0] = tempa[0] ^ Rcon[i/Nk];

#if defined(AES256) && (AES256 == 1)

if (i % Nk == 4)

// Function Subword()

tempa[0] = getSBoxValue(tempa[0]);

tempa[1] = getSBoxValue(tempa[1]);

tempa[2] = getSBoxValue(tempa[2]);

tempa[3] = getSBoxValue(tempa[3]);

#endif

RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0];

RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1];


RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2];

RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3];

static void AddRoundKey(uint8_t round)

uint8_t i,j;

for (i=0;i<4;++i)

for (j = 0; j < 4; ++j)

(*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j];

static void SubBytes(void)

uint8_t i, j;

for (i = 0; i < 4; ++i)

for (j = 0; j < 4; ++j)

(*state)[j][i] = getSBoxValue((*state)[j][i]);

static void ShiftRows(void)

uint8_t temp;

temp = (*state)[0][1];

(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];

(*state)[2][1] = (*state)[3][1];

(*state)[3][1] = temp;

temp = (*state)[0][2];

(*state)[0][2] = (*state)[2][2];

(*state)[2][2] = temp;

temp = (*state)[1][2];

(*state)[1][2] = (*state)[3][2];

(*state)[3][2] = temp;

temp = (*state)[0][3];

(*state)[0][3] = (*state)[3][3];

(*state)[3][3] = (*state)[2][3];

(*state)[2][3] = (*state)[1][3];

(*state)[1][3] = temp;

static uint8_t xtime(uint8_t x)

return ((x<<1) ^ (((x>>7) & 1) * 0x1b));

static void MixColumns(void)

uint8_t i;

uint8_t Tmp,Tm,t;

for (i = 0; i < 4; ++i)

t = (*state)[i][0];

Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;

Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;

Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;

Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;

Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;


}

#if MULTIPLY_AS_A_FUNCTION

static uint8_t Multiply(uint8_t x, uint8_t y)

return (((y & 1) * x) ^

((y>>1 & 1) * xtime(x)) ^

((y>>2 & 1) * xtime(xtime(x))) ^

((y>>3 & 1) * xtime(xtime(xtime(x)))) ^

((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))));

#else

#define Multiply(x, y) \

( ((y & 1) * x) ^ \

((y>>1 & 1) * xtime(x)) ^ \

((y>>2 & 1) * xtime(xtime(x))) ^ \

((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \

((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \

#endif

static void InvMixColumns(void)

int i;

uint8_t a, b, c, d;

for (i = 0; i < 4; ++i)

a = (*state)[i][0];

b = (*state)[i][1];

c = (*state)[i][2];

d = (*state)[i][3];

(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);

(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);


(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);

(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);

static void InvSubBytes(void)

uint8_t i,j;

for (i = 0; i < 4; ++i)

for (j = 0; j < 4; ++j)

(*state)[j][i] = getSBoxInvert((*state)[j][i]);

static void InvShiftRows(void)

uint8_t temp;

temp = (*state)[3][1];

(*state)[3][1] = (*state)[2][1];

(*state)[2][1] = (*state)[1][1];

(*state)[1][1] = (*state)[0][1];

(*state)[0][1] = temp;

temp = (*state)[0][2];

(*state)[0][2] = (*state)[2][2];

(*state)[2][2] = temp;

temp = (*state)[1][2];

(*state)[1][2] = (*state)[3][2];

(*state)[3][2] = temp;

temp = (*state)[0][3];

(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];

(*state)[2][3] = (*state)[3][3];

(*state)[3][3] = temp;

static void Cipher(void)

uint8_t round = 0;

AddRoundKey(0);

for (round = 1; round < Nr; ++round)

SubBytes();

ShiftRows();

MixColumns();

AddRoundKey(round);

SubBytes();

ShiftRows();

AddRoundKey(Nr);

static void InvCipher(void)

uint8_t round=0;

AddRoundKey(Nr);

for (round = (Nr - 1); round > 0; --round)

InvShiftRows();

InvSubBytes();

AddRoundKey(round);

InvMixColumns();

InvShiftRows();
InvSubBytes();

AddRoundKey(0);

#if defined(ECB) && (ECB == 1)

void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t* output, const uint32_t

length)

memcpy(output, input, length);

state = (state_t*)output;

Key = key;

KeyExpansion();

Cipher();

void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t

length)

// Copy input to output, and work in-memory on output

memcpy(output, input, length);

state = (state_t*)output;

// The KeyExpansion routine must be called before encryption.

Key = key;

KeyExpansion();

InvCipher();

#endif // #if defined(ECB) && (ECB == 1)

#if defined(CBC) && (CBC == 1)

static void XorWithIv(uint8_t* buf)

uint8_t i;

for (i = 0; i < BLOCKLEN; ++i) //WAS for(i = 0; i < KEYLEN; ++i) but the block in AES is always
128bit so 16 bytes!

buf[i] ^= Iv[i];

void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t*

key, const uint8_t* iv)

uintptr_t i;

uint8_t extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */

if (0 != key)

Key = key;

KeyExpansion();

if (iv != 0)

Iv = (uint8_t*)iv;

for (i = 0; i < length; i += BLOCKLEN)

XorWithIv(input);

memcpy(output, input, BLOCKLEN);

state = (state_t*)output;

Cipher();

Iv = output;

input += BLOCKLEN;

output += BLOCKLEN;

//printf("Step %d - %d", i/16, i);

if (extra)
{

memcpy(output, input, extra);

state = (state_t*)output;

Cipher();

void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t*

key, const uint8_t* iv)

uintptr_t i;

uint8_t extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */

if (0 != key)

Key = key;

KeyExpansion();

if (iv != 0)

Iv = (uint8_t*)iv;

for (i = 0; i < length; i += BLOCKLEN)

memcpy(output, input, BLOCKLEN);

state = (state_t*)output;

InvCipher();

XorWithIv(output);

Iv = input;

input += BLOCKLEN;

output += BLOCKLEN;

if (extra)
{

memcpy(output, input, extra);

state = (state_t*)output;

InvCipher();

#endif // #if defined(CBC) && (CBC == 1)

static void phex(uint8_t* str);

static void test_encrypt_ecb(void);

static void test_decrypt_ecb(void);

static void test_encrypt_ecb_verbose(void);

static void test_encrypt_cbc(void);

static void test_decrypt_cbc(void);

int main(void)

#ifdef AES128

printf("\nTesting AES128\n\n");

#elif defined(AES192)

printf("\nTesting AES192\n\n");

#elif defined(AES256)

printf("\nTesting AES256\n\n");

#else

printf("You need to specify a symbol between AES128, AES192 or AES256. Exiting");

return 0;

#endif

test_encrypt_cbc();

test_decrypt_cbc();

test_decrypt_ecb();

test_encrypt_ecb();

test_encrypt_ecb_verbose();

return 0;
}

// prints string as hex

static void phex(uint8_t* str)

#ifdef AES128

uint8_t len = 16;

#elif defined(AES192)

uint8_t len = 24;

#elif defined(AES256)

uint8_t len = 32;

#endif

unsigned char i;

for(i = 0; i < len; ++i)

printf("%.2x", str[i]);

printf("\n");

static void test_encrypt_ecb_verbose(void)

uint8_t i, buf[64], buf2[64];

uint8_t key[16] = { (uint8_t) 0x2b, (uint8_t) 0x7e, (uint8_t) 0x15, (uint8_t) 0x16, (uint8_t)

0x28, (uint8_t) 0xae, (uint8_t) 0xd2, (uint8_t) 0xa6, (uint8_t) 0xab, (uint8_t) 0xf7, (uint8_t)

0x15, (uint8_t) 0x88, (uint8_t) 0x09, (uint8_t) 0xcf, (uint8_t) 0x4f, (uint8_t) 0x3c };

uint8_t plain_text[64] = { (uint8_t) 0x6b, (uint8_t) 0xc1, (uint8_t) 0xbe, (uint8_t) 0xe2,

(uint8_t) 0x2e, (uint8_t) 0x40, (uint8_t) 0x9f, (uint8_t) 0x96, (uint8_t) 0xe9, (uint8_t) 0x3d,

(uint8_t) 0x7e, (uint8_t) 0x11, (uint8_t) 0x73, (uint8_t) 0x93, (uint8_t) 0x17, (uint8_t) 0x2a,

(uint8_t) 0xae, (uint8_t) 0x2d, (uint8_t) 0x8a, (uint8_t) 0x57, (uint8_t) 0x1e,

(uint8_t) 0x03, (uint8_t) 0xac, (uint8_t) 0x9c, (uint8_t) 0x9e, (uint8_t) 0xb7, (uint8_t) 0x6f,

(uint8_t) 0xac, (uint8_t) 0x45, (uint8_t) 0xaf, (uint8_t) 0x8e, (uint8_t) 0x51,

(uint8_t) 0x30, (uint8_t) 0xc8, (uint8_t) 0x1c, (uint8_t) 0x46, (uint8_t) 0xa3,

(uint8_t) 0x5c, (uint8_t) 0xe4, (uint8_t) 0x11, (uint8_t) 0xe5, (uint8_t) 0xfb, (uint8_t) 0xc1,

(uint8_t) 0x19, (uint8_t) 0x1a, (uint8_t) 0x0a, (uint8_t) 0x52, (uint8_t) 0xef,
(uint8_t) 0xf6, (uint8_t) 0x9f, (uint8_t) 0x24, (uint8_t) 0x45, (uint8_t) 0xdf,

(uint8_t) 0x4f, (uint8_t) 0x9b, (uint8_t) 0x17, (uint8_t) 0xad, (uint8_t) 0x2b, (uint8_t) 0x41,

(uint8_t) 0x7b, (uint8_t) 0xe6, (uint8_t) 0x6c, (uint8_t) 0x37, (uint8_t) 0x10 };

memset(buf, 0, 64);

memset(buf2, 0, 64);

printf("ECB encrypt verbose:\n\n");

printf("plain text:\n");

for(i = (uint8_t) 0; i < (uint8_t) 4; ++i)

phex(plain_text + i * (uint8_t) 16);

printf("\n");

printf("key:\n");

phex(key);

printf("\n");

printf("ciphertext:\n");

for(i = 0; i < 4; ++i)

AES_ECB_encrypt(plain_text + (i*16), key, buf+(i*16), 16);

phex(buf + (i*16));

printf("\n");

static void test_encrypt_ecb(void)

#ifdef AES128

uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09,

0xcf, 0x4f, 0x3c};

uint8_t out[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24,

0x66, 0xef, 0x97};

#elif defined(AES192)
uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80,

0x90, 0x79, 0xe5,0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b};

uint8_t out[] = { 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57,

0x1f, 0xa5, 0xcc };

#elif defined(AES256)

uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85,

0x7d, 0x77, 0x81,

0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,

0xdf, 0xf4 };

uint8_t out[] = { 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d,

0xb1, 0x81, 0xf8 };

#endif

uint8_t in[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73,

0x93, 0x17, 0x2a};

uint8_t buffer[16];

AES_ECB_encrypt(in, key, buffer, 16);

printf("ECB encrypt: ");

if(0 == memcmp((char*) out, (char*) buffer, 16))

printf("SUCCESS!\n");

else

printf("FAILURE!\n");

static void test_decrypt_cbc(void)

#ifdef AES128

uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09,

0xcf, 0x4f, 0x3c };


uint8_t in[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12,

0xe9, 0x19, 0x7d,

0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76,

0x78, 0xb2,

0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22,

0x95, 0x16,

0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86,

0xe1, 0xa7 };

#elif defined(AES192)

uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80,

0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b};

uint8_t in[] = { 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f,

0xa0, 0x71, 0xe8,

0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69,

0x14, 0x5a,

0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1,

0x02, 0xe0,

0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56,

0x15, 0xcd };

#elif defined(AES256)

uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85,

0x7d, 0x77, 0x81,

0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,

0xdf, 0xf4 };

uint8_t in[] = { 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f,

0x7b, 0xfb, 0xd6,

0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70,

0x2c, 0x7d,

0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23,

0x14, 0x61,

0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a,
0x9d, 0x1b };

#endif

uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,

0x0d, 0x0e, 0x0f };

uint8_t out[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73,

0x93, 0x17, 0x2a,

0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf,

0x8e, 0x51,

0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a,

0x52, 0xef,

0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c,

0x37, 0x10 };

uint8_t buffer[64];

AES_CBC_decrypt_buffer(buffer, in, 64, key, iv);

printf("CBC decrypt: ");

if(0 == memcmp((char*) out, (char*) buffer, 64))

printf("SUCCESS!\n");

else

printf("FAILURE!\n");

static void test_encrypt_cbc(void)

#ifdef AES128

uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09,

0xcf, 0x4f, 0x3c };

uint8_t out[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12,

0xe9, 0x19, 0x7d,


0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76,

0x78, 0xb2,

0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22,

0x95, 0x16,

0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86,

0xe1, 0xa7 };

#elif defined(AES192)

uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80,

0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b};

uint8_t out[] = { 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f,

0xa0, 0x71, 0xe8,

0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69,

0x14, 0x5a,

0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1,

0x02, 0xe0,

0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56,

0x15, 0xcd };

#elif defined(AES256)

uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85,

0x7d, 0x77, 0x81,

0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,

0xdf, 0xf4 };

uint8_t out[] = { 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f,

0x7b, 0xfb, 0xd6,

0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70,

0x2c, 0x7d,

0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23,

0x14, 0x61,

0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a,

0x9d, 0x1b };

#endif
uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,

0x0d, 0x0e, 0x0f };

uint8_t in[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73,

0x93, 0x17, 0x2a,

0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf,

0x8e, 0x51,

0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a,

0x52, 0xef,

0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c,

0x37, 0x10 };

uint8_t buffer[64];

AES_CBC_encrypt_buffer(buffer, in, 64, key, iv);

printf("CBC encrypt: ");

if(0 == memcmp((char*) out, (char*) buffer, 64))

printf("SUCCESS!\n");

else

printf("FAILURE!\n");

static void test_decrypt_ecb(void)

#ifdef AES128

uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09,

0xcf, 0x4f, 0x3c};

uint8_t in[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24,

0x66, 0xef, 0x97};

#elif defined(AES192)

uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80,
0x90, 0x79, 0xe5,

0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b};

uint8_t in[] = { 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57,

0x1f, 0xa5, 0xcc };

#elif defined(AES256)

uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85,

0x7d, 0x77, 0x81,

0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,

0xdf, 0xf4 };

uint8_t in[] = { 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d,

0xb1, 0x81, 0xf8 };

#endif

uint8_t out[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73,

0x93, 0x17, 0x2a};

uint8_t buffer[16];

AES_ECB_decrypt(in, key, buffer, 16);

printf("ECB decrypt: ");

if(0 == memcmp((char*) out, (char*) buffer, 16))

printf("SUCCESS!\n");

else

printf("FAILURE!\n");

}
OUTPUT:

You might also like