source: ecs_cellMon/tools/FileEncrypt/src/aes.c @ 3

Last change on this file since 3 was 3, checked in by f.jahn, 20 months ago

fw hinzugfügt-->zed

File size: 18.6 KB
Line 
1/*
2
3This is an implementation of the AES128 algorithm, specifically ECB and CBC mode.
4
5The implementation is verified against the test vectors in:
6  National Institute of Standards and Technology Special Publication 800-38A 2001 ED
7
8ECB-AES128
9----------
10
11  plain-text:
12    6bc1bee22e409f96e93d7e117393172a
13    ae2d8a571e03ac9c9eb76fac45af8e51
14    30c81c46a35ce411e5fbc1191a0a52ef
15    f69f2445df4f9b17ad2b417be66c3710
16
17  key:
18    2b7e151628aed2a6abf7158809cf4f3c
19
20  resulting cipher
21    3ad77bb40d7a3660a89ecaf32466ef97
22    f5d3d58503b9699de785895a96fdbaaf
23    43b1cd7f598ece23881b00e3ed030688
24    7b0c785e27e8ad3f8223207104725dd4
25
26
27NOTE:   String length must be evenly divisible by 16byte (str_len % 16 == 0)
28        You should pad the end of the string with zeros if this is not the case.
29
30*/
31
32
33/*****************************************************************************/
34/* Includes:                                                                 */
35/*****************************************************************************/
36#include <stdint.h>
37#include <string.h> // CBC mode, for memset
38#include "aes.h"
39#include<stdio.h>
40
41
42/*****************************************************************************/
43/* Defines:                                                                  */
44/*****************************************************************************/
45// The number of columns comprising a state in AES. This is a constant in AES. Value=4
46#define Nb 4
47// The number of 32 bit words in a key.
48#define Nk 4
49// Key length in bytes [128 bit]
50#define KEYLEN 16
51// The number of rounds in AES Cipher.
52#define Nr 10
53
54// jcallan@github points out that declaring Multiply as a function
55// reduces code size considerably with the Keil ARM compiler.
56// See this link for more information: https://github.com/kokke/tiny-AES128-C/pull/3
57#ifndef MULTIPLY_AS_A_FUNCTION
58  #define MULTIPLY_AS_A_FUNCTION 0
59#endif
60
61
62/*****************************************************************************/
63/* Private variables:                                                        */
64/*****************************************************************************/
65// state - array holding the intermediate results during decryption.
66typedef uint8_t state_t[4][4];
67static state_t* state;
68
69// The array that stores the round keys.
70static uint8_t RoundKey[176];
71
72// The Key input to the AES Program
73static const uint8_t* Key;
74
75#if defined(CBC) && CBC
76  // Initial Vector used only for CBC mode
77  static uint8_t* Iv;
78#endif
79
80// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
81// The numbers below can be computed dynamically trading ROM for RAM -
82// This can be useful in (embedded) bootloader applications, where ROM is often limited.
83static const uint8_t sbox[256] =   {
84  //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
85  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
86  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
87  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
88  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
89  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
90  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
91  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
92  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
93  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
94  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
95  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
96  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
97  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
98  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
99  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
100  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
101
102static const uint8_t rsbox[256] =
103{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
104  0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
105  0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
106  0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
107  0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
108  0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
109  0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
110  0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
111  0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
112  0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
113  0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
114  0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
115  0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
116  0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
117  0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
118  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
119
120
121// The round constant word array, Rcon[i], contains the values given by
122// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
123// Note that i starts at 1, not 0).
124static const uint8_t Rcon[255] = {
125  0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 
126  0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 
127  0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 
128  0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 
129  0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 
130  0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 
131  0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 
132  0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 
133  0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 
134  0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 
135  0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 
136  0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 
137  0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 
138  0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 
139  0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 
140  0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb  };
141
142
143/*****************************************************************************/
144/* Private functions:                                                        */
145/*****************************************************************************/
146static uint8_t getSBoxValue(uint8_t num)
147{
148  return sbox[num];
149}
150
151static uint8_t getSBoxInvert(uint8_t num)
152{
153  return rsbox[num];
154}
155
156// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
157static void KeyExpansion(void)
158{
159  uint32_t i, j, k;
160  uint8_t tempa[4]; // Used for the column/row operations
161 
162  // The first round key is the key itself.
163  for(i = 0; i < Nk; ++i)
164  {
165    RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
166    RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
167    RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
168    RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
169  }
170
171  // All other round keys are found from the previous round keys.
172  for(; (i < (Nb * (Nr + 1))); ++i)
173  {
174    for(j = 0; j < 4; ++j)
175    {
176      tempa[j]=RoundKey[(i-1) * 4 + j];
177    }
178    if (i % Nk == 0)
179    {
180      // This function rotates the 4 bytes in a word to the left once.
181      // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
182
183      // Function RotWord()
184      {
185        k = tempa[0];
186        tempa[0] = tempa[1];
187        tempa[1] = tempa[2];
188        tempa[2] = tempa[3];
189        tempa[3] = k;
190      }
191
192      // SubWord() is a function that takes a four-byte input word and
193      // applies the S-box to each of the four bytes to produce an output word.
194
195      // Function Subword()
196      {
197        tempa[0] = getSBoxValue(tempa[0]);
198        tempa[1] = getSBoxValue(tempa[1]);
199        tempa[2] = getSBoxValue(tempa[2]);
200        tempa[3] = getSBoxValue(tempa[3]);
201      }
202
203      tempa[0] =  tempa[0] ^ Rcon[i/Nk];
204    }
205    else if (Nk > 6 && i % Nk == 4)
206    {
207      // Function Subword()
208      {
209        tempa[0] = getSBoxValue(tempa[0]);
210        tempa[1] = getSBoxValue(tempa[1]);
211        tempa[2] = getSBoxValue(tempa[2]);
212        tempa[3] = getSBoxValue(tempa[3]);
213      }
214    }
215    RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0];
216    RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1];
217    RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2];
218    RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3];
219  }
220}
221
222// This function adds the round key to state.
223// The round key is added to the state by an XOR function.
224static void AddRoundKey(uint8_t round)
225{
226  uint8_t i,j;
227  for(i=0;i<4;++i)
228  {
229    for(j = 0; j < 4; ++j)
230    {
231      (*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j];
232    }
233  }
234}
235
236// The SubBytes Function Substitutes the values in the
237// state matrix with values in an S-box.
238static void SubBytes(void)
239{
240  uint8_t i, j;
241  for(i = 0; i < 4; ++i)
242  {
243    for(j = 0; j < 4; ++j)
244    {
245      (*state)[j][i] = getSBoxValue((*state)[j][i]);
246    }
247  }
248}
249
250// The ShiftRows() function shifts the rows in the state to the left.
251// Each row is shifted with different offset.
252// Offset = Row number. So the first row is not shifted.
253static void ShiftRows(void)
254{
255  uint8_t temp;
256
257  // Rotate first row 1 columns to left 
258  temp           = (*state)[0][1];
259  (*state)[0][1] = (*state)[1][1];
260  (*state)[1][1] = (*state)[2][1];
261  (*state)[2][1] = (*state)[3][1];
262  (*state)[3][1] = temp;
263
264  // Rotate second row 2 columns to left 
265  temp           = (*state)[0][2];
266  (*state)[0][2] = (*state)[2][2];
267  (*state)[2][2] = temp;
268
269  temp       = (*state)[1][2];
270  (*state)[1][2] = (*state)[3][2];
271  (*state)[3][2] = temp;
272
273  // Rotate third row 3 columns to left
274  temp       = (*state)[0][3];
275  (*state)[0][3] = (*state)[3][3];
276  (*state)[3][3] = (*state)[2][3];
277  (*state)[2][3] = (*state)[1][3];
278  (*state)[1][3] = temp;
279}
280
281static uint8_t xtime(uint8_t x)
282{
283  return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
284}
285
286// MixColumns function mixes the columns of the state matrix
287static void MixColumns(void)
288{
289  uint8_t i;
290  uint8_t Tmp,Tm,t;
291  for(i = 0; i < 4; ++i)
292  { 
293    t   = (*state)[i][0];
294    Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
295    Tm  = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm);  (*state)[i][0] ^= Tm ^ Tmp ;
296    Tm  = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm);  (*state)[i][1] ^= Tm ^ Tmp ;
297    Tm  = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm);  (*state)[i][2] ^= Tm ^ Tmp ;
298    Tm  = (*state)[i][3] ^ t ;        Tm = xtime(Tm);  (*state)[i][3] ^= Tm ^ Tmp ;
299  }
300}
301
302// Multiply is used to multiply numbers in the field GF(2^8)
303#if MULTIPLY_AS_A_FUNCTION
304static uint8_t Multiply(uint8_t x, uint8_t y)
305{
306  return (((y & 1) * x) ^
307       ((y>>1 & 1) * xtime(x)) ^
308       ((y>>2 & 1) * xtime(xtime(x))) ^
309       ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
310       ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))));
311  }
312#else
313#define Multiply(x, y)                                \
314      (  ((y & 1) * x) ^                              \
315      ((y>>1 & 1) * xtime(x)) ^                       \
316      ((y>>2 & 1) * xtime(xtime(x))) ^                \
317      ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^         \
318      ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))   \
319
320#endif
321
322// MixColumns function mixes the columns of the state matrix.
323// The method used to multiply may be difficult to understand for the inexperienced.
324// Please use the references to gain more information.
325static void InvMixColumns(void)
326{
327  int i;
328  uint8_t a,b,c,d;
329  for(i=0;i<4;++i)
330  { 
331    a = (*state)[i][0];
332    b = (*state)[i][1];
333    c = (*state)[i][2];
334    d = (*state)[i][3];
335
336    (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
337    (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
338    (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
339    (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
340  }
341}
342
343
344// The SubBytes Function Substitutes the values in the
345// state matrix with values in an S-box.
346static void InvSubBytes(void)
347{
348  uint8_t i,j;
349  for(i=0;i<4;++i)
350  {
351    for(j=0;j<4;++j)
352    {
353      (*state)[j][i] = getSBoxInvert((*state)[j][i]);
354    }
355  }
356}
357
358static void InvShiftRows(void)
359{
360  uint8_t temp;
361
362  // Rotate first row 1 columns to right 
363  temp=(*state)[3][1];
364  (*state)[3][1]=(*state)[2][1];
365  (*state)[2][1]=(*state)[1][1];
366  (*state)[1][1]=(*state)[0][1];
367  (*state)[0][1]=temp;
368
369  // Rotate second row 2 columns to right
370  temp=(*state)[0][2];
371  (*state)[0][2]=(*state)[2][2];
372  (*state)[2][2]=temp;
373
374  temp=(*state)[1][2];
375  (*state)[1][2]=(*state)[3][2];
376  (*state)[3][2]=temp;
377
378  // Rotate third row 3 columns to right
379  temp=(*state)[0][3];
380  (*state)[0][3]=(*state)[1][3];
381  (*state)[1][3]=(*state)[2][3];
382  (*state)[2][3]=(*state)[3][3];
383  (*state)[3][3]=temp;
384}
385
386
387// Cipher is the main function that encrypts the PlainText.
388static void Cipher(void)
389{
390  uint8_t round = 0;
391
392  // Add the First round key to the state before starting the rounds.
393  AddRoundKey(0); 
394 
395  // There will be Nr rounds.
396  // The first Nr-1 rounds are identical.
397  // These Nr-1 rounds are executed in the loop below.
398  for(round = 1; round < Nr; ++round)
399  {
400    SubBytes();
401    ShiftRows();
402    MixColumns();
403    AddRoundKey(round);
404  }
405 
406  // The last round is given below.
407  // The MixColumns function is not here in the last round.
408  SubBytes();
409  ShiftRows();
410  AddRoundKey(Nr);
411}
412
413static void InvCipher(void)
414{
415  uint8_t round=0;
416
417  // Add the First round key to the state before starting the rounds.
418  AddRoundKey(Nr); 
419
420  // There will be Nr rounds.
421  // The first Nr-1 rounds are identical.
422  // These Nr-1 rounds are executed in the loop below.
423  for(round=Nr-1;round>0;round--)
424  {
425    InvShiftRows();
426    InvSubBytes();
427    AddRoundKey(round);
428    InvMixColumns();
429  }
430 
431  // The last round is given below.
432  // The MixColumns function is not here in the last round.
433  InvShiftRows();
434  InvSubBytes();
435  AddRoundKey(0);
436}
437
438static void BlockCopy(uint8_t* output, uint8_t* input)
439{
440  uint8_t i;
441  for (i=0;i<KEYLEN;++i)
442  {
443    output[i] = input[i];
444  }
445}
446
447
448
449/*****************************************************************************/
450/* Public functions:                                                         */
451/*****************************************************************************/
452#if defined(ECB) && ECB
453
454
455void AES128_ECB_encrypt(uint8_t* input, const uint8_t* key, uint8_t* output)
456{
457  // Copy input to output, and work in-memory on output
458  BlockCopy(output, input);
459  state = (state_t*)output;
460
461  Key = key;
462  KeyExpansion();
463
464  // The next function call encrypts the PlainText with the Key using AES algorithm.
465  Cipher();
466}
467
468void AES128_ECB_decrypt(uint8_t* input, const uint8_t* key, uint8_t *output)
469{
470  // Copy input to output, and work in-memory on output
471  BlockCopy(output, input);
472  state = (state_t*)output;
473
474  // The KeyExpansion routine must be called before encryption.
475  Key = key;
476  KeyExpansion();
477
478  InvCipher();
479}
480
481
482#endif // #if defined(ECB) && ECB
483
484
485
486
487
488#if defined(CBC) && CBC
489
490
491static void XorWithIv(uint8_t* buf)
492{
493  uint8_t i;
494  for(i = 0; i < KEYLEN; ++i)
495  {
496    buf[i] ^= Iv[i];
497  }
498}
499
500void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
501{
502  uintptr_t i;
503  uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */
504
505  BlockCopy(output, input);
506  state = (state_t*)output;
507
508  // Skip the key expansion if key is passed as 0
509  if(0 != key)
510  {
511    Key = key;
512    KeyExpansion();
513  }
514
515  if(iv != 0)
516  {
517    Iv = (uint8_t*)iv;
518  }
519
520  for(i = 0; i < length; i += KEYLEN)
521  {
522    XorWithIv(input);
523    BlockCopy(output, input);
524    state = (state_t*)output;
525    Cipher();
526    Iv = output;
527    input += KEYLEN;
528    output += KEYLEN;
529  }
530
531  if(remainders)
532  {
533    BlockCopy(output, input);
534    memset(output + remainders, 0, KEYLEN - remainders); /* add 0-padding */
535    state = (state_t*)output;
536    Cipher();
537  }
538}
539
540void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
541{
542  uintptr_t i;
543  uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */
544 
545  BlockCopy(output, input);
546  state = (state_t*)output;
547
548  // Skip the key expansion if key is passed as 0
549  if(0 != key)
550  {
551    Key = key;
552    KeyExpansion();
553  }
554
555  // If iv is passed as 0, we continue to encrypt without re-setting the Iv
556  if(iv != 0)
557  {
558    Iv = (uint8_t*)iv;
559  }
560
561  for(i = 0; i < length; i += KEYLEN)
562  {
563    BlockCopy(output, input);
564    state = (state_t*)output;
565    InvCipher();
566    XorWithIv(output);
567    Iv = input;
568    input += KEYLEN;
569    output += KEYLEN;
570  }
571
572  if(remainders)
573  {
574    BlockCopy(output, input);
575    memset(output+remainders, 0, KEYLEN - remainders); /* add 0-padding */
576    state = (state_t*)output;
577    InvCipher();
578  }
579}
580
581
582#endif // #if defined(CBC) && CBC
583
584
585// prints string as hex
586void phex(uint8_t* str, int num)
587{
588    unsigned char i;
589    for(i = 0; i < num ; ++i)
590        printf("%.2x", str[i]);
591    printf("\n");
592}
Note: See TracBrowser for help on using the repository browser.