comparison aes.c @ 10:439b7aaaec9e

Get aes from avr231 appnote instead
author Matt Johnston <matt@ucc.asn.au>
date Wed, 12 Jun 2013 22:57:44 +0800
parents 87c8d0a11906
children
comparison
equal deleted inserted replaced
9:3aa92c7f379c 10:439b7aaaec9e
1 // advanced encryption standard 1 #include "aes.h"
2 // Original author: Karl Malbrain, [email protected] 2 //#include "loader.h"
3 // Ported to Atmel AVR by: Jiri Pittner, [email protected]
4 // 3 //
5 /* 4 #define KEY_COUNT 1
6 This work, including the source code, documentation 5
7 and related data, is placed into the public domain. 6 #if KEY_COUNT > 0
8 7
9 The original author is Karl Malbrain. 8 //#include "aeskeys.inc"
10 9
11 THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY 10
12 OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF 11
13 MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, 12
14 ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE 13 typedef unsigned char byte;
15 RESULTING FROM THE USE, MODIFICATION, OR 14
16 REDISTRIBUTION OF THIS SOFTWARE. 15
17 */ 16
18 17 #define BPOLY 0x1b //!< Lower 8 bits of (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1).
19 #include <stdlib.h> 18 #define BLOCKSIZE 16 //!< Block size in number of bytes.
20 #include <string.h> 19
21 20
22 #include <avr/pgmspace.h> //tables have to reside in flash memory 21
23 22 #if KEY_COUNT == 1
24 23 #define KEYBITS 128 //!< Use AES128.
25 // AES only supports Nb=4 24 #elif KEY_COUNT == 2
26 #define Nb 4 // number of columns in the state & expanded key 25 #define KEYBITS 192 //!< Use AES196.
27 26 #elif KEY_COUNT == 3
28 #define Nk 4 // number of columns in a key 27 #define KEYBITS 256 //!< Use AES256.
29 #define Nr 10 // number of rounds in encryption 28 #else
30 29 #error Use 1, 2 or 3 keys!
31 #define Sbox(i) (pgm_read_byte(&P_Sbox[i])) 30 #endif
32 const unsigned char P_Sbox[256] __attribute__ ((__progmem__)) = { // forward s-box 31
33 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 32 #if KEYBITS == 128
34 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 33 #define ROUNDS 10 //!< Number of rounds.
35 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 34 #define KEYLENGTH 16 //!< Key length in number of bytes.
36 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 35 #elif KEYBITS == 192
37 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 36 #define ROUNDS 12 //!< Number of rounds.
38 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 37 #define KEYLENGTH 24 //!< // Key length in number of bytes.
39 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 38 #elif KEYBITS == 256
40 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 39 #define ROUNDS 14 //!< Number of rounds.
41 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 40 #define KEYLENGTH 32 //!< Key length in number of bytes.
42 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 41 #else
43 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 42 #error Key must be 128, 192 or 256 bits!
44 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 43 #endif
45 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 44
46 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 45 #define EXPANDED_KEY_SIZE (BLOCKSIZE * (ROUNDS+1)) //!< 176, 208 or 240 bytes.
47 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 46
48 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; 47
49 48
50 #define InvSbox(i) (pgm_read_byte(&P_InvSbox[i])) 49 byte block1[ 256 ]; //!< Workspace 1.
51 const unsigned char P_InvSbox[256] __attribute__ ((__progmem__)) = { // inverse s-box 50 byte block2[ 256 ]; //!< Worksapce 2.
52 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 51
53 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 52
54 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 53
55 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 54 byte * powTbl; //!< Final location of exponentiation lookup table.
56 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 55 byte * logTbl; //!< Final location of logarithm lookup table.
57 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 56 byte * sBox; //!< Final location of s-box.
58 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 57 byte * sBoxInv; //!< Final location of inverse s-box.
59 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 58 byte * expandedKey; //!< Final location of expanded key.
60 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 59
61 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 60
62 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 61
63 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 62 void CalcPowLog( byte * powTbl, byte * logTbl )
64 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 63 {
65 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 64 byte i = 0;
66 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 65 byte t = 1;
67 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; 66
68 67 do {
69 // combined Xtimes2[Sbox[]] 68 // Use 0x03 as root for exponentiation and logarithms.
70 #define Xtime2Sbox(i) (pgm_read_byte(&P_Xtime2Sbox[i])) 69 powTbl[i] = t;
71 const unsigned char P_Xtime2Sbox[256] __attribute__ ((__progmem__)) = { 70 logTbl[t] = i;
72 0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91, 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec, 71 i++;
73 0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb, 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b, 72
74 0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83, 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a, 73 // Muliply t by 3 in GF(2^8).
75 0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f, 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea, 74 t ^= (t << 1) ^ (t & 0x80 ? BPOLY : 0);
76 0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b, 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13, 75 } while( t != 1 ); // Cyclic properties ensure that i < 255.
77 0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6, 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85, 76
78 0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11, 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b, 77 powTbl[255] = powTbl[0]; // 255 = '-0', 254 = -1, etc.
79 0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1, 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf, 78 }
80 0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e, 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6, 79
81 0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b, 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad, 80
82 0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8, 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2, 81
83 0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49, 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10, 82 void CalcSBox( byte * sBox )
84 0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97, 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f, 83 {
85 0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c, 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27, 84 byte i, rot;
86 0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33, 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5, 85 byte temp;
87 0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0, 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c 86 byte result;
88 }; 87
89 88 // Fill all entries of sBox[].
90 // combined Xtimes3[Sbox[]] 89 i = 0;
91 #define Xtime3Sbox(i) (pgm_read_byte(&P_Xtime3Sbox[i])) 90 do {
92 const unsigned char P_Xtime3Sbox[256] __attribute__ ((__progmem__)) = { 91 // Inverse in GF(2^8).
93 0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54, 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a, 92 if( i > 0 ) {
94 0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b, 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b, 93 temp = powTbl[ 255 - logTbl[i] ];
95 0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f, 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f, 94 } else {
96 0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5, 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f, 95 temp = 0;
97 0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb, 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97,
98 0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed, 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a,
99 0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94, 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3,
100 0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04, 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d,
101 0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39, 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95,
102 0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83, 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76,
103 0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4, 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b,
104 0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0, 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18,
105 0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51, 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85,
106 0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12, 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9,
107 0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7, 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a,
108 0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8, 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a
109 };
110
111 // modular multiplication tables
112 // based on:
113
114 // Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x)
115 // Xtime3[x] = x^Xtime2[x];
116
117 #define Xtime2(i) (pgm_read_byte(&P_Xtime2[i]))
118 const unsigned char P_Xtime2[256] __attribute__ ((__progmem__)) = {
119 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
120 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
121 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
122 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
123 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
124 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
125 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
126 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
127 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
128 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
129 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
130 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
131 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
132 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
133 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
134 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5};
135
136 #define Xtime9(i) (pgm_read_byte(&P_Xtime9[i]))
137 const unsigned char P_Xtime9[256] __attribute__ ((__progmem__)) = {
138 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
139 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
140 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
141 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
142 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
143 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
144 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
145 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
146 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
147 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
148 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
149 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
150 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
151 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
152 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
153 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46};
154
155 #define XtimeB(i) (pgm_read_byte(&P_XtimeB[i]))
156 const unsigned char P_XtimeB[256] __attribute__ ((__progmem__)) = {
157 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
158 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
159 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
160 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
161 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
162 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
163 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
164 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
165 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
166 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
167 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
168 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
169 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
170 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
171 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
172 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3};
173
174 #define XtimeD(i) (pgm_read_byte(&P_XtimeD[i]))
175 const unsigned char P_XtimeD[256] __attribute__ ((__progmem__)) = {
176 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
177 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
178 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
179 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
180 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
181 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
182 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
183 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
184 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
185 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
186 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
187 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
188 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
189 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
190 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
191 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97};
192
193 #define XtimeE(i) (pgm_read_byte(&P_XtimeE[i]))
194 const unsigned char P_XtimeE[256] __attribute__ ((__progmem__)) = {
195 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
196 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
197 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
198 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
199 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
200 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
201 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
202 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
203 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
204 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
205 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
206 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
207 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
208 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
209 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
210 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d};
211
212 // exchanges columns in each of 4 rows
213 // row0 - unchanged, row1- shifted left 1,
214 // row2 - shifted left 2 and row3 - shifted left 3
215 void ShiftRows (unsigned char *state)
216 {
217 unsigned char tmp;
218
219 // just substitute row 0
220 state[0] = Sbox(state[0]), state[4] = Sbox(state[4]);
221 state[8] = Sbox(state[8]), state[12] = Sbox(state[12]);
222
223 // rotate row 1
224 tmp = Sbox(state[1]), state[1] = Sbox(state[5]);
225 state[5] = Sbox(state[9]), state[9] = Sbox(state[13]), state[13] = tmp;
226
227 // rotate row 2
228 tmp = Sbox(state[2]), state[2] = Sbox(state[10]), state[10] = tmp;
229 tmp = Sbox(state[6]), state[6] = Sbox(state[14]), state[14] = tmp;
230
231 // rotate row 3
232 tmp = Sbox(state[15]), state[15] = Sbox(state[11]);
233 state[11] = Sbox(state[7]), state[7] = Sbox(state[3]), state[3] = tmp;
234 }
235
236 // restores columns in each of 4 rows
237 // row0 - unchanged, row1- shifted right 1,
238 // row2 - shifted right 2 and row3 - shifted right 3
239 void InvShiftRows (unsigned char *state)
240 {
241 unsigned char tmp;
242
243 // restore row 0
244 state[0] = InvSbox(state[0]), state[4] = InvSbox(state[4]);
245 state[8] = InvSbox(state[8]), state[12] = InvSbox(state[12]);
246
247 // restore row 1
248 tmp = InvSbox(state[13]), state[13] = InvSbox(state[9]);
249 state[9] = InvSbox(state[5]), state[5] = InvSbox(state[1]), state[1] = tmp;
250
251 // restore row 2
252 tmp = InvSbox(state[2]), state[2] = InvSbox(state[10]), state[10] = tmp;
253 tmp = InvSbox(state[6]), state[6] = InvSbox(state[14]), state[14] = tmp;
254
255 // restore row 3
256 tmp = InvSbox(state[3]), state[3] = InvSbox(state[7]);
257 state[7] = InvSbox(state[11]), state[11] = InvSbox(state[15]), state[15] = tmp;
258 }
259
260 // recombine and mix each row in a column
261 void MixSubColumns (unsigned char *state)
262 {
263 unsigned char tmp[4 * Nb];
264
265 // mixing column 0
266 tmp[0] = Xtime2Sbox(state[0]) ^ Xtime3Sbox(state[5]) ^ Sbox(state[10]) ^ Sbox(state[15]);
267 tmp[1] = Sbox(state[0]) ^ Xtime2Sbox(state[5]) ^ Xtime3Sbox(state[10]) ^ Sbox(state[15]);
268 tmp[2] = Sbox(state[0]) ^ Sbox(state[5]) ^ Xtime2Sbox(state[10]) ^ Xtime3Sbox(state[15]);
269 tmp[3] = Xtime3Sbox(state[0]) ^ Sbox(state[5]) ^ Sbox(state[10]) ^ Xtime2Sbox(state[15]);
270
271 // mixing column 1
272 tmp[4] = Xtime2Sbox(state[4]) ^ Xtime3Sbox(state[9]) ^ Sbox(state[14]) ^ Sbox(state[3]);
273 tmp[5] = Sbox(state[4]) ^ Xtime2Sbox(state[9]) ^ Xtime3Sbox(state[14]) ^ Sbox(state[3]);
274 tmp[6] = Sbox(state[4]) ^ Sbox(state[9]) ^ Xtime2Sbox(state[14]) ^ Xtime3Sbox(state[3]);
275 tmp[7] = Xtime3Sbox(state[4]) ^ Sbox(state[9]) ^ Sbox(state[14]) ^ Xtime2Sbox(state[3]);
276
277 // mixing column 2
278 tmp[8] = Xtime2Sbox(state[8]) ^ Xtime3Sbox(state[13]) ^ Sbox(state[2]) ^ Sbox(state[7]);
279 tmp[9] = Sbox(state[8]) ^ Xtime2Sbox(state[13]) ^ Xtime3Sbox(state[2]) ^ Sbox(state[7]);
280 tmp[10] = Sbox(state[8]) ^ Sbox(state[13]) ^ Xtime2Sbox(state[2]) ^ Xtime3Sbox(state[7]);
281 tmp[11] = Xtime3Sbox(state[8]) ^ Sbox(state[13]) ^ Sbox(state[2]) ^ Xtime2Sbox(state[7]);
282
283 // mixing column 3
284 tmp[12] = Xtime2Sbox(state[12]) ^ Xtime3Sbox(state[1]) ^ Sbox(state[6]) ^ Sbox(state[11]);
285 tmp[13] = Sbox(state[12]) ^ Xtime2Sbox(state[1]) ^ Xtime3Sbox(state[6]) ^ Sbox(state[11]);
286 tmp[14] = Sbox(state[12]) ^ Sbox(state[1]) ^ Xtime2Sbox(state[6]) ^ Xtime3Sbox(state[11]);
287 tmp[15] = Xtime3Sbox(state[12]) ^ Sbox(state[1]) ^ Sbox(state[6]) ^ Xtime2Sbox(state[11]);
288
289 memcpy (state, tmp, sizeof(tmp));
290 }
291
292 // restore and un-mix each row in a column
293 void InvMixSubColumns (unsigned char *state)
294 {
295 unsigned char tmp[4 * Nb];
296 int i;
297
298 // restore column 0
299 tmp[0] = XtimeE(state[0]) ^ XtimeB(state[1]) ^ XtimeD(state[2]) ^ Xtime9(state[3]);
300 tmp[5] = Xtime9(state[0]) ^ XtimeE(state[1]) ^ XtimeB(state[2]) ^ XtimeD(state[3]);
301 tmp[10] = XtimeD(state[0]) ^ Xtime9(state[1]) ^ XtimeE(state[2]) ^ XtimeB(state[3]);
302 tmp[15] = XtimeB(state[0]) ^ XtimeD(state[1]) ^ Xtime9(state[2]) ^ XtimeE(state[3]);
303
304 // restore column 1
305 tmp[4] = XtimeE(state[4]) ^ XtimeB(state[5]) ^ XtimeD(state[6]) ^ Xtime9(state[7]);
306 tmp[9] = Xtime9(state[4]) ^ XtimeE(state[5]) ^ XtimeB(state[6]) ^ XtimeD(state[7]);
307 tmp[14] = XtimeD(state[4]) ^ Xtime9(state[5]) ^ XtimeE(state[6]) ^ XtimeB(state[7]);
308 tmp[3] = XtimeB(state[4]) ^ XtimeD(state[5]) ^ Xtime9(state[6]) ^ XtimeE(state[7]);
309
310 // restore column 2
311 tmp[8] = XtimeE(state[8]) ^ XtimeB(state[9]) ^ XtimeD(state[10]) ^ Xtime9(state[11]);
312 tmp[13] = Xtime9(state[8]) ^ XtimeE(state[9]) ^ XtimeB(state[10]) ^ XtimeD(state[11]);
313 tmp[2] = XtimeD(state[8]) ^ Xtime9(state[9]) ^ XtimeE(state[10]) ^ XtimeB(state[11]);
314 tmp[7] = XtimeB(state[8]) ^ XtimeD(state[9]) ^ Xtime9(state[10]) ^ XtimeE(state[11]);
315
316 // restore column 3
317 tmp[12] = XtimeE(state[12]) ^ XtimeB(state[13]) ^ XtimeD(state[14]) ^ Xtime9(state[15]);
318 tmp[1] = Xtime9(state[12]) ^ XtimeE(state[13]) ^ XtimeB(state[14]) ^ XtimeD(state[15]);
319 tmp[6] = XtimeD(state[12]) ^ Xtime9(state[13]) ^ XtimeE(state[14]) ^ XtimeB(state[15]);
320 tmp[11] = XtimeB(state[12]) ^ XtimeD(state[13]) ^ Xtime9(state[14]) ^ XtimeE(state[15]);
321
322 for( i=0; i < 4 * Nb; i++ )
323 state[i] = InvSbox(tmp[i]);
324 }
325
326 // encrypt/decrypt columns of the key
327 // n.b. you can replace this with
328 // byte-wise xor if you wish.
329
330 void AddRoundKey (unsigned *state, unsigned *key)
331 {
332 int idx;
333
334 for( idx = 0; idx < 4; idx++ )
335 state[idx] ^= key[idx];
336 }
337
338 unsigned char Rcon[11] = {
339 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
340
341 // produce Nb bytes for each round
342 void ExpandKey (unsigned char *key, unsigned char *expkey)
343 {
344 unsigned char tmp0, tmp1, tmp2, tmp3, tmp4;
345 unsigned idx;
346
347 memcpy (expkey, key, Nk * 4);
348
349 for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) {
350 tmp0 = expkey[4*idx - 4];
351 tmp1 = expkey[4*idx - 3];
352 tmp2 = expkey[4*idx - 2];
353 tmp3 = expkey[4*idx - 1];
354 if( !(idx % Nk) ) {
355 tmp4 = tmp3;
356 tmp3 = Sbox(tmp0);
357 tmp0 = Sbox(tmp1) ^ Rcon[idx/Nk];
358 tmp1 = Sbox(tmp2);
359 tmp2 = Sbox(tmp4);
360 } else if( Nk > 6 && idx % Nk == 4 ) {
361 tmp0 = Sbox(tmp0);
362 tmp1 = Sbox(tmp1);
363 tmp2 = Sbox(tmp2);
364 tmp3 = Sbox(tmp3);
365 } 96 }
366 97
367 expkey[4*idx+0] = expkey[4*idx - 4*Nk + 0] ^ tmp0; 98 // Affine transformation in GF(2).
368 expkey[4*idx+1] = expkey[4*idx - 4*Nk + 1] ^ tmp1; 99 result = temp ^ 0x63; // Start with adding a vector in GF(2).
369 expkey[4*idx+2] = expkey[4*idx - 4*Nk + 2] ^ tmp2; 100 for( rot = 0; rot < 4; rot++ ) {
370 expkey[4*idx+3] = expkey[4*idx - 4*Nk + 3] ^ tmp3; 101 // Rotate left.
371 } 102 temp = (temp<<1) | (temp>>7);
372 } 103
373 104 // Add rotated byte in GF(2).
374 // encrypt one 128 bit block 105 result ^= temp;
375 void Encrypt (unsigned char *in, unsigned char *expkey, unsigned char *out) 106 }
376 { 107
377 unsigned char state[Nb * 4]; 108 // Put result in table.
378 unsigned round; 109 sBox[i] = result;
379 110 } while( ++i != 0 );
380 memcpy (state, in, Nb * 4); 111 }
381 AddRoundKey ((unsigned *)state, (unsigned *)expkey); 112
382 113
383 for( round = 1; round < Nr + 1; round++ ) { 114
384 if( round < Nr ) 115 void CalcSBoxInv( byte * sBox, byte * sBoxInv )
385 MixSubColumns (state); 116 {
386 else 117 byte i = 0;
387 ShiftRows (state); 118 byte j = 0;
388 119
389 AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb); 120 // Iterate through all elements in sBoxInv using i.
390 } 121 do {
391 122 // Search through sBox using j.
392 memcpy (out, state, sizeof(state)); 123 do {
393 } 124 // Check if current j is the inverse of current i.
394 125 if( sBox[ j ] == i ) {
395 void Decrypt (unsigned char *in, unsigned char *expkey, unsigned char *out) 126 // If so, set sBoxInc and indicate search finished.
396 { 127 sBoxInv[ i ] = j;
397 unsigned char state[Nb * 4]; 128 j = 255;
398 unsigned round; 129 }
399 130 } while( ++j != 0 );
400 memcpy (state, in, sizeof(state)); 131 } while( ++i != 0 );
401 132 }
402 AddRoundKey ((unsigned *)state, (unsigned *)expkey + Nr * Nb); 133
403 InvShiftRows(state); 134
404 135
405 for( round = Nr; round--; ) 136 void CycleLeft( byte * row )
137 {
138 // Cycle 4 bytes in an array left once.
139 byte temp = row[0];
140 row[0] = row[1];
141 row[1] = row[2];
142 row[2] = row[3];
143 row[3] = temp;
144 }
145
146
147
148 void InvMixColumn( byte * column )
149 {
150 byte result0, result1, result2, result3;
151 byte column0, column1, column2, column3;
152 byte xor;
153
154 // This generates more effective code, at least
155 // with the IAR C compiler.
156 column0 = column[0];
157 column1 = column[1];
158 column2 = column[2];
159 column3 = column[3];
160
161 // Partial sums (modular addition using XOR).
162 result0 = column1 ^ column2 ^ column3;
163 result1 = column0 ^ column2 ^ column3;
164 result2 = column0 ^ column1 ^ column3;
165 result3 = column0 ^ column1 ^ column2;
166
167 // Multiply column bytes by 2 modulo BPOLY.
168 // This operation is done the following way to ensure cycle count
169 // independent from data contents. Take care when changing this code.
170 xor = 0;
171 if (column0 & 0x80) {
172 xor = BPOLY;
173 }
174 column0 <<= 1;
175 column0 ^= xor;
176
177 xor = 0;
178 if (column1 & 0x80) {
179 xor = BPOLY;
180 }
181 column1 <<= 1;
182 column1 ^= xor;
183
184 xor = 0;
185 if (column2 & 0x80) {
186 xor = BPOLY;
187 }
188 column2 <<= 1;
189 column2 ^= xor;
190
191 xor = 0;
192 if (column3 & 0x80) {
193 xor = BPOLY;
194 }
195 column3 <<= 1;
196 column3 ^= xor;
197
198 // More partial sums.
199 result0 ^= column0 ^ column1;
200 result1 ^= column1 ^ column2;
201 result2 ^= column2 ^ column3;
202 result3 ^= column0 ^ column3;
203
204 // Multiply column bytes by 2 modulo BPOLY.
205 // This operation is done the following way to ensure cycle count
206 // independent from data contents. Take care when changing this code.
207 xor = 0;
208 if (column0 & 0x80) {
209 xor = BPOLY;
210 }
211 column0 <<= 1;
212 column0 ^= xor;
213
214 xor = 0;
215 if (column1 & 0x80) {
216 xor = BPOLY;
217 }
218 column1 <<= 1;
219 column1 ^= xor;
220
221 xor = 0;
222 if (column2 & 0x80) {
223 xor = BPOLY;
224 }
225 column2 <<= 1;
226 column2 ^= xor;
227
228 xor = 0;
229 if (column3 & 0x80) {
230 xor = BPOLY;
231 }
232 column3 <<= 1;
233 column3 ^= xor;
234
235 // More partial sums.
236 result0 ^= column0 ^ column2;
237 result1 ^= column1 ^ column3;
238 result2 ^= column0 ^ column2;
239 result3 ^= column1 ^ column3;
240
241 // Multiply column bytes by 2 modulo BPOLY.
242 // This operation is done the following way to ensure cycle count
243 // independent from data contents. Take care when changing this code.
244 xor = 0;
245 if (column0 & 0x80) {
246 xor = BPOLY;
247 }
248 column0 <<= 1;
249 column0 ^= xor;
250
251 xor = 0;
252 if (column1 & 0x80) {
253 xor = BPOLY;
254 }
255 column1 <<= 1;
256 column1 ^= xor;
257
258 xor = 0;
259 if (column2 & 0x80) {
260 xor = BPOLY;
261 }
262 column2 <<= 1;
263 column2 ^= xor;
264
265 xor = 0;
266 if (column3 & 0x80) {
267 xor = BPOLY;
268 }
269 column3 <<= 1;
270 column3 ^= xor;
271
272 // Final partial sum.
273 column0 ^= column1 ^ column2 ^ column3;
274
275 // Final sums stored into original column bytes.
276 column[0] = result0 ^ column0;
277 column[1] = result1 ^ column0;
278 column[2] = result2 ^ column0;
279 column[3] = result3 ^ column0;
280 }
281
282
283
284 void SubBytes( byte * bytes, byte count )
285 {
286 do {
287 *bytes = sBox[ *bytes ]; // Substitute every byte in state.
288 bytes++;
289 } while( --count );
290 }
291
292
293
294 void InvSubBytesAndXOR( byte * bytes, byte * key, byte count )
295 {
296 do {
297 // *bytes = sBoxInv[ *bytes ] ^ *key; // Inverse substitute every byte in state and add key.
298 *bytes = block2[ *bytes ] ^ *key; // Use block2 directly. Increases speed.
299 bytes++;
300 key++;
301 } while( --count );
302 }
303
304
305
306 void InvShiftRows( byte * state )
307 {
308 byte temp;
309
310 // Note: State is arranged column by column.
311
312 // Cycle second row right one time.
313 temp = state[ 1 + 3*4 ];
314 state[ 1 + 3*4 ] = state[ 1 + 2*4 ];
315 state[ 1 + 2*4 ] = state[ 1 + 1*4 ];
316 state[ 1 + 1*4 ] = state[ 1 + 0*4 ];
317 state[ 1 + 0*4 ] = temp;
318
319 // Cycle third row right two times.
320 temp = state[ 2 + 0*4 ];
321 state[ 2 + 0*4 ] = state[ 2 + 2*4 ];
322 state[ 2 + 2*4 ] = temp;
323 temp = state[ 2 + 1*4 ];
324 state[ 2 + 1*4 ] = state[ 2 + 3*4 ];
325 state[ 2 + 3*4 ] = temp;
326
327 // Cycle fourth row right three times, ie. left once.
328 temp = state[ 3 + 0*4 ];
329 state[ 3 + 0*4 ] = state[ 3 + 1*4 ];
330 state[ 3 + 1*4 ] = state[ 3 + 2*4 ];
331 state[ 3 + 2*4 ] = state[ 3 + 3*4 ];
332 state[ 3 + 3*4 ] = temp;
333 }
334
335
336
337 void InvMixColumns( byte * state )
338 {
339 InvMixColumn( state + 0*4 );
340 InvMixColumn( state + 1*4 );
341 InvMixColumn( state + 2*4 );
342 InvMixColumn( state + 3*4 );
343 }
344
345
346
347 void XORBytes( byte * bytes1, byte * bytes2, byte count )
348 {
349 do {
350 *bytes1 ^= *bytes2; // Add in GF(2), ie. XOR.
351 bytes1++;
352 bytes2++;
353 } while( --count );
354 }
355
356
357
358 void CopyBytes( byte * to, byte * from, byte count )
359 {
360 do {
361 *to = *from;
362 to++;
363 from++;
364 } while( --count );
365 }
366
367
368
369 void KeyExpansion( byte * key, byte * expandedKey )
370 {
371 byte temp[4];
372 byte i;
373 byte Rcon[4] = { 0x01, 0x00, 0x00, 0x00 }; // Round constant.
374
375 #if 0
376 // matt
377 unsigned char BOOTFLASH * key = kTable;
378 #endif
379
380 // Copy key to start of expanded key.
381 i = KEYLENGTH;
382 do {
383 *expandedKey = *key;
384 expandedKey++;
385 key++;
386 } while( --i );
387
388 // Prepare last 4 bytes of key in temp.
389 expandedKey -= 4;
390 temp[0] = *(expandedKey++);
391 temp[1] = *(expandedKey++);
392 temp[2] = *(expandedKey++);
393 temp[3] = *(expandedKey++);
394
395 // Expand key.
396 i = KEYLENGTH;
397 while( i < BLOCKSIZE*(ROUNDS+1) ) {
398 // Are we at the start of a multiple of the key size?
399 if( (i % KEYLENGTH) == 0 ) {
400 CycleLeft( temp ); // Cycle left once.
401 SubBytes( temp, 4 ); // Substitute each byte.
402 XORBytes( temp, Rcon, 4 ); // Add constant in GF(2).
403 *Rcon = (*Rcon << 1) ^ (*Rcon & 0x80 ? BPOLY : 0);
404 }
405
406 // Keysize larger than 24 bytes, ie. larger that 192 bits?
407 #if KEYLENGTH > 24
408 // Are we right past a block size?
409 else if( (i % KEYLENGTH) == BLOCKSIZE ) {
410 SubBytes( temp, 4 ); // Substitute each byte.
411 }
412 #endif
413
414 // Add bytes in GF(2) one KEYLENGTH away.
415 XORBytes( temp, expandedKey - KEYLENGTH, 4 );
416
417 // Copy result to current 4 bytes.
418 *(expandedKey++) = temp[ 0 ];
419 *(expandedKey++) = temp[ 1 ];
420 *(expandedKey++) = temp[ 2 ];
421 *(expandedKey++) = temp[ 3 ];
422
423 i += 4; // Next 4 bytes.
424 }
425 }
426
427
428
429 void InvCipher( byte * block, byte * expandedKey )
430 {
431 byte round = ROUNDS-1;
432 expandedKey += BLOCKSIZE * ROUNDS;
433
434 XORBytes( block, expandedKey, 16 );
435 expandedKey -= BLOCKSIZE;
436
437 do {
438 InvShiftRows( block );
439 InvSubBytesAndXOR( block, expandedKey, 16 );
440 expandedKey -= BLOCKSIZE;
441 InvMixColumns( block );
442 } while( --round );
443
444 InvShiftRows( block );
445 InvSubBytesAndXOR( block, expandedKey, 16 );
446 }
447
448
449
450 void aesInit( unsigned char *key, unsigned char * tempbuf )
451 {
452 powTbl = block1;
453 logTbl = block2;
454 CalcPowLog( powTbl, logTbl );
455
456 sBox = tempbuf;
457 CalcSBox( sBox );
458
459 expandedKey = block1;
460 KeyExpansion( key, expandedKey );
461
462 sBoxInv = block2; // Must be block2.
463 CalcSBoxInv( sBox, sBoxInv );
464 }
465
466
467
468 void aesDecrypt( unsigned char * buffer, unsigned char * chainBlock )
469 {
470 byte temp[ BLOCKSIZE ];
471
472 CopyBytes( temp, buffer, BLOCKSIZE );
473 InvCipher( buffer, expandedKey );
474 if (chainBlock)
406 { 475 {
407 AddRoundKey ((unsigned *)state, (unsigned *)expkey + round * Nb); 476 XORBytes( buffer, chainBlock, BLOCKSIZE );
408 if( round ) 477 CopyBytes( chainBlock, temp, BLOCKSIZE );
409 InvMixSubColumns (state); 478 }
410 } 479 }
411 480
412 memcpy (out, state, sizeof(state));
413 }
414
415
416 #if 0
417
418 /*avr specific routines*/
419 #include "backward.h"
420 #include <avr/io.h>
421 #include <avr/pgmspace.h>
422 #include <avr/eeprom.h>
423 #include <avr/interrupt.h>
424 #include <avr/sleep.h>
425
426
427
428 #if defined(at90s2313) || defined(at90s8535)
429 #else
430 #define ATmega
431 #endif 481 #endif
432
433 #ifdef ATmega
434 #define USR UCSRA
435 #endif
436
437
438
439 void printP (PGM_P string){
440 char c;
441 c=pgm_read_byte(string);
442 while (c) {
443 loop_until_bit_is_set(USR, UDRE);
444 UDR = c;
445 c=pgm_read_byte(++string);
446 }
447 return;
448 }
449
450
451
452 void print (const char *string){
453 while (*string) {
454 loop_until_bit_is_set(USR, UDRE);
455 UDR = *string++;
456 }
457 return;
458 }
459
460 void scan(char *string){
461 char c;
462 do {
463 do {
464 loop_until_bit_is_set(USR, RXC);
465 c =UDR;
466 } while bit_is_set(USR, FE);
467 *string++ = c;
468 //echo the character
469 loop_until_bit_is_set(USR, UDRE);
470 UDR = c;
471 } while ( c != '\r' );
472 loop_until_bit_is_set(USR, UDRE);
473 UDR = '\n';
474 string[-1]=0;
475 }
476
477
478 //UART initialize
479 #ifdef ATmega
480 #define UCR UCSRB
481 #define UART_INIT(baud) { \
482 UBRRH=0; \
483 UBRRL= (XTAL/baud+15)/16-1; \
484 UCSRB=(1<<TXEN)|(1<<RXEN); \
485 UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)|(1<<USBS); }
486 #else
487 #define UART_INIT(baud) { \
488 UBRR = (XTAL/baud+15)/16-1; \
489 sbi(UCR, TXEN); \
490 sbi(UCR, RXEN); \
491 }
492 #endif
493
494 #define itoa10(N,S) itoa(N,S,10)
495 #define itoa16(N,S) itoa(N,S,16)
496
497
498 //DEMO
499
500 unsigned char sampleout[16];
501
502
503 unsigned char samplekey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab,
504 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
505
506 unsigned char samplein[] = {0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31,
507 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34};
508
509 #define BAUD 115200
510
511 int main(void)
512 {
513 UART_INIT(BAUD);
514
515 unsigned char expkey[4 * Nb * (Nr + 1)];
516 unsigned char i;
517 char c[8];
518
519 printP(PSTR("Original: "));
520 for( i = 0; i < 16; i++ ) {itoa16(samplein[i],c);print(c); print(" ");}
521 printP(PSTR("\n"));
522
523 ExpandKey (samplekey, expkey);
524 Encrypt (samplein, expkey, sampleout);
525
526 printP(PSTR("Encrypted: "));
527 for( i = 0; i < 16; i++ ) {itoa16(sampleout[i],c);print(c); print(" ");}
528 printP(PSTR("\n"));
529
530 Decrypt (sampleout, expkey, samplein);
531
532 printP(PSTR("Decrypted: "));
533
534 for( i = 0; i < 16; i++ ) {itoa16(samplein[i],c);print(c); print(" ");}
535 printP(PSTR("\n"));
536 }
537
538
539 #endif