nostril

A C cli tool for creating nostr events
git clone git://jb55.com/nostril
Log | Files | Refs | Submodules | README | LICENSE

aes.c (18982B)


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