Advertisement
Guest User

CryptLib_Aes.c

a guest
Nov 23rd, 2017
483
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 24.00 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //  CryptLib_Aes
  3. //
  4. //  Implementation of AES block cipher. Originally written by Kokke (https://github.com/kokke). Modified by WaterJuice
  5. //  retaining Public Domain license.
  6. //
  7. //  AES is a block cipher that operates on 128 bit blocks. Encryption an Decryption routines use an AesContext which
  8. //  must be initialised with the key. An AesContext can be initialised with a 128, 192, or 256 bit key. Use the
  9. //  AesInitialise[n] functions to initialise the context with the key. Once an AES context is initialised its contents
  10. //  are not changed by the encrypting and decrypting functions. A context only needs to be initialised once for any
  11. //  given key and the context may be used by the encrypt/decrypt functions in simultaneous threads.
  12. //  All operations are performed byte wise and this implementation works in both little and endian processors.
  13. //  There are no alignment requirements with the keys and data blocks.
  14. //
  15. //  This is free and unencumbered software released into the public domain - November 2017 waterjuice.org
  16. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17.  
  18. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  19. //  IMPORTS
  20. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  21.  
  22. #include "CryptLib_Aes.h"
  23. #include <stdint.h>
  24. #include <memory.h>
  25.  
  26. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. //  DEFINES
  28. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  29.  
  30. // Array holding the intermediate results during decryption.
  31. typedef struct
  32. {
  33.     uint8_t     state[4][4];
  34. } AesState;
  35.  
  36. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  37. //  CONSTANTS
  38. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  39.  
  40. // AES lookup values
  41. static const uint8_t SBOX[256] =
  42. {
  43.     0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
  44.     0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
  45.     0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
  46.     0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
  47.     0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
  48.     0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
  49.     0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
  50.     0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
  51.     0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
  52.     0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
  53.     0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
  54.     0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
  55.     0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
  56.     0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
  57.     0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
  58.     0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
  59. };
  60.  
  61. static const uint8_t RSBOX[256] =
  62. {
  63.     0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
  64.     0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
  65.     0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
  66.     0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
  67.     0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
  68.     0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
  69.     0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
  70.     0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
  71.     0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
  72.     0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
  73.     0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
  74.     0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
  75.     0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
  76.     0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
  77.     0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
  78.     0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
  79.  
  80. // The round constant word array, RCON[i], contains the values given by
  81. // x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
  82. static const uint8_t RCON[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
  83.  
  84. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  85. //  INTERNAL FUNCTIONS
  86. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87.  
  88. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  89. //  KeyExpansion
  90. //
  91. //  This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
  92. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. static
  94. void
  95.     KeyExpansion
  96.     (
  97.         uint8_t const*  Key,                // [in]
  98.         AesContext*     Context             // [in out]
  99.     )
  100. {
  101.     uint32_t    i;
  102.     uint8_t     k;
  103.     uint8_t     temp [4];   // Used for the column/row operations
  104.  
  105.     // The first round key is the key itself.
  106.     for( i=0; i<Context->KeySizeInWords; i++ )
  107.     {
  108.         Context->RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
  109.         Context->RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
  110.         Context->RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
  111.         Context->RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
  112.     }
  113.  
  114.     // All other round keys are found from the previous round keys.
  115.     for( i=Context->KeySizeInWords; i<4*(Context->NumberOfRounds+1); i++ )
  116.     {
  117.         #ifdef _MSC_VER
  118.             // Visual Studio code analysis complains about the following code that the index into Context->RoundKey
  119.             // may be -4. This is because it is concerned that 'i' may be zero. However we know that 'i' will not
  120.             // be zero as it starts at Context->KeySizeInWords which is never going to be zero when this function
  121.             // is called (It will have one of 3 values assigned to it by the initialise functions). So we need to
  122.             // just suppress the warning here to stop Visual Studio complaining.
  123.             #pragma warning( suppress : 6385 )
  124.         #endif
  125.         temp[0] = Context->RoundKey[(i-1) * 4 + 0];
  126.         temp[1] = Context->RoundKey[(i-1) * 4 + 1];
  127.         temp[2] = Context->RoundKey[(i-1) * 4 + 2];
  128.         temp[3] = Context->RoundKey[(i-1) * 4 + 3];
  129.  
  130.         if( 0 == i % Context->KeySizeInWords )
  131.         {
  132.             // This function shifts the 4 bytes in a word to the left once.
  133.             // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
  134.             k = temp[0];
  135.             temp[0] = temp[1];
  136.             temp[1] = temp[2];
  137.             temp[2] = temp[3];
  138.             temp[3] = k;
  139.  
  140.             // SubWord is a function that takes a four-byte input word and
  141.             // applies the S-box to each of the four bytes to produce an output word.
  142.             temp[0] = SBOX[temp[0]];
  143.             temp[1] = SBOX[temp[1]];
  144.             temp[2] = SBOX[temp[2]];
  145.             temp[3] = SBOX[temp[3]];
  146.  
  147.             temp[0] =  temp[0] ^ RCON[i/Context->KeySizeInWords];
  148.         }
  149.  
  150.         if( AES_KEY_SIZE_256/4 == Context->KeySizeInWords )
  151.         {
  152.             // Only performed with 256 bit sized keys
  153.             if( 4 == i % Context->KeySizeInWords )
  154.             {
  155.                 // Function Subword()
  156.                 temp[0] = SBOX[temp[0]];
  157.                 temp[1] = SBOX[temp[1]];
  158.                 temp[2] = SBOX[temp[2]];
  159.                 temp[3] = SBOX[temp[3]];
  160.             }
  161.         }
  162.  
  163.         Context->RoundKey[i*4 + 0] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 0] ^ temp[0];
  164.         Context->RoundKey[i*4 + 1] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 1] ^ temp[1];
  165.         Context->RoundKey[i*4 + 2] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 2] ^ temp[2];
  166.         Context->RoundKey[i*4 + 3] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 3] ^ temp[3];
  167.     }
  168. }
  169.  
  170. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  171. //  AddRoundKey
  172. //
  173. //  This function adds the round key to state. The round key is added to the state by an XOR function.
  174. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  175. static
  176. void
  177.     AddRoundKey
  178.     (
  179.         uint32_t            Round,          // [in]
  180.         AesContext const*   Context,        // [in]
  181.         AesState*           State           // [in out]
  182.     )
  183. {
  184.     uint32_t  i;
  185.     uint32_t  j;
  186.  
  187.     for( i=0; i<4; i++ )
  188.     {
  189.         for( j=0; j<4; j++ )
  190.         {
  191.             State->state[i][j] ^= Context->RoundKey[(Round*4*4) + (i*4) + j];
  192.         }
  193.     }
  194. }
  195.  
  196. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  197. //  SubBytes
  198. //
  199. //  The SubBytes Function Substitutes the values in the state matrix with values in an S-box.
  200. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  201. static
  202. void
  203.     SubBytes
  204.     (
  205.         AesState*       State               // [in out]
  206.     )
  207. {
  208.     uint32_t i;
  209.     uint32_t j;
  210.  
  211.     for( i=0; i<4; i++ )
  212.     {
  213.         for( j=0; j<4; j++ )
  214.         {
  215.             State->state[j][i] = SBOX[ State->state[j][i] ];
  216.         }
  217.     }
  218. }
  219.  
  220. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. //  ShiftRows
  222. //
  223. //  The ShiftRows() function shifts the rows in the state to the left. Each row is shifted with different offset.
  224. //  Offset = Row number. So the first row is not shifted.
  225. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  226. static
  227. void
  228.     ShiftRows
  229.     (
  230.         AesState*     State                 // [in out]
  231.     )
  232. {
  233.     uint8_t temp;
  234.  
  235.     // Rotate first row 1 columns to left
  236.     temp           = State->state[0][1];
  237.     State->state[0][1] = State->state[1][1];
  238.     State->state[1][1] = State->state[2][1];
  239.     State->state[2][1] = State->state[3][1];
  240.     State->state[3][1] = temp;
  241.  
  242.     // Rotate second row 2 columns to left
  243.     temp           = State->state[0][2];
  244.     State->state[0][2] = State->state[2][2];
  245.     State->state[2][2] = temp;
  246.  
  247.     temp           = State->state[1][2];
  248.     State->state[1][2] = State->state[3][2];
  249.     State->state[3][2] = temp;
  250.  
  251.     // Rotate third row 3 columns to left
  252.     temp           = State->state[0][3];
  253.     State->state[0][3] = State->state[3][3];
  254.     State->state[3][3] = State->state[2][3];
  255.     State->state[2][3] = State->state[1][3];
  256.     State->state[1][3] = temp;
  257. }
  258.  
  259. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  260. //  xtime
  261. //
  262. //  Performs a calculation
  263. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  264. static
  265. uint8_t
  266.     xtime
  267.     (
  268.         uint8_t     x                       // [in]
  269.     )
  270. {
  271.     return (x<<1) ^ ( ((x>>7) & 1) * 0x1b );
  272. }
  273.  
  274. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  275. //  MixColumns
  276. //
  277. //  MixColumns function mixes the columns of the state matrix
  278. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  279. static
  280. void
  281.     MixColumns
  282.     (
  283.         AesState*     State                 // [in out]
  284.     )
  285. {
  286.     uint32_t  i;
  287.     uint8_t   Tmp;
  288.     uint8_t   Tm;
  289.     uint8_t   t;
  290.  
  291.     for( i=0; i<4; i++ )
  292.     {
  293.         t   = State->state[i][0];
  294.         Tmp = State->state[i][0] ^ State->state[i][1] ^ State->state[i][2] ^ State->state[i][3] ;
  295.         Tm  = State->state[i][0] ^ State->state[i][1] ; Tm = xtime(Tm);  State->state[i][0] ^= Tm ^ Tmp ;
  296.         Tm  = State->state[i][1] ^ State->state[i][2] ; Tm = xtime(Tm);  State->state[i][1] ^= Tm ^ Tmp ;
  297.         Tm  = State->state[i][2] ^ State->state[i][3] ; Tm = xtime(Tm);  State->state[i][2] ^= Tm ^ Tmp ;
  298.         Tm  = State->state[i][3] ^ t ;              Tm = xtime(Tm);  State->state[i][3] ^= Tm ^ Tmp ;
  299.     }
  300. }
  301.  
  302. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  303. //  Multiply
  304. //
  305. //  Multiply is used to multiply numbers in the field GF(2^8). This is defined as a macro.
  306. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  307. #define Multiply(x, y)                                \
  308.       (  ((y & 1) * x) ^                              \
  309.       ((y>>1 & 1) * xtime(x)) ^                       \
  310.       ((y>>2 & 1) * xtime(xtime(x))) ^                \
  311.       ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^         \
  312.       ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))   \
  313.  
  314. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  315. //  InvMixColumns
  316. //
  317. //  InvMixColumns function mixes the columns of the state matrix.
  318. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  319. static
  320. void
  321.     InvMixColumns
  322.     (
  323.         AesState*     State                 // [in out]
  324.     )
  325. {
  326.     uint32_t    i;
  327.     uint8_t     a;
  328.     uint8_t     b;
  329.     uint8_t     c;
  330.     uint8_t     d;
  331.  
  332.     for( i=0; i<4; i++ )
  333.     {
  334.         a = State->state[i][0];
  335.         b = State->state[i][1];
  336.         c = State->state[i][2];
  337.         d = State->state[i][3];
  338.  
  339.         State->state[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
  340.         State->state[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
  341.         State->state[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
  342.         State->state[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
  343.     }
  344. }
  345.  
  346. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  347. //  InvSubBytes
  348. //
  349. //  The InvSubBytes Function Substitutes the values in the state matrix with values in an S-box.
  350. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  351. static
  352. void
  353.     InvSubBytes
  354.     (
  355.         AesState*     State                 // [in out]
  356.     )
  357. {
  358.     uint32_t  i;
  359.     uint32_t  j;
  360.  
  361.     for( i=0; i<4; i++ )
  362.     {
  363.         for( j=0; j<4; j++ )
  364.         {
  365.             State->state[j][i] = RSBOX[ State->state[j][i] ];
  366.         }
  367.     }
  368. }
  369.  
  370. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  371. //  InvShiftRows
  372. //
  373. //  Inverse of ShiftRows
  374. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  375. static
  376. void
  377.     InvShiftRows
  378.     (
  379.         AesState*     State                 // [in out]
  380.     )
  381. {
  382.     uint8_t temp;
  383.  
  384.     // Rotate first row 1 columns to right
  385.     temp = State->state[3][1];
  386.     State->state[3][1] = State->state[2][1];
  387.     State->state[2][1] = State->state[1][1];
  388.     State->state[1][1] = State->state[0][1];
  389.     State->state[0][1] = temp;
  390.  
  391.     // Rotate second row 2 columns to right
  392.     temp = State->state[0][2];
  393.     State->state[0][2] = State->state[2][2];
  394.     State->state[2][2] = temp;
  395.  
  396.     temp = State->state[1][2];
  397.     State->state[1][2] = State->state[3][2];
  398.     State->state[3][2] = temp;
  399.  
  400.     // Rotate third row 3 columns to right
  401.     temp = State->state[0][3];
  402.     State->state[0][3] = State->state[1][3];
  403.     State->state[1][3] = State->state[2][3];
  404.     State->state[2][3] = State->state[3][3];
  405.     State->state[3][3] = temp;
  406. }
  407.  
  408. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  409. //  EXPORTED FUNCTIONS
  410. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  411.  
  412. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  413. //  AesInitialise128
  414. //
  415. //  Initialises an AesContext with a 128 bit key.
  416. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  417. void
  418.     AesInitialise128
  419.     (
  420.         uint8_t const   Key [AES_KEY_SIZE_128],         // [in]
  421.         AesContext*     Context                         // [out]
  422.     )
  423. {
  424.     memset( Context, 0, sizeof(*Context) );
  425.  
  426.     Context->KeySizeInWords = AES_KEY_SIZE_128 / sizeof(uint32_t);
  427.     Context->NumberOfRounds = 10;
  428.  
  429.     KeyExpansion( Key, Context );
  430. }
  431.  
  432. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  433. //  AesInitialise192
  434. //
  435. //  Initialises an AesContext with a 192 bit key.
  436. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  437. void
  438.     AesInitialise192
  439.     (
  440.         uint8_t const   Key [AES_KEY_SIZE_192],         // [in]
  441.         AesContext*     Context                         // [out]
  442.     )
  443. {
  444.     memset( Context, 0, sizeof(*Context) );
  445.  
  446.     Context->KeySizeInWords = AES_KEY_SIZE_192 / sizeof(uint32_t);
  447.     Context->NumberOfRounds = 12;
  448.  
  449.     KeyExpansion( Key, Context );
  450. }
  451.  
  452. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  453. //  AesInitialise256
  454. //
  455. //  Initialises an AesContext with a 256 bit key.
  456. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  457. void
  458.     AesInitialise256
  459.     (
  460.         uint8_t const   Key [AES_KEY_SIZE_256],         // [in]
  461.         AesContext*     Context                         // [out]
  462.     )
  463. {
  464.     memset( Context, 0, sizeof(*Context) );
  465.  
  466.     Context->KeySizeInWords = AES_KEY_SIZE_256 / sizeof(uint32_t);
  467.     Context->NumberOfRounds = 14;
  468.  
  469.     KeyExpansion( Key, Context );
  470. }
  471.  
  472. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  473. //  AesEncrypt
  474. //
  475. //  Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions
  476. //  AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use
  477. //  AesEncryptInPlace in this situation.
  478. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  479. void
  480.     AesEncrypt
  481.     (
  482.         AesContext const*   Context,                    // [in]
  483.         uint8_t const       Input [AES_BLOCK_SIZE],     // [in]
  484.         uint8_t             Output [AES_BLOCK_SIZE]     // [out]
  485.     )
  486. {
  487.     memcpy( Output, Input, AES_BLOCK_SIZE );
  488.     AesEncryptInPlace( Context, Output );
  489. }
  490.  
  491. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  492. //  AesDecrypt
  493. //
  494. //  Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions
  495. //  AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use
  496. //  AesDecryptInPlace in this situation.
  497. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  498. void
  499.     AesDecrypt
  500.     (
  501.         AesContext const*   Context,                    // [in]
  502.         uint8_t const       Input [AES_BLOCK_SIZE],     // [in]
  503.         uint8_t             Output [AES_BLOCK_SIZE]     // [out]
  504.     )
  505. {
  506.     memcpy( Output, Input, AES_BLOCK_SIZE);
  507.     AesDecryptInPlace(Context, Output );
  508. }
  509.  
  510. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  511. //  AesEncryptInPlace
  512. //
  513. //  Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions
  514. //  AesInitialise[n]. The encryption is performed in place.
  515. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  516. void
  517.     AesEncryptInPlace
  518.     (
  519.         AesContext const*   Context,                    // [in]
  520.         uint8_t             Block [AES_BLOCK_SIZE]      // [in out]
  521.     )
  522. {
  523.     uint32_t round = 0;
  524.  
  525.     // Add the First round key to the state before starting the rounds.
  526.     AddRoundKey( 0, Context, (AesState*)Block );
  527.  
  528.     // There will be Nr rounds.
  529.     // The first Nr-1 rounds are identical.
  530.     // These Nr-1 rounds are executed in the loop below.
  531.     for( round=1; round<Context->NumberOfRounds; round++ )
  532.     {
  533.         SubBytes( (AesState*)Block );
  534.         ShiftRows( (AesState*)Block );
  535.         MixColumns( (AesState*)Block );
  536.         AddRoundKey( round, Context, (AesState*)Block );
  537.     }
  538.  
  539.     // The last round is given below.
  540.     // The MixColumns function is not here in the last round.
  541.     SubBytes( (AesState*)Block);
  542.     ShiftRows( (AesState*)Block);
  543.     AddRoundKey( Context->NumberOfRounds, Context, (AesState*)Block );
  544. }
  545.  
  546. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  547. //  AesDecryptInPlace
  548. //
  549. //  Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions
  550. //  AesInitialise[n]. The decryption is performed in place.
  551. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  552. void
  553.     AesDecryptInPlace
  554.     (
  555.         AesContext const*   Context,                    // [in]
  556.         uint8_t             Block [AES_BLOCK_SIZE]      // [in out]
  557.     )
  558. {
  559.     uint32_t round = 0;
  560.  
  561.     // Add the First round key to the state before starting the rounds.
  562.     AddRoundKey( Context->NumberOfRounds, Context, (AesState*)Block );
  563.  
  564.     // The first NumberOfRounds-1 rounds are identical.
  565.     for( round=(Context->NumberOfRounds-1); round>0; round-- )
  566.     {
  567.         InvShiftRows( (AesState*)Block );
  568.         InvSubBytes( (AesState*)Block );
  569.         AddRoundKey( round, Context, (AesState*)Block );
  570.         InvMixColumns( (AesState*)Block );
  571.     }
  572.  
  573.     // The MixColumns function is not here in the last round.
  574.     InvShiftRows( (AesState*)Block );
  575.     InvSubBytes( (AesState*)Block );
  576.     AddRoundKey( 0, Context, (AesState*)Block );
  577. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement