CMakeLists.txt 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. add_sources_from_current_dir(crypto
  2. aes-common.c
  3. aes-select.c
  4. aes-sw.c
  5. aesgcm-common.c
  6. aesgcm-select.c
  7. aesgcm-sw.c
  8. aesgcm-ref-poly.c
  9. arcfour.c
  10. argon2.c
  11. bcrypt.c
  12. blake2.c
  13. blowfish.c
  14. chacha20-poly1305.c
  15. crc32.c
  16. des.c
  17. diffie-hellman.c
  18. dsa.c
  19. ecc-arithmetic.c
  20. ecc-ssh.c
  21. hash_simple.c
  22. hmac.c
  23. kex-hybrid.c
  24. mac.c
  25. mac_simple.c
  26. md5.c
  27. mlkem.c
  28. mpint.c
  29. ntru.c
  30. openssh-certs.c
  31. prng.c
  32. pubkey-pem.c
  33. pubkey-ppk.c
  34. pubkey-ssh1.c
  35. rfc6979.c
  36. rsa.c
  37. sha256-common.c
  38. sha256-select.c
  39. sha256-sw.c
  40. sha512-common.c
  41. sha512-select.c
  42. sha512-sw.c
  43. sha3.c
  44. sha1-common.c
  45. sha1-select.c
  46. sha1-sw.c
  47. xdmauth.c)
  48. include(CheckCSourceCompiles)
  49. function(test_compile_with_flags outvar)
  50. cmake_parse_arguments(OPT "" ""
  51. "GNU_FLAGS;MSVC_FLAGS;ADD_SOURCES_IF_SUCCESSFUL;TEST_SOURCE" "${ARGN}")
  52. # Figure out what flags are applicable to this compiler.
  53. set(flags)
  54. if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR
  55. CMAKE_C_COMPILER_ID MATCHES "Clang")
  56. set(flags ${OPT_GNU_FLAGS})
  57. endif()
  58. if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
  59. set(flags ${OPT_MSVC_FLAGS})
  60. endif()
  61. # See if we can compile the provided test program.
  62. foreach(i ${flags})
  63. set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${i}")
  64. endforeach()
  65. check_c_source_compiles("${OPT_TEST_SOURCE}" "${outvar}")
  66. if(${outvar} AND OPT_ADD_SOURCES_IF_SUCCESSFUL)
  67. # Make an object library that compiles the implementation with the
  68. # necessary flags, and add the resulting objects to the crypto
  69. # library.
  70. set(libname object_lib_${outvar})
  71. add_library(${libname} OBJECT ${OPT_ADD_SOURCES_IF_SUCCESSFUL})
  72. target_compile_options(${libname} PRIVATE ${flags})
  73. target_sources(crypto PRIVATE $<TARGET_OBJECTS:${libname}>)
  74. endif()
  75. # Export the output to the caller's scope, so that further tests can
  76. # be based on it.
  77. set(${outvar} ${${outvar}} PARENT_SCOPE)
  78. endfunction()
  79. # ----------------------------------------------------------------------
  80. # Try to enable x86 intrinsics-based crypto implementations.
  81. test_compile_with_flags(HAVE_WMMINTRIN_H
  82. GNU_FLAGS -msse4.1
  83. TEST_SOURCE "
  84. #include <wmmintrin.h>
  85. #include <smmintrin.h>
  86. volatile __m128i r, a, b;
  87. int main(void) { r = _mm_xor_si128(a, b); }")
  88. if(HAVE_WMMINTRIN_H)
  89. test_compile_with_flags(HAVE_AES_NI
  90. GNU_FLAGS -msse4.1 -maes
  91. TEST_SOURCE "
  92. #include <wmmintrin.h>
  93. #include <smmintrin.h>
  94. volatile __m128i r, a, b;
  95. int main(void) { r = _mm_aesenc_si128(a, b); }"
  96. ADD_SOURCES_IF_SUCCESSFUL aes-ni aes-ni.c)
  97. # shaintrin.h doesn't exist on all compilers; sometimes it's folded
  98. # into the other headers
  99. test_compile_with_flags(HAVE_SHAINTRIN_H
  100. GNU_FLAGS -msse4.1 -msha
  101. TEST_SOURCE "
  102. #include <wmmintrin.h>
  103. #include <smmintrin.h>
  104. #include <immintrin.h>
  105. #include <shaintrin.h>
  106. volatile __m128i r, a, b;
  107. int main(void) { r = _mm_xor_si128(a, b); }")
  108. if(HAVE_SHAINTRIN_H)
  109. set(include_shaintrin "#include <shaintrin.h>")
  110. else()
  111. set(include_shaintrin "")
  112. endif()
  113. test_compile_with_flags(HAVE_SHA_NI
  114. GNU_FLAGS -msse4.1 -msha
  115. TEST_SOURCE "
  116. #include <wmmintrin.h>
  117. #include <smmintrin.h>
  118. #include <immintrin.h>
  119. ${include_shaintrin}
  120. volatile __m128i r, a, b, c;
  121. int main(void) { r = _mm_sha256rnds2_epu32(a, b, c); }"
  122. ADD_SOURCES_IF_SUCCESSFUL sha256-ni.c sha1-ni.c)
  123. test_compile_with_flags(HAVE_CLMUL
  124. GNU_FLAGS -msse4.1 -mpclmul
  125. TEST_SOURCE "
  126. #include <wmmintrin.h>
  127. #include <tmmintrin.h>
  128. volatile __m128i r, a, b;
  129. int main(void) { r = _mm_clmulepi64_si128(a, b, 5);
  130. r = _mm_shuffle_epi8(r, a); }"
  131. ADD_SOURCES_IF_SUCCESSFUL aesgcm-clmul.c)
  132. endif()
  133. # ----------------------------------------------------------------------
  134. # Try to enable Arm Neon intrinsics-based crypto implementations.
  135. # Start by checking which header file we need. ACLE specifies that it
  136. # ought to be <arm_neon.h>, on both 32- and 64-bit Arm, but Visual
  137. # Studio for some reason renamed the header to <arm64_neon.h> in
  138. # 64-bit, and gives an error if you use the standard name. (However,
  139. # clang-cl does let you use the standard name.)
  140. test_compile_with_flags(HAVE_ARM_NEON_H
  141. MSVC_FLAGS -D_ARM_USE_NEW_NEON_INTRINSICS
  142. TEST_SOURCE "
  143. #include <arm_neon.h>
  144. volatile uint8x16_t r, a, b;
  145. int main(void) { r = veorq_u8(a, b); }")
  146. if(HAVE_ARM_NEON_H)
  147. set(neon ON)
  148. set(neon_header "arm_neon.h")
  149. else()
  150. test_compile_with_flags(HAVE_ARM64_NEON_H TEST_SOURCE "
  151. #include <arm64_neon.h>
  152. volatile uint8x16_t r, a, b;
  153. int main(void) { r = veorq_u8(a, b); }")
  154. if(HAVE_ARM64_NEON_H)
  155. set(neon ON)
  156. set(neon_header "arm64_neon.h")
  157. set(USE_ARM64_NEON_H ON)
  158. endif()
  159. endif()
  160. if(neon)
  161. # If we have _some_ NEON header, look for the individual things we
  162. # can enable with it.
  163. # The 'crypto' architecture extension includes support for AES,
  164. # SHA-1, and SHA-256.
  165. test_compile_with_flags(HAVE_NEON_CRYPTO
  166. GNU_FLAGS -march=armv8-a+crypto
  167. MSVC_FLAGS -D_ARM_USE_NEW_NEON_INTRINSICS
  168. TEST_SOURCE "
  169. #include <${neon_header}>
  170. volatile uint8x16_t r, a, b;
  171. volatile uint32x4_t s, x, y, z;
  172. int main(void) { r = vaeseq_u8(a, b); s = vsha256hq_u32(x, y, z); }"
  173. ADD_SOURCES_IF_SUCCESSFUL aes-neon.c sha256-neon.c sha1-neon.c)
  174. test_compile_with_flags(HAVE_NEON_PMULL
  175. GNU_FLAGS -march=armv8-a+crypto
  176. MSVC_FLAGS -D_ARM_USE_NEW_NEON_INTRINSICS
  177. TEST_SOURCE "
  178. #include <${neon_header}>
  179. volatile poly128_t r;
  180. volatile poly64_t a, b;
  181. volatile poly64x2_t u, v;
  182. int main(void) { r = vmull_p64(a, b); r = vmull_high_p64(u, v); }"
  183. ADD_SOURCES_IF_SUCCESSFUL aesgcm-neon.c)
  184. test_compile_with_flags(HAVE_NEON_VADDQ_P128
  185. GNU_FLAGS -march=armv8-a+crypto
  186. MSVC_FLAGS -D_ARM_USE_NEW_NEON_INTRINSICS
  187. TEST_SOURCE "
  188. #include <${neon_header}>
  189. volatile poly128_t r;
  190. int main(void) { r = vaddq_p128(r, r); }")
  191. # The 'sha3' architecture extension, despite the name, includes
  192. # support for SHA-512 (from the SHA-2 standard) as well as SHA-3
  193. # proper.
  194. #
  195. # Versions of clang up to and including clang 12 support this
  196. # extension in assembly language, but not the ACLE intrinsics for
  197. # it. So we check both.
  198. test_compile_with_flags(HAVE_NEON_SHA512_INTRINSICS
  199. GNU_FLAGS -march=armv8.2-a+crypto+sha3
  200. TEST_SOURCE "
  201. #include <${neon_header}>
  202. volatile uint64x2_t r, a, b;
  203. int main(void) { r = vsha512su0q_u64(a, b); }"
  204. ADD_SOURCES_IF_SUCCESSFUL sha512-neon.c)
  205. if(HAVE_NEON_SHA512_INTRINSICS)
  206. set(HAVE_NEON_SHA512 ON)
  207. else()
  208. test_compile_with_flags(HAVE_NEON_SHA512_ASM
  209. GNU_FLAGS -march=armv8.2-a+crypto+sha3
  210. TEST_SOURCE "
  211. #include <${neon_header}>
  212. volatile uint64x2_t r, a;
  213. int main(void) { __asm__(\"sha512su0 %0.2D,%1.2D\" : \"+w\" (r) : \"w\" (a)); }"
  214. ADD_SOURCES_IF_SUCCESSFUL sha512-neon.c)
  215. if(HAVE_NEON_SHA512_ASM)
  216. set(HAVE_NEON_SHA512 ON)
  217. endif()
  218. endif()
  219. endif()
  220. test_compile_with_flags(HAVE_ARM_DIT
  221. GNU_FLAGS -march=armv8.4-a
  222. TEST_SOURCE "
  223. int main(void) { asm volatile(\"msr dit, %0\" :: \"r\"(1)); }"
  224. ADD_SOURCES_IF_SUCCESSFUL enable_dit.c)
  225. set(HAVE_AES_NI ${HAVE_AES_NI} PARENT_SCOPE)
  226. set(HAVE_SHA_NI ${HAVE_SHA_NI} PARENT_SCOPE)
  227. set(HAVE_SHAINTRIN_H ${HAVE_SHAINTRIN_H} PARENT_SCOPE)
  228. set(HAVE_NEON_CRYPTO ${HAVE_NEON_CRYPTO} PARENT_SCOPE)
  229. set(HAVE_NEON_SHA512 ${HAVE_NEON_SHA512} PARENT_SCOPE)
  230. set(HAVE_NEON_SHA512_INTRINSICS ${HAVE_NEON_SHA512_INTRINSICS} PARENT_SCOPE)
  231. set(USE_ARM64_NEON_H ${USE_ARM64_NEON_H} PARENT_SCOPE)
  232. set(HAVE_ARM_DIT ${HAVE_ARM_DIT} PARENT_SCOPE)