aes.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. /* Extracted from /usr/lib/gcc/x86_64-linux-gnu/11/include/emmintrin.h and
  7. /usr/lib/gcc/x86_64-linux-gnu/11/include/wmmintrin.h */
  8. typedef int __v4si __attribute__ ((__vector_size__ (16)));
  9. typedef unsigned long long __v2du __attribute__ ((__vector_size__ (16)));
  10. typedef long long __v2di __attribute__ ((__vector_size__ (16)));
  11. typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
  12. extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  13. _mm_shuffle_epi32 (__m128i __A, const int __mask)
  14. {
  15. return (__m128i)__builtin_ia32_pshufd ((__v4si)__A, __mask);
  16. }
  17. extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  18. _mm_slli_si128 (__m128i __A, const int __N)
  19. {
  20. return (__m128i)__builtin_ia32_pslldqi128 (__A, __N * 8);
  21. }
  22. extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  23. _mm_xor_si128 (__m128i __A, __m128i __B)
  24. {
  25. return (__m128i) ((__v2du)__A ^ (__v2du)__B);
  26. }
  27. extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  28. _mm_aeskeygenassist_si128 (__m128i __X, const int __C)
  29. {
  30. return (__m128i) __builtin_ia32_aeskeygenassist128 ((__v2di)__X, __C);
  31. }
  32. extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  33. _mm_aesenc_si128 (__m128i __X, __m128i __Y)
  34. {
  35. return (__m128i) __builtin_ia32_aesenc128 ((__v2di)__X, (__v2di)__Y);
  36. }
  37. extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  38. _mm_aesenclast_si128 (__m128i __X, __m128i __Y)
  39. {
  40. return (__m128i) __builtin_ia32_aesenclast128 ((__v2di)__X, (__v2di)__Y);
  41. }
  42. extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  43. _mm_set_epi64x (long long __q1, long long __q0)
  44. {
  45. return __extension__ (__m128i)(__v2di){ __q0, __q1 };
  46. }
  47. using AESkey = __m128i[11];
  48. static inline __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2)
  49. {
  50. __m128i temp3;
  51. temp2 = _mm_shuffle_epi32 (temp2 ,0xff);
  52. temp3 = _mm_slli_si128 (temp1, 0x4);
  53. temp1 = _mm_xor_si128 (temp1, temp3);
  54. temp3 = _mm_slli_si128 (temp3, 0x4);
  55. temp1 = _mm_xor_si128 (temp1, temp3);
  56. temp3 = _mm_slli_si128 (temp3, 0x4);
  57. temp1 = _mm_xor_si128 (temp1, temp3);
  58. temp1 = _mm_xor_si128 (temp1, temp2);
  59. return temp1;
  60. }
  61. static inline void AES_128_Key_Expansion (AESkey &key, __m128i rawkey)
  62. {
  63. __m128i temp1, temp2;
  64. __m128i *Key_Schedule = key;
  65. temp1 = rawkey;
  66. Key_Schedule[0] = temp1;
  67. temp2 = _mm_aeskeygenassist_si128 (temp1 ,0x1);
  68. temp1 = AES_128_ASSIST(temp1, temp2);
  69. Key_Schedule[1] = temp1;
  70. temp2 = _mm_aeskeygenassist_si128 (temp1,0x2);
  71. temp1 = AES_128_ASSIST(temp1, temp2);
  72. Key_Schedule[2] = temp1;
  73. temp2 = _mm_aeskeygenassist_si128 (temp1,0x4);
  74. temp1 = AES_128_ASSIST(temp1, temp2);
  75. Key_Schedule[3] = temp1;
  76. temp2 = _mm_aeskeygenassist_si128 (temp1,0x8);
  77. temp1 = AES_128_ASSIST(temp1, temp2);
  78. Key_Schedule[4] = temp1;
  79. temp2 = _mm_aeskeygenassist_si128 (temp1,0x10);
  80. temp1 = AES_128_ASSIST(temp1, temp2);
  81. Key_Schedule[5] = temp1;
  82. temp2 = _mm_aeskeygenassist_si128 (temp1,0x20);
  83. temp1 = AES_128_ASSIST(temp1, temp2);
  84. Key_Schedule[6] = temp1;
  85. temp2 = _mm_aeskeygenassist_si128 (temp1,0x40);
  86. temp1 = AES_128_ASSIST(temp1, temp2);
  87. Key_Schedule[7] = temp1;
  88. temp2 = _mm_aeskeygenassist_si128 (temp1,0x80);
  89. temp1 = AES_128_ASSIST(temp1, temp2);
  90. Key_Schedule[8] = temp1;
  91. temp2 = _mm_aeskeygenassist_si128 (temp1,0x1b);
  92. temp1 = AES_128_ASSIST(temp1, temp2);
  93. Key_Schedule[9] = temp1;
  94. temp2 = _mm_aeskeygenassist_si128 (temp1,0x36);
  95. temp1 = AES_128_ASSIST(temp1, temp2);
  96. Key_Schedule[10] = temp1;
  97. }
  98. static inline void AES_ECB_encrypt(__m128i &ciphertext, __m128i plaintext,
  99. const AESkey &key)
  100. {
  101. __m128i tmp;
  102. int j;
  103. tmp = plaintext;
  104. tmp = _mm_xor_si128 (tmp,key[0]);
  105. for(j=1; j<10; j++){
  106. tmp = _mm_aesenc_si128 (tmp,key[j]);
  107. }
  108. tmp = _mm_aesenclast_si128 (tmp,key[j]);
  109. ciphertext=tmp;
  110. }
  111. #endif