aes.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /* Based on 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. using AESkey = __m128i[11];
  6. static inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2)
  7. {
  8. __m128i temp3;
  9. temp2 = _mm_shuffle_epi32 (temp2 ,0xff);
  10. temp3 = _mm_slli_si128 (temp1, 0x4);
  11. temp1 = _mm_xor_si128 (temp1, temp3);
  12. temp3 = _mm_slli_si128 (temp3, 0x4);
  13. temp1 = _mm_xor_si128 (temp1, temp3);
  14. temp3 = _mm_slli_si128 (temp3, 0x4);
  15. temp1 = _mm_xor_si128 (temp1, temp3);
  16. temp1 = _mm_xor_si128 (temp1, temp2);
  17. return temp1;
  18. }
  19. static inline void AES_128_Key_Expansion (AESkey &key, __m128i rawkey)
  20. {
  21. __m128i temp1, temp2;
  22. __m128i *Key_Schedule = key;
  23. temp1 = rawkey;
  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. static inline void AES_ECB_encrypt(__m128i &ciphertext, __m128i plaintext, const AESkey &key)
  57. {
  58. __m128i tmp;
  59. int j;
  60. tmp = plaintext;
  61. tmp = _mm_xor_si128 (tmp,key[0]);
  62. for(j=1; j<10; j++){
  63. tmp = _mm_aesenc_si128 (tmp,key[j]);
  64. }
  65. tmp = _mm_aesenclast_si128 (tmp,key[j]);
  66. ciphertext=tmp;
  67. }