@@ -629,13 +629,14 @@ endfunction()
629629if (FIPS_SHARED)
630630 # Rewrite libcrypto.so, libcrypto.dylib, or crypto.dll to inject the correct module
631631 # hash value. For now we support the FIPS build only on Linux, macOS, iOS, and Windows.
632- if (MSVC )
633- # On Windows, inject_hash.go parses the PE DLL to find the .fipstx and
634- # .fipsco sections, computes the integrity hash, and replaces the
635- # placeholder value directly in the DLL file. This single-DLL approach
636- # avoids the hash mismatch that occurs with the two-DLL capture_hash
637- # method on ARM64 where mandatory ASLR causes the linker to resolve
638- # COFF relocations to different addresses in precrypto.dll vs crypto.dll.
632+ if (MSVC AND ARCH STREQUAL "aarch64" )
633+ # On ARM64 Windows, ASLR is mandatory and cannot be disabled. The linker
634+ # resolves COFF relocations to different addresses when building two
635+ # separate DLLs (precrypto.dll vs crypto.dll), so the two-DLL
636+ # capture_hash approach produces a hash mismatch. Instead we use
637+ # inject_hash.go which parses the single crypto.dll PE file, finds the
638+ # .fipstx and .fipsco sections, computes the integrity hash from the
639+ # on-disk content, and replaces the placeholder value directly in the file.
639640 build_libcrypto (NAME crypto MODULE_SOURCE $<TARGET_OBJECTS :fipsmodule > SET_OUTPUT_NAME )
640641
641642 add_custom_command (
@@ -645,6 +646,34 @@ if(FIPS_SHARED)
645646 -o $<TARGET_FILE :crypto > -in-object $<TARGET_FILE :crypto >
646647 WORKING_DIRECTORY ${AWSLC_SOURCE_DIR}
647648 )
649+ elseif (MSVC )
650+ # On x64 Windows we use capture_hash.go to capture the computed integrity
651+ # value that the module prints on its first (failing) run, then embed that
652+ # value in generated_fips_shared_support.c for the final crypto.dll.
653+ # See FIPS.md for a full explanation of the process.
654+ build_libcrypto (NAME precrypto MODULE_SOURCE $<TARGET_OBJECTS :fipsmodule >)
655+ add_executable (fips_empty_main fipsmodule/fips_empty_main.c )
656+ target_link_libraries (fips_empty_main PUBLIC precrypto )
657+ target_add_awslc_include_paths (TARGET fips_empty_main SCOPE PRIVATE )
658+ add_custom_command (OUTPUT generated_fips_shared_support.c
659+ COMMAND ${GO_EXECUTABLE} run
660+ ${AWSLC_SOURCE_DIR} /util/fipstools/capture_hash/capture_hash.go
661+ -in-executable $<TARGET_FILE :fips_empty_main > > generated_fips_shared_support.c
662+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
663+ DEPENDS fips_empty_main ${AWSLC_SOURCE_DIR} /util/fipstools/capture_hash/capture_hash.go
664+ )
665+ add_library (
666+ generated_fipsmodule
667+
668+ OBJECT
669+
670+ generated_fips_shared_support.c
671+ ${AWSLC_SOURCE_DIR} /crypto/fipsmodule/cpucap/cpucap.c
672+ )
673+ target_compile_definitions (generated_fipsmodule PRIVATE BORINGSSL_IMPLEMENTATION S2N_BN_HIDE_SYMBOLS )
674+ target_add_awslc_include_paths (TARGET generated_fipsmodule SCOPE PRIVATE )
675+
676+ build_libcrypto (NAME crypto MODULE_SOURCE $<TARGET_OBJECTS :generated_fipsmodule > SET_OUTPUT_NAME )
648677 else ()
649678 # On Apple and Linux platforms inject_hash.go can parse libcrypto and inject
650679 # the hash directly into the final library.
0 commit comments