aes.hpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /* Reference code from the Intel AES-NI whitepaper
  2. * http://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf
  3. */
  4. #include <wmmintrin.h>
  5. inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2)
  6. {
  7. __m128i temp3;
  8. temp2 = _mm_shuffle_epi32 (temp2 ,0xff);
  9. temp3 = _mm_slli_si128 (temp1, 0x4);
  10. temp1 = _mm_xor_si128 (temp1, temp3);
  11. temp3 = _mm_slli_si128 (temp3, 0x4);
  12. temp1 = _mm_xor_si128 (temp1, temp3);
  13. temp3 = _mm_slli_si128 (temp3, 0x4);
  14. temp1 = _mm_xor_si128 (temp1, temp3);
  15. temp1 = _mm_xor_si128 (temp1, temp2);
  16. return temp1;
  17. }
  18. void AES_128_Key_Expansion (const unsigned char *userkey,
  19. unsigned char *key)
  20. {
  21. __m128i temp1, temp2;
  22. __m128i *Key_Schedule = (__m128i*)key;
  23. temp1 = _mm_loadu_si128((__m128i*)userkey);
  24. Key_Schedule[0] = temp1;
  25. temp2 = _mm_aeskeygenassist_si128 (temp1 ,0x1);
  26. temp1 = AES_128_ASSIST(temp1, temp2);
  27. Key_Schedule[1] = temp1;
  28. temp2 = _mm_aeskeygenassist_si128 (temp1,0x2);
  29. temp1 = AES_128_ASSIST(temp1, temp2);
  30. Key_Schedule[2] = temp1;
  31. temp2 = _mm_aeskeygenassist_si128 (temp1,0x4);
  32. temp1 = AES_128_ASSIST(temp1, temp2);
  33. Key_Schedule[3] = temp1;
  34. temp2 = _mm_aeskeygenassist_si128 (temp1,0x8);
  35. temp1 = AES_128_ASSIST(temp1, temp2);
  36. Key_Schedule[4] = temp1;
  37. temp2 = _mm_aeskeygenassist_si128 (temp1,0x10);
  38. temp1 = AES_128_ASSIST(temp1, temp2);
  39. Key_Schedule[5] = temp1;
  40. temp2 = _mm_aeskeygenassist_si128 (temp1,0x20);
  41. temp1 = AES_128_ASSIST(temp1, temp2);
  42. Key_Schedule[6] = temp1;
  43. temp2 = _mm_aeskeygenassist_si128 (temp1,0x40);
  44. temp1 = AES_128_ASSIST(temp1, temp2);
  45. Key_Schedule[7] = temp1;
  46. temp2 = _mm_aeskeygenassist_si128 (temp1,0x80);
  47. temp1 = AES_128_ASSIST(temp1, temp2);
  48. Key_Schedule[8] = temp1;
  49. temp2 = _mm_aeskeygenassist_si128 (temp1,0x1b);
  50. temp1 = AES_128_ASSIST(temp1, temp2);
  51. Key_Schedule[9] = temp1;
  52. temp2 = _mm_aeskeygenassist_si128 (temp1,0x36);
  53. temp1 = AES_128_ASSIST(temp1, temp2);
  54. Key_Schedule[10] = temp1;
  55. }
  56. /* Note – the length of the output buffer is assumed to be a multiple of 16 bytes */
  57. void AES_ECB_encrypt(const unsigned char *in, //pointer to the PLAINTEXT
  58. unsigned char *out, //pointer to the CIPHERTEXT buffer
  59. unsigned long length, //text length in bytes
  60. const char *key, //pointer to the expanded key schedule
  61. int number_of_rounds) //number of AES rounds 10,12 or 14
  62. {
  63. __m128i tmp;
  64. int i,j;
  65. if(length%16)
  66. length = length/16+1;
  67. else
  68. length = length/16;
  69. for(i=0; i < length; i++){
  70. tmp = _mm_loadu_si128 (&((__m128i*)in)[i]);
  71. tmp = _mm_xor_si128 (tmp,((__m128i*)key)[0]);
  72. for(j=1; j <number_of_rounds; j++){
  73. tmp = _mm_aesenc_si128 (tmp,((__m128i*)key)[j]);
  74. }
  75. tmp = _mm_aesenclast_si128 (tmp,((__m128i*)key)[j]);
  76. _mm_storeu_si128 (&((__m128i*)out)[i],tmp);
  77. }
  78. }