From 1ec9e7ec98965c7c03eb2a276f3a450f11c88cb7 Mon Sep 17 00:00:00 2001 From: Tobias Brick Date: Sat, 12 Oct 2024 17:18:22 +0000 Subject: [PATCH] add SymCrypt-debuginfo package --- ...to-prevent-stripping-and-post-proces.patch | 108 ++++++++++++++++++ ...-process_fips_module-to-specify-the-.patch | 58 ++++++++++ SPECS/SymCrypt/SymCrypt.signatures.json | 3 +- SPECS/SymCrypt/SymCrypt.spec | 35 +++++- SPECS/SymCrypt/find-debuginfo | 42 ++++++- 5 files changed, 237 insertions(+), 9 deletions(-) create mode 100644 SPECS/SymCrypt/0001-add-build-flags-to-prevent-stripping-and-post-proces.patch create mode 100644 SPECS/SymCrypt/0001-add-parameter-to-process_fips_module-to-specify-the-.patch diff --git a/SPECS/SymCrypt/0001-add-build-flags-to-prevent-stripping-and-post-proces.patch b/SPECS/SymCrypt/0001-add-build-flags-to-prevent-stripping-and-post-proces.patch new file mode 100644 index 00000000000..1019dbb44d0 --- /dev/null +++ b/SPECS/SymCrypt/0001-add-build-flags-to-prevent-stripping-and-post-proces.patch @@ -0,0 +1,108 @@ +From a91f9a55e6b8b01511538827005a6e948ccf6e27 Mon Sep 17 00:00:00 2001 +From: Tobias Brick +Date: Sat, 12 Oct 2024 02:06:21 +0000 +Subject: [PATCH] add build flags to prevent stripping and post processing + +--- + BUILD.md | 2 ++ + CMakeLists.txt | 14 ++++++++++++++ + modules/linux/common/ModuleCommon.cmake | 4 ++-- + scripts/build.py | 8 ++++++++ + 4 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/BUILD.md b/BUILD.md +index e7f0618..a4984da 100644 +--- a/BUILD.md ++++ b/BUILD.md +@@ -63,6 +63,8 @@ and building the Linux modules with FIPS integrity checks. + * To cross-compile for Linux ARM64, you must also use `--toolchain=cmake-configs/Toolchain-Clang-ARM64.cmake` + * `-DSYMCRYPT_USE_ASM=` to choose whether to use assembly optimizations. Defaults to `ON`. + * `-DSYMCRYPT_FIPS_BUILD=` to choose whether to enable FIPS self-tests in the SymCrypt shared object module. Defaults to `ON`. Currently only affects Linux builds. ++ * `-DSYMCRYPT_STRIP_BINARY=` to choose whether to strip the binary. Defaults to `ON`. ++ * `-DSYMCRYPT_FIPS_POSTPROCESS=` to choose whether to run the FIPS postprocess script. Defaults to `ON`. + * For a release build, specify `-DCMAKE_BUILD_TYPE=RelWithDebInfo` + 1. `cmake --build bin` + * Optionally, for a release build on Windows, specify `--config Release` +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 6da485d..1533e9d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -54,6 +54,18 @@ if(SYMCRYPT_FIPS_BUILD) + add_compile_options(-DSYMCRYPT_DO_FIPS_SELFTESTS=1) + endif() + ++option( ++ SYMCRYPT_STRIP_BINARY ++ "When enabled, SymCrypt will strip the binary in release mode." ++ ON ++) ++ ++option( ++ SYMCRYPT_FIPS_POSTPROCESS ++ "When enabled, SymCrypt will do postprocessing the binary for FIPS integrity verification." ++ ON ++) ++ + option( + SYMCRYPT_TEST_LEGACY_IMPL + "When enabled, the SymCrypt unit tests will be linked against and configured to run compatibility and performance tests on the legacy +@@ -94,6 +106,8 @@ message(STATUS "Host: ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_PROCESSOR}") + message(STATUS "Target: ${CMAKE_SYSTEM_NAME} ${SYMCRYPT_TARGET_ARCH} ${SYMCRYPT_TARGET_ENV}") + message(STATUS "ASM optimizations: ${SYMCRYPT_USE_ASM}") + message(STATUS "FIPS build: ${SYMCRYPT_FIPS_BUILD}") ++message(STATUS "Strip binary: ${SYMCRYPT_STRIP_BINARY}") ++message(STATUS "FIPS postprocess: ${SYMCRYPT_FIPS_POSTPROCESS}") + + # Set output directories binaries + # Note: we use a generator expression because "Multi-configuration generators [e.g. Visual Studio] +diff --git a/modules/linux/common/ModuleCommon.cmake b/modules/linux/common/ModuleCommon.cmake +index ced60ac..7d626c0 100644 +--- a/modules/linux/common/ModuleCommon.cmake ++++ b/modules/linux/common/ModuleCommon.cmake +@@ -57,7 +57,7 @@ set_target_properties(${TARGET_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) + set_target_properties(${TARGET_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) + + +-if(CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo") ++if(CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo" AND SYMCRYPT_STRIP_BINARY) + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD +@@ -69,7 +69,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo") + ) + endif() + +-if(SYMCRYPT_FIPS_BUILD) ++if(SYMCRYPT_FIPS_BUILD AND SYMCRYPT_FIPS_POSTPROCESS) + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD +diff --git a/scripts/build.py b/scripts/build.py +index bbf0c89..48a7146 100755 +--- a/scripts/build.py ++++ b/scripts/build.py +@@ -101,6 +101,12 @@ def configure_cmake(args : argparse.Namespace) -> None: + if not args.fips: + cmake_args.append("-DSYMCRYPT_FIPS_BUILD=OFF") + ++ if not args.strip_binary: ++ cmake_args.append("-DSYMCRYPT_STRIP_BINARY=OFF") ++ ++ if not args.fips_postprocess: ++ cmake_args.append("-DSYMCRYPT_FIPS_POSTPROCESS=OFF") ++ + if args.test_legacy_impl: + cmake_args.append("-DSYMCRYPT_TEST_LEGACY_IMPL=ON") + +@@ -215,6 +221,8 @@ def main() -> None: + parser_cmake.add_argument("--cxx", type = str, help = "Specify the C++ compiler to use. If not provided, uses platform default.") + parser_cmake.add_argument("--no-asm", action = "store_false", dest = "asm", help = "Disable handwritten ASM optimizations.", default = True) + parser_cmake.add_argument("--no-fips", action = "store_false", dest = "fips", help = "Disable FIPS selftests and postprocessing of binary. Currently only affects Linux targets.", default = True) ++ parser_cmake.add_argument("--no-strip-binary", action = "store_false", dest = "strip_binary", help = "Disable stripping of binary.", default = True) ++ parser_cmake.add_argument("--no-fips-postprocess", action = "store_false", dest = "fips_postprocess", help = "Disable FIPS postprocessing of binary.", default = True) + parser_cmake.add_argument("--test-legacy-impl", action = "store_true", + help = "Build unit tests with support for legacy Windows cryptographic implementations. Requires access to private static libraries.", + default = False) +-- +2.39.4 + diff --git a/SPECS/SymCrypt/0001-add-parameter-to-process_fips_module-to-specify-the-.patch b/SPECS/SymCrypt/0001-add-parameter-to-process_fips_module-to-specify-the-.patch new file mode 100644 index 00000000000..932afbe1edd --- /dev/null +++ b/SPECS/SymCrypt/0001-add-parameter-to-process_fips_module-to-specify-the-.patch @@ -0,0 +1,58 @@ +From a3741fb82606395f3ef7f079f7bd6ed4891107ce Mon Sep 17 00:00:00 2001 +From: Tobias Brick +Date: Sat, 12 Oct 2024 00:32:43 +0000 +Subject: [PATCH] add parameter to process_fips_module to specify the + processing directory + +--- + scripts/process_fips_module.py | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/scripts/process_fips_module.py b/scripts/process_fips_module.py +index 53dcaad..87f521a 100755 +--- a/scripts/process_fips_module.py ++++ b/scripts/process_fips_module.py +@@ -16,6 +16,7 @@ import io + import logging + import os + import secrets ++import shutil + import stat + import struct + +@@ -382,6 +383,8 @@ def main(): + + parser = argparse.ArgumentParser(description = "Postprocess SymCrypt shared object module") + parser.add_argument("input", type=str, help = "Path to SymCrypt module") ++ parser.add_argument("-p", "--processing-dir", type=str, default=None, ++ help = "Directory to store temporary debug files during processing. If unspecified, will use the processing directory in the same folder as input.") + parser.add_argument("-d", "--debug", action = "store_true", + help = "Enable debug output (also dumps hashable module contents to file)") + +@@ -392,8 +395,8 @@ def main(): + else: + logging.basicConfig(level = logging.INFO) + +- debug_files_basename = os.path.join( +- os.path.dirname(args.input), "processing", os.path.basename(args.input)) ++ processing_dir = args.processing_dir or os.path.join(os.path.dirname(args.input), "processing") ++ debug_files_basename = os.path.join(processing_dir, os.path.basename(args.input)) + with open(args.input, "rb") as input_file: + buffer = input_file.read() + buffer_stream = io.BytesIO(buffer) +@@ -463,7 +466,11 @@ def main(): + reset_jump_slots(elf_file, original_jump_slot_values) + + # Copy the original input file to a backup file before writing our changes back to the original +- os.replace(args.input, debug_files_basename + ".bak") ++ # os.replace doesn't work across mount points so we manually delete and move the file. ++ backup_file = debug_files_basename + ".bak" ++ if os.path.exists(backup_file): ++ os.remove(backup_file) ++ shutil.move(args.input, backup_file) + + with open(args.input, "wb") as output_file: + output_file.write(buffer_stream.getbuffer()) +-- +2.39.4 + diff --git a/SPECS/SymCrypt/SymCrypt.signatures.json b/SPECS/SymCrypt/SymCrypt.signatures.json index 95bfaafe0cc..5f16465c919 100644 --- a/SPECS/SymCrypt/SymCrypt.signatures.json +++ b/SPECS/SymCrypt/SymCrypt.signatures.json @@ -1,6 +1,7 @@ { "Signatures": { "SymCrypt-103.4.2.tar.gz": "7cbcee7625fd1d99286e393a727504189dab4d407c6c3474bd2532d5ee231921", - "jitterentropy-library-3.3.1.tar.gz": "4a50cb02b4836cd5550016e2fc2263e6982abaa11467a9e1cea260c1c2f7d487" + "jitterentropy-library-3.3.1.tar.gz": "4a50cb02b4836cd5550016e2fc2263e6982abaa11467a9e1cea260c1c2f7d487", + "find-debuginfo": "b3e40f886735e44a434bb4a4925c4a497ab3288decd1c445c428b0d7397e9e03" } } diff --git a/SPECS/SymCrypt/SymCrypt.spec b/SPECS/SymCrypt/SymCrypt.spec index 06694ec5716..a1e73d68c53 100644 --- a/SPECS/SymCrypt/SymCrypt.spec +++ b/SPECS/SymCrypt/SymCrypt.spec @@ -1,8 +1,7 @@ -%define debug_package %{nil} Summary: A core cryptographic library written by Microsoft Name: SymCrypt Version: 103.4.2 -Release: 1%{?dist} +Release: 2%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Azure Linux @@ -10,6 +9,9 @@ Group: System/Libraries URL: https://github.com/microsoft/SymCrypt Source0: https://github.com/microsoft/SymCrypt/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: https://github.com/smuellerDD/jitterentropy-library/archive/v3.3.1.tar.gz#/jitterentropy-library-3.3.1.tar.gz +Source2: find-debuginfo +Patch1: 0001-add-build-flags-to-prevent-stripping-and-post-proces.patch +Patch2: 0001-add-parameter-to-process_fips_module-to-specify-the-.patch BuildRequires: cmake %ifarch aarch64 BuildRequires: clang >= 12.0.1-4 @@ -40,11 +42,12 @@ A core cryptographic library written by Microsoft %endif %prep -%setup -q -%setup -q -a 1 +%autosetup -a 1 -p1 # Create a symbolic link as if jitterentropy-library has been pulled in as git submodule rm -rf 3rdparty/jitterentropy-library ln -s ../jitterentropy-library-3.3.1 3rdparty/jitterentropy-library +# Copy the custom find-debuginfo script +cp %{SOURCE2} . %build SYMCRYPT_BRANCH=main \ @@ -52,7 +55,9 @@ SYMCRYPT_COMMIT_HASH=a84ffe1 \ SYMCRYPT_COMMIT_TIMESTAMP=2024-01-26T22:00:47-08:00 \ cmake -S . -B bin \ -DSYMCRYPT_TARGET_ARCH=%{symcrypt_arch} \ - -DCMAKE_BUILD_TYPE=Release \ + -DSYMCRYPT_STRIP_BINARY=OFF \ + -DSYMCRYPT_FIPS_POSTPROCESS=OFF \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DCMAKE_C_COMPILER=%{symcrypt_cc} \ -DCMAKE_CXX_COMPILER=%{symcrypt_cxx} \ -DCMAKE_C_FLAGS="%{symcrypt_c_flags}" \ @@ -60,6 +65,21 @@ cmake -S . -B bin \ cmake --build bin +# Override the default find-debuginfo script to our own custom one, which is modified +# to allow us to keep symbols. +# Also add custom options to the call to find-debuginfo. +%define __find_debuginfo ./find-debuginfo +%define _find_debuginfo_opts --keep-symbol SymCryptVolatileFipsHmacKey --keep-symbol SymCryptVolatileFipsHmacKeyRva --keep-symbol SymCryptVolatileFipsBoundaryOffset --keep-symbol SymCryptVolatileFipsHmacDigest + +# Override the default to allow us to do custom fips post-processing after debug info/stripping is done. +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + mkdir -p "bin/module/generic/processing" \ + python3 "scripts/process_fips_module.py" "%{buildroot}%{_libdir}/libsymcrypt.so.%{version}" --processing-dir "bin/module/generic/processing" --debug \ +%{nil} + %install mkdir -p %{buildroot}%{_libdir} mkdir -p %{buildroot}%{_includedir} @@ -78,7 +98,10 @@ chmod 755 %{buildroot}%{_libdir}/libsymcrypt.so.%{version} %{_includedir}/* %changelog -* Wed Jun 25 2024 Maxwell Moyer-McKee - 103.4.2-1 +* Mon Oct 14 2024 Tobias Brick - 103.4.2-2 +- Add debuginfo package + +* Wed Jun 26 2024 Maxwell Moyer-McKee - 103.4.2-1 - Update SymCrypt to v103.4.2 for FIPS certification * Thu Apr 25 2024 Maxwell Moyer-McKee - 103.4.1-2 diff --git a/SPECS/SymCrypt/find-debuginfo b/SPECS/SymCrypt/find-debuginfo index fcc883d9dde..b03534f7e97 100755 --- a/SPECS/SymCrypt/find-debuginfo +++ b/SPECS/SymCrypt/find-debuginfo @@ -28,6 +28,7 @@ automagically generates debug info and file lists Options: [--strict-build-id] [-g] [-r] [-m] [-i] [-n] [--keep-section SECTION] [--remove-section SECTION] +[--keep-symbol SYMBOL] [--g-libs] [-j N] [--jobs N] [-o debugfiles.list] @@ -52,6 +53,9 @@ keep a (non-allocated) section in the main executable or explicitly remove it into the .debug file. SECTION is an extended wildcard pattern. Both options can be given more than once. +Use --keep-symbol SYMBOL to keep the symbol in the main executable. +This option can be given more than once. + The --strict-build-id flag says to exit with failure status if any ELF binary processed fails to contain a build-id note. @@ -99,7 +103,9 @@ EOF } # Figure out where we are installed so we can call other helper scripts. -install_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# SymCrypt-Specific: Because we have our own custom find-debuginfo, we need to use the +# location that the system version is installed at. +install_dir="$(cd "$(dirname "$(which find-debuginfo)")" && pwd)" # With -g arg, pass it to strip on libraries or executables. strip_g=false @@ -113,6 +119,9 @@ strip_r=false # keep or remove arguments to eu-strip. keep_remove_args= +# keep or remove symbols arguments +keep_symbol_args= + # with -m arg, add minimal debuginfo to binary. include_minidebug=false @@ -225,6 +234,10 @@ while [ $# -gt 0 ]; do keep_remove_args="${keep_remove_args} --remove-section $2" shift ;; + --keep-symbol) + keep_symbol_args="${keep_symbol_args} --keep-symbol $2" + shift + ;; -j) n_jobs=$2 shift @@ -318,7 +331,32 @@ strip_to_debug() $strip_glibs && case "$(file -bi "$2")" in application/x-sharedlib*) g=-g ;; esac - eu-strip --remove-comment $r $g ${keep_remove_args} -f "$1" "$2" || exit + + # SymCrypt-Specific: We need to keep certain symbols in the stripped binary, which eu-strip does not support. + # So instead we use strip, but that has different semantics. + # + # Original eu-strip command: + # eu-strip --remove-comment $r $g ${keep_remove_args} ${keep_symbol_args} -f "$1" "$2" || exit + # + # Always remove the comment section + keep_remove_args="${keep_remove_args} --remove-section .comment" + + # We don't set $r and $g in my testing. If we ever do set those, then this script + # will need to be modified to either find the equivalent in strip, or intentionally + # decide to not support these flags. + if [ -n "$r" ] || [ -n "$g" ]; then + echo >&2 "*** ERROR: strip_to_debug: r ('${r}') or g ('${r}') is set, but this script does not support it" + exit 2 + fi + + # strip has the -o flag instead of the -f flag, but the semantics are reversed + # For eu-strip, -f will extract the removed sections into the file given, leaving the original file alone. + # For strip, -o will write the stripped file to the given location, leaving original file alone. + # So we need to swap the arguments to strip. + mv "${2}" "${1}" + + # The original cmake file for SymCrypt uses --strip-unneeded + strip --strip-unneeded ${keep_remove_args} ${keep_symbol_args} -o "$2" "$1" || exit chmod 444 "$1" || exit }