@@ -2177,8 +2177,7 @@ else()
21772177 endif ()
21782178endif ()
21792179
2180- # TODO: - AES-XTS
2181- # - Web server
2180+ # TODO: - Web server
21822181# - Web client
21832182add_option ("WOLFSSL_CMAC"
21842183 "Enable CMAC (default: disabled)"
@@ -2763,10 +2762,128 @@ if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64|AMD64")
27632762 set (WOLFSSL_X86_64_BUILD ON )
27642763 add_option ("WOLFSSL_X86_64_BUILD_ASM" "Build ASM files" "yes" "yes;no" )
27652764 list (APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_X86_64_BUILD" )
2765+ elseif ("${CMAKE_SYSTEM_PROCESSOR } " MATCHES "^(i[3-6]86|x86)$" )
2766+ # 32-bit x86. The distinction matters beyond the define: the AES-GCM
2767+ # speedup has its OWN assembly there (aes_gcm_x86_asm.S) rather than a
2768+ # 32-bit build of the x86-64 one, which is what BUILD_X86_ASM selects
2769+ # below - the same split autotools makes with ENABLED_X86_ASM.
2770+ set (WOLFSSL_X86_BUILD ON )
2771+ list (APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_X86_BUILD" )
27662772elseif ("${CMAKE_SYSTEM_PROCESSOR } " MATCHES "aarch64|arm64" )
27672773 list (APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AARCH64_BUILD" )
27682774endif ()
27692775
2776+ # Intel assembly speedups. cmake/functions.cmake already selects the asm
2777+ # sources from this variable; declaring it makes it discoverable and gives it
2778+ # a default. USE_INTEL_SPEEDUP is what makes the C dispatch to those sources -
2779+ # without it they compile but nothing ever calls them.
2780+ add_option ("WOLFSSL_INTEL_ASM"
2781+ "Enable Intel assembly speedups (default: disabled)"
2782+ "no" "yes;no" )
2783+
2784+ if (WOLFSSL_INTEL_ASM)
2785+ list (APPEND WOLFSSL_DEFINITIONS "-DUSE_INTEL_SPEEDUP" )
2786+ endif ()
2787+
2788+ # AES-NI. Same shape: functions.cmake already reads WOLFSSL_AESNI to select
2789+ # the AES assembly, but WOLFSSL_AESNI has to reach the compiler as well or
2790+ # aes.c leaves every AES-NI path out and the assembly it does build is never
2791+ # called. --enable-intelasm implies it in the autotools build; match that.
2792+ add_option ("WOLFSSL_AESNI"
2793+ "Enable AES-NI (default: disabled)"
2794+ "no" "yes;no" )
2795+
2796+ if (WOLFSSL_AESNI OR WOLFSSL_INTEL_ASM)
2797+ # x86 only. Both the define and the -maes below are meaningless
2798+ # elsewhere, and -maes lands on CMAKE_C_FLAGS for the library AND every
2799+ # example and test target, so a cross compiler rejects the whole build.
2800+ # Fail with a clear message instead, as WOLFSSL_INTELASM_INTRINSICS and
2801+ # WOLFSSL_FALCON_ASM do below.
2802+ if (NOT WOLFSSL_X86_64_BUILD AND NOT WOLFSSL_X86_BUILD)
2803+ message (FATAL_ERROR
2804+ "WOLFSSL_AESNI / WOLFSSL_INTEL_ASM are x86 only" )
2805+ endif ()
2806+ set (WOLFSSL_AESNI "yes" )
2807+ list (APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AESNI" )
2808+ # aes.c uses AES-NI intrinsics directly in the key schedule, so the
2809+ # instructions have to be available to the compiler, not just to the
2810+ # assembler. A flag, not a define, so it goes on CMAKE_C_FLAGS rather
2811+ # than WOLFSSL_DEFINITIONS. This is an ISA the runtime dispatch already
2812+ # requires before calling in, so it does not widen what any dispatched
2813+ # routine may use.
2814+ if (NOT CMAKE_C_COMPILER_ID STREQUAL "MSVC" )
2815+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS } -maes" )
2816+ endif ()
2817+ endif ()
2818+
2819+ # AES-XTS. The XTS assembly is wrapped in WOLFSSL_AES_XTS, so without this
2820+ # option the file is an empty translation unit.
2821+ add_option ("WOLFSSL_AESXTS"
2822+ "Enable AES-XTS (default: disabled)"
2823+ "no" "yes;no" )
2824+
2825+ if (WOLFSSL_AESXTS)
2826+ list (APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AES_XTS" )
2827+ # --enable-aesxts also turns the streaming API on by default for
2828+ # non-ARMASM builds (configure.ac defaults ENABLED_AESXTS_STREAM from
2829+ # ENABLED_AESXTS). Without this, cmake -DWOLFSSL_AESXTS=yes silently
2830+ # gives a smaller API than the autotools equivalent - no
2831+ # wc_AesXtsEncryptInit/Update/Final - which breaks the documented
2832+ # --enable-foo == -DWOLFSSL_FOO=yes mapping.
2833+ if (NOT WOLFSSL_ARM_ASM)
2834+ list (APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AESXTS_STREAM" )
2835+ endif ()
2836+ endif ()
2837+
2838+ # Build the Intel speedups from the generated C intrinsics rather than from
2839+ # the generated assembly. Both come out of one generator, so the two forms
2840+ # compute the same thing; the C form is visible to the optimiser, to LTO and
2841+ # to the sanitisers. Coverage is per algorithm - anything without an
2842+ # intrinsics translation keeps building from assembly.
2843+ # Falcon's floating-point backend. Falcon needs binary64 arithmetic that is
2844+ # bit-exact everywhere it runs, so the fpr layer is written in SSE2 rather
2845+ # than left to the compiler; this is autotools' --enable-falcon=asm. It is
2846+ # x86-64 only, and it selects a different fpr representation from the
2847+ # native-double backends, which is why those are mutually exclusive there.
2848+ add_option ("WOLFSSL_FALCON_ASM"
2849+ "Build Falcon's fpr layer from the generated x86-64 assembly (default: disabled)"
2850+ "no" "yes;no" )
2851+
2852+ if (WOLFSSL_FALCON_ASM)
2853+ if (NOT WOLFSSL_FALCON)
2854+ message (FATAL_ERROR "WOLFSSL_FALCON_ASM requires WOLFSSL_FALCON" )
2855+ endif ()
2856+ if (NOT WOLFSSL_X86_64_BUILD)
2857+ message (FATAL_ERROR "WOLFSSL_FALCON_ASM is x86-64 only" )
2858+ endif ()
2859+ list (APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_FALCON_FPR_ASM" )
2860+ set_wolfssl_definitions ("WOLFSSL_FALCON_FPR_ASM" RESULT )
2861+ endif ()
2862+
2863+ add_option ("WOLFSSL_INTELASM_INTRINSICS"
2864+ "Build the x86-64 speedups from generated C intrinsics rather than assembly (default: disabled)"
2865+ "no" "yes;no" )
2866+
2867+ if (WOLFSSL_INTELASM_INTRINSICS)
2868+ if (NOT WOLFSSL_INTEL_ASM)
2869+ message (FATAL_ERROR
2870+ "WOLFSSL_INTELASM_INTRINSICS requires WOLFSSL_INTEL_ASM" )
2871+ endif ()
2872+ if (NOT WOLFSSL_X86_64_BUILD)
2873+ message (FATAL_ERROR "WOLFSSL_INTELASM_INTRINSICS is x86-64 only" )
2874+ endif ()
2875+ # Unlike the assembly it replaces, this code is compiled, and CMake adds
2876+ # no -O of its own unless a build type asks for one. At -O0 the generated
2877+ # SHA-256 runs several times slower than the assembly rather than at
2878+ # parity, which reads as the intrinsics being slow instead of unoptimised.
2879+ if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS MATCHES "-O" )
2880+ message (WARNING
2881+ "WOLFSSL_INTELASM_INTRINSICS with no CMAKE_BUILD_TYPE: the "
2882+ "generated C compiles unoptimised and will be far slower than "
2883+ "the assembly. Use -DCMAKE_BUILD_TYPE=Release." )
2884+ endif ()
2885+ endif ()
2886+
27702887# SP math all
27712888add_option ("WOLFSSL_SP_MATH_ALL"
27722889 "Enable Single Precision math implementation for full algorithm suite (default: enabled)"
@@ -4223,6 +4340,32 @@ endif()
42234340
42244341add_library (wolfssl::wolfssl ALIAS wolfssl )
42254342
4343+ # The generated x86-64 intrinsics are a literal transliteration of the assembly
4344+ # - one C statement per instruction - so their functions are enormous.
4345+ # Unoptimised, the compiler gives every intermediate its own stack slot and
4346+ # never reuses one: mlkem_encapsulate_avx512 gets a 718KB frame on gcc and
4347+ # 1.9MB on clang, enough to overflow a thread stack. At -O1 and above the slots
4348+ # are shared and the frame drops to about 2KB. CMake emits no -O at all when
4349+ # CMAKE_BUILD_TYPE is unset, which is the default, so force the level on just
4350+ # these sources - not on the rest of the library, whose flags stay the user's.
4351+ # Override with -DWOLFSSL_INTRIN_OPT=-O2 if you want a different level.
4352+ set (WOLFSSL_INTRIN_OPT "" CACHE STRING
4353+ "Optimisation flag for the generated *_intrin.c files (default -O1, /O1 on MSVC)" )
4354+ if (NOT WOLFSSL_INTRIN_OPT)
4355+ if (MSVC )
4356+ set (WOLFSSL_INTRIN_OPT "/O1" )
4357+ else ()
4358+ set (WOLFSSL_INTRIN_OPT "-O1" )
4359+ endif ()
4360+ endif ()
4361+ foreach (_intrin_src ${LIB_SOURCES} )
4362+ if (_intrin_src MATCHES "_intrin\\ .c$" )
4363+ set_source_files_properties ("${_intrin_src} " PROPERTIES
4364+ COMPILE_OPTIONS "${WOLFSSL_INTRIN_OPT} " )
4365+ endif ()
4366+ endforeach ()
4367+ unset (_intrin_src)
4368+
42264369if (NOT "$ENV{ARIA_DIR} " STREQUAL "" )
42274370 message (STATUS "Found Environment variable ARIA_DIR=$ENV{ARIA_DIR} " )
42284371 if (WOLFSSL_ARIA)
0 commit comments