aes.hpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #ifndef __AES_HPP__
  2. #define __AES_HPP__
  3. /* Based on reference code from the Intel AES-NI whitepaper
  4. * http://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf
  5. */
  6. #include <wmmintrin.h>
  7. using AESkey = __m128i[11];
  8. static inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2)
  9. {
  10. __m128i temp3;
  11. temp2 = _mm_shuffle_epi32 (temp2 ,0xff);
  12. temp3 = _mm_slli_si128 (temp1, 0x4);
  13. temp1 = _mm_xor_si128 (temp1, temp3);
  14. temp3 = _mm_slli_si128 (temp3, 0x4);
  15. temp1 = _mm_xor_si128 (temp1, temp3);
  16. temp3 = _mm_slli_si128 (temp3, 0x4);
  17. temp1 = _mm_xor_si128 (temp1, temp3);
  18. temp1 = _mm_xor_si128 (temp1, temp2);
  19. return temp1;
  20. }
  21. static inline void AES_128_Key_Expansion (AESkey &key, __m128i rawkey)
  22. {
  23. __m128i temp1, temp2;
  24. __m128i *Key_Schedule = key;
  25. temp1 = rawkey;
  26. Key_Schedule[0] = temp1;
  27. temp2 = _mm_aeskeygenassist_si128 (temp1 ,0x1);
  28. temp1 = AES_128_ASSIST(temp1, temp2);
  29. Key_Schedule[1] = temp1;
  30. temp2 = _mm_aeskeygenassist_si128 (temp1,0x2);
  31. temp1 = AES_128_ASSIST(temp1, temp2);
  32. Key_Schedule[2] = temp1;
  33. temp2 = _mm_aeskeygenassist_si128 (temp1,0x4);
  34. temp1 = AES_128_ASSIST(temp1, temp2);
  35. Key_Schedule[3] = temp1;
  36. temp2 = _mm_aeskeygenassist_si128 (temp1,0x8);
  37. temp1 = AES_128_ASSIST(temp1, temp2);
  38. Key_Schedule[4] = temp1;
  39. temp2 = _mm_aeskeygenassist_si128 (temp1,0x10);
  40. temp1 = AES_128_ASSIST(temp1, temp2);
  41. Key_Schedule[5] = temp1;
  42. temp2 = _mm_aeskeygenassist_si128 (temp1,0x20);
  43. temp1 = AES_128_ASSIST(temp1, temp2);
  44. Key_Schedule[6] = temp1;
  45. temp2 = _mm_aeskeygenassist_si128 (temp1,0x40);
  46. temp1 = AES_128_ASSIST(temp1, temp2);
  47. Key_Schedule[7] = temp1;
  48. temp2 = _mm_aeskeygenassist_si128 (temp1,0x80);
  49. temp1 = AES_128_ASSIST(temp1, temp2);
  50. Key_Schedule[8] = temp1;
  51. temp2 = _mm_aeskeygenassist_si128 (temp1,0x1b);
  52. temp1 = AES_128_ASSIST(temp1, temp2);
  53. Key_Schedule[9] = temp1;
  54. temp2 = _mm_aeskeygenassist_si128 (temp1,0x36);
  55. temp1 = AES_128_ASSIST(temp1, temp2);
  56. Key_Schedule[10] = temp1;
  57. }
  58. static inline void AES_ECB_encrypt(__m128i &ciphertext, __m128i plaintext,
  59. const AESkey &key, size_t &aes_ops)
  60. {
  61. __m128i tmp;
  62. int j;
  63. tmp = plaintext;
  64. tmp = _mm_xor_si128 (tmp,key[0]);
  65. for(j=1; j<10; j++){
  66. tmp = _mm_aesenc_si128 (tmp,key[j]);
  67. }
  68. tmp = _mm_aesenclast_si128 (tmp,key[j]);
  69. ciphertext=tmp;
  70. ++aes_ops;
  71. }
  72. #endif