Guest User

CryptLib_Aes.c

a guest
Nov 23rd, 2017
269
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×