rijndael-internal.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* Rijndael (AES) for GnuPG
  2. * Copyright (C) 2000, 2001, 2002, 2003, 2007,
  3. * 2008, 2011, 2012 Free Software Foundation, Inc.
  4. *
  5. * This file is part of Libgcrypt.
  6. *
  7. * Libgcrypt is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * Libgcrypt is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef G10_RIJNDAEL_INTERNAL_H
  21. #define G10_RIJNDAEL_INTERNAL_H
  22. #include "types.h" /* for byte and u32 typedefs */
  23. #define MAXKC (256/32)
  24. #define MAXROUNDS 14
  25. #define BLOCKSIZE (128/8)
  26. /* Helper macro to force alignment to 16 or 64 bytes. */
  27. #ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
  28. # define ATTR_ALIGNED_16 __attribute__ ((aligned (16)))
  29. # define ATTR_ALIGNED_64 __attribute__ ((aligned (64)))
  30. #else
  31. # define ATTR_ALIGNED_16
  32. # define ATTR_ALIGNED_64
  33. #endif
  34. /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */
  35. #undef USE_AMD64_ASM
  36. #if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
  37. defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
  38. # define USE_AMD64_ASM 1
  39. #endif
  40. /* USE_SSSE3 indicates whether to use SSSE3 code. */
  41. #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
  42. (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
  43. defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
  44. # define USE_SSSE3 1
  45. #endif
  46. /* USE_ARM_ASM indicates whether to use ARM assembly code. */
  47. #undef USE_ARM_ASM
  48. #if defined(__ARMEL__)
  49. # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
  50. # define USE_ARM_ASM 1
  51. # endif
  52. #endif
  53. #if defined(__AARCH64EL__)
  54. # ifdef HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS
  55. # define USE_ARM_ASM 1
  56. # endif
  57. #endif
  58. /* USE_PADLOCK indicates whether to compile the padlock specific
  59. code. */
  60. #undef USE_PADLOCK
  61. #ifdef ENABLE_PADLOCK_SUPPORT
  62. # ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
  63. # if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)
  64. # define USE_PADLOCK 1
  65. # endif
  66. # endif
  67. #endif /* ENABLE_PADLOCK_SUPPORT */
  68. /* USE_AESNI inidicates whether to compile with Intel AES-NI code. We
  69. need the vector-size attribute which seems to be available since
  70. gcc 3. However, to be on the safe side we require at least gcc 4. */
  71. #undef USE_AESNI
  72. #ifdef ENABLE_AESNI_SUPPORT
  73. # if ((defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
  74. # if __GNUC__ >= 4
  75. # define USE_AESNI 1
  76. # endif
  77. # endif
  78. #endif /* ENABLE_AESNI_SUPPORT */
  79. /* USE_VAES inidicates whether to compile with AMD64 VAES code. */
  80. #undef USE_VAES
  81. #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
  82. defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
  83. defined(__x86_64__) && defined(ENABLE_AVX2_SUPPORT) && \
  84. defined(HAVE_GCC_INLINE_ASM_VAES_VPCLMUL) && \
  85. defined(USE_AESNI)
  86. # define USE_VAES 1
  87. #endif
  88. /* USE_VAES_I386 inidicates whether to compile with i386 VAES code. */
  89. #undef USE_VAES_I386
  90. #if (defined(HAVE_COMPATIBLE_GCC_I386_PLATFORM_AS) || \
  91. defined(HAVE_COMPATIBLE_GCC_WIN32_PLATFORM_AS)) && \
  92. defined(__i386__) && defined(ENABLE_AVX2_SUPPORT) && \
  93. defined(HAVE_GCC_INLINE_ASM_VAES_VPCLMUL) && \
  94. defined(USE_AESNI)
  95. # define USE_VAES_I386 1
  96. #endif
  97. /* USE_ARM_CE indicates whether to enable ARMv8 Crypto Extension assembly
  98. * code. */
  99. #undef USE_ARM_CE
  100. #ifdef ENABLE_ARM_CRYPTO_SUPPORT
  101. # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
  102. && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
  103. && defined(HAVE_GCC_INLINE_ASM_AARCH32_CRYPTO)
  104. # define USE_ARM_CE 1
  105. # elif defined(__AARCH64EL__) \
  106. && defined(HAVE_COMPATIBLE_GCC_AARCH64_PLATFORM_AS) \
  107. && defined(HAVE_GCC_INLINE_ASM_AARCH64_CRYPTO)
  108. # define USE_ARM_CE 1
  109. # endif
  110. #endif /* ENABLE_ARM_CRYPTO_SUPPORT */
  111. /* USE_PPC_CRYPTO indicates whether to enable PowerPC vector crypto
  112. * accelerated code. USE_PPC_CRYPTO_WITH_PPC9LE indicates whether to
  113. * enable POWER9 optimized variant. */
  114. #undef USE_PPC_CRYPTO
  115. #undef USE_PPC_CRYPTO_WITH_PPC9LE
  116. #ifdef ENABLE_PPC_CRYPTO_SUPPORT
  117. # if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \
  118. defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC)
  119. # if __GNUC__ >= 4
  120. # define USE_PPC_CRYPTO 1
  121. # if !defined(WORDS_BIGENDIAN) && defined(HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00)
  122. # define USE_PPC_CRYPTO_WITH_PPC9LE 1
  123. # endif
  124. # endif
  125. # endif
  126. #endif /* ENABLE_PPC_CRYPTO_SUPPORT */
  127. /* USE_S390X_CRYPTO indicates whether to enable zSeries code. */
  128. #undef USE_S390X_CRYPTO
  129. #if defined(HAVE_GCC_INLINE_ASM_S390X)
  130. # define USE_S390X_CRYPTO 1
  131. #endif /* USE_S390X_CRYPTO */
  132. struct RIJNDAEL_context_s;
  133. typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx,
  134. unsigned char *bx,
  135. const unsigned char *ax);
  136. typedef void (*rijndael_prefetchfn_t)(void);
  137. typedef void (*rijndael_prepare_decfn_t)(struct RIJNDAEL_context_s *ctx);
  138. /* Our context object. */
  139. typedef struct RIJNDAEL_context_s
  140. {
  141. /* The first fields are the keyschedule arrays. This is so that
  142. they are aligned on a 16 byte boundary if using gcc. This
  143. alignment is required for the AES-NI code and a good idea in any
  144. case. The alignment is guaranteed due to the way cipher.c
  145. allocates the space for the context. The PROPERLY_ALIGNED_TYPE
  146. hack is used to force a minimal alignment if not using gcc of if
  147. the alignment requirement is higher that 16 bytes. */
  148. union
  149. {
  150. PROPERLY_ALIGNED_TYPE dummy;
  151. byte keyschedule[MAXROUNDS+1][4][4];
  152. u32 keyschedule32[MAXROUNDS+1][4];
  153. u32 keyschedule32b[(MAXROUNDS+1)*4];
  154. #ifdef USE_PADLOCK
  155. /* The key as passed to the padlock engine. It is only used if
  156. the padlock engine is used (USE_PADLOCK, below). */
  157. unsigned char padlock_key[16] __attribute__ ((aligned (16)));
  158. #endif /*USE_PADLOCK*/
  159. } u1;
  160. union
  161. {
  162. PROPERLY_ALIGNED_TYPE dummy;
  163. byte keyschedule[MAXROUNDS+1][4][4];
  164. u32 keyschedule32[MAXROUNDS+1][4];
  165. } u2;
  166. int rounds; /* Key-length-dependent number of rounds. */
  167. unsigned int decryption_prepared:1; /* The decryption key schedule is available. */
  168. #ifdef USE_AESNI
  169. unsigned int use_avx:1; /* AVX shall be used by AES-NI implementation. */
  170. unsigned int use_avx2:1; /* AVX2 shall be used by AES-NI implementation. */
  171. #endif /*USE_AESNI*/
  172. #ifdef USE_S390X_CRYPTO
  173. byte km_func;
  174. byte km_func_xts;
  175. byte kmc_func;
  176. byte kmac_func;
  177. byte kmf_func;
  178. byte kmo_func;
  179. byte kma_func;
  180. #endif /*USE_S390X_CRYPTO*/
  181. rijndael_cryptfn_t encrypt_fn;
  182. rijndael_cryptfn_t decrypt_fn;
  183. rijndael_prefetchfn_t prefetch_enc_fn;
  184. rijndael_prefetchfn_t prefetch_dec_fn;
  185. rijndael_prepare_decfn_t prepare_decryption;
  186. } RIJNDAEL_context ATTR_ALIGNED_16;
  187. /* Macros defining alias for the keyschedules. */
  188. #define keyschenc u1.keyschedule
  189. #define keyschenc32 u1.keyschedule32
  190. #define keyschenc32b u1.keyschedule32b
  191. #define keyschdec u2.keyschedule
  192. #define keyschdec32 u2.keyschedule32
  193. #define padlockkey u1.padlock_key
  194. #endif /* G10_RIJNDAEL_INTERNAL_H */