Problem:
An invalid libbcm_c_generated_asm.a is generated when bcm.c is compiled with Zig, leading to delocate failing with a parse error. This only happens when -DFIPS=1 is set.
error while parsing "/work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule/libbcm_c_generated_asm.a":
parse error near Unknown (line 1 symbol 1 - line 1 symbol 1):
""
I'm working with 83d85826595641bb2f23c6108f2e031fcd5cd505 commit, as that's what aws-lc-fips-sys 0.13.14 mentions in Cargo.toml.
I'm sharing a minimal reproduction of the issue: https://github.com/RafalSumislawski/aws-lc-zig-fips-repro
Why it fails?
AWS-LC's FIPS CMakeList defines a normal static library target named bcm_c_generated_asm from crypto/fipsmodule/bcm.c, adds the regular include/definition setup for that target, and sets COMPILE_OPTIONS "-S" so the compiler emits assembly instead of an object file. As a result the bcm.c compile command includes both assembly-output and object/dependency flags:
zig-cc ... -S -MD -MT ... -MF ... -o bcm.c.o -c bcm.c
GCC/Clang tolerate this command shape and emit assembly. Zig does not produce an archive member that delocate can parse, so the archive starts with object-like data instead of assembly text.
The build then runs delocate. That command passes the generated static archive with -a $<TARGET_FILE:bcm_c_generated_asm>, so delocate expects the archive member produced by bcm_c_generated_asm to be textual assembly.
Fix?
This can either be seen as a zig cc issue: "zig cc doesn't behave exactly like clang"
Or an AWS-LC issue: "A compiler command containing -S as well as -MD/-MT/-MF is questionable, and just happens to work with clang"
I managed to build aws-lc with zig using shims that removed the surplus flags.
So this could be fixed here in aws-lc, by generating bcm.c textual assembly with a dedicated custom command that does not include -c, -MD, -MT, or -MF, rather than relying on the current normal CMake object/static-library compile rule plus COMPILE_OPTIONS "-S".
Context (or why do I care about using zig here)
I'm trying to build FIPS-compliant rust AWS lambda functions using cargo lambda. Using zig as C compiler is the default https://www.cargo-lambda.info/guide/cross-compiling.html#cross-compiling-with-the-zig-toolchain and in my experience most reliable way of cross compiling rust lambdas across arm64/x86_64 MacOS/Linux
Relevant details
AWS-LC commit: 83d8582
System information: I've provided a reproduction in a docker container. My local setup is an M1 Mac, but it's mostly irrelevant
Build log:
-- Go compiler 1.22.2 found
-- The C compiler identification is Clang 21.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/bin/zig-cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- FIPS build mode configured
-- FIPS entropy source method configured: Passive
-- The CXX compiler identification is Clang 21.1.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/zig-c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Perl: /usr/bin/perl (found version "5.38.2")
-- Setting CMAKE_C_STANDARD=11
-- stdalign_check.c probe is positive, enabling AWS_LC_STDALIGN_AVAILABLE
-- builtin_swap_check.c probe is positive, enabling AWS_LC_BUILTIN_SWAP_SUPPORTED
-- linux_u32.c probe is positive, enabling AWS_LC_URANDOM_U32
-- The ASM compiler identification is Clang with GNU-like command-line
-- Found assembler: /usr/local/bin/zig-cc
CMake Deprecation Warning at cmake/go.cmake:55 (cmake_policy):
The OLD behavior for policy CMP0116 will be removed from a future version
of CMake.
The cmake-policies(7) manual explains that the OLD behaviors of all
policies are deprecated and that a policy should be set to OLD only under
specific short-term circumstances. Projects should be ported to the NEW
behavior and not rely on setting a policy to OLD.
Call Stack (most recent call first):
crypto/fipsmodule/CMakeLists.txt:367 (go_executable)
CMake Deprecation Warning at cmake/go.cmake:55 (cmake_policy):
The OLD behavior for policy CMP0116 will be removed from a future version
of CMake.
The cmake-policies(7) manual explains that the OLD behaviors of all
policies are deprecated and that a policy should be set to OLD only under
specific short-term circumstances. Projects should be ported to the NEW
behavior and not rely on setting a policy to OLD.
Call Stack (most recent call first):
crypto/fipsmodule/CMakeLists.txt:415 (go_executable)
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Configuring done (21.6s)
-- Generating done (0.1s)
-- Build files have been written to: /work/build/linux-arm64-fips/cmake-build
Change Dir: '/work/build/linux-arm64-fips/cmake-build'
Run Build Command(s): /usr/bin/ninja -v crypto
[1/325] cd /work/build/linux-arm64-fips/cmake-build/crypto && /usr/bin/cmake -E make_directory test && /usr/bin/perl /work/aws-lc/crypto/test/asm/trampoline-armv8.pl linux64 test/trampoline-armv8.S
...
[317/325] cd /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule && /usr/bin/cmake -E make_directory . && /usr/bin/perl /work/aws-lc/crypto/fipsmodule/aes/asm/vpaes-armv8.pl linux64 vpaes-armv8.S
[318/325] cd /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule && /usr/bin/cmake -E make_directory . && /usr/bin/perl /work/aws-lc/crypto/fipsmodule/sha/asm/sha512-armv8.pl linux64 sha512-armv8.S
[319/325] cd /work/aws-lc/crypto/fipsmodule && /usr/bin/go build -o /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule/delocate boringssl.googlesource.com/boringssl/util/fipstools/delocate && /usr/bin/go run /work/aws-lc/util/godeps.go -format depfile -target crypto/fipsmodule/delocate -pkg boringssl.googlesource.com/boringssl/util/fipstools/delocate -out /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule/delocate.d
[320/325] cd /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule && ./delocate -a /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule/libbcm_c_generated_asm.a -o bcm-delocated.S -cc /usr/local/bin/zig-cc -cc-flags \ \ -Wno-newline-eof\ -Wa,--noexecstack /work/aws-lc/include/openssl/arm_arch.h /work/aws-lc/include/openssl/asm_base.h /work/aws-lc/include/openssl/target.h aesv8-armx.S aesv8-gcm-armv8.S aesv8-gcm-armv8-unroll8.S armv8-mont.S bn-armv8.S ghash-neon-armv8.S ghashv8-armx.S keccak1600-armv8.S md5-armv8.S p256-armv8-asm.S p256_beeu-armv8-asm.S sha1-armv8.S sha256-armv8.S sha512-armv8.S vpaes-armv8.S p384/bignum_add_p384.S.S p384/bignum_sub_p384.S.S p384/bignum_neg_p384.S.S p384/bignum_tomont_p384.S.S p384/bignum_deamont_p384.S.S p384/bignum_montmul_p384.S.S p384/bignum_montmul_p384_alt.S.S p384/bignum_montsqr_p384.S.S p384/bignum_montsqr_p384_alt.S.S p384/bignum_nonzero_6.S.S p384/bignum_littleendian_6.S.S p521/bignum_add_p521.S.S p521/bignum_sub_p521.S.S p521/bignum_neg_p521.S.S p521/bignum_mul_p521.S.S p521/bignum_mul_p521_alt.S.S p521/bignum_sqr_p521.S.S p521/bignum_sqr_p521_alt.S.S p521/bignum_tolebytes_p521.S.S p521/bignum_fromlebytes_p521.S.S curve25519/bignum_mod_n25519.S.S curve25519/bignum_neg_p25519.S.S curve25519/bignum_madd_n25519.S.S curve25519/bignum_madd_n25519_alt.S.S curve25519/edwards25519_decode.S.S curve25519/edwards25519_decode_alt.S.S curve25519/edwards25519_encode.S.S curve25519/edwards25519_scalarmulbase.S.S curve25519/edwards25519_scalarmulbase_alt.S.S curve25519/edwards25519_scalarmuldouble.S.S curve25519/edwards25519_scalarmuldouble_alt.S.S curve25519/curve25519_x25519_byte.S.S curve25519/curve25519_x25519_byte_alt.S.S curve25519/curve25519_x25519base_byte.S.S curve25519/curve25519_x25519base_byte_alt.S.S fastmul/bignum_kmul_16_32.S.S fastmul/bignum_kmul_32_64.S.S fastmul/bignum_ksqr_16_32.S.S fastmul/bignum_ksqr_32_64.S.S fastmul/bignum_emontredc_8n.S.S generic/bignum_ge.S.S generic/bignum_mul.S.S generic/bignum_optsub.S.S generic/bignum_sqr.S.S fastmul/bignum_kmul_16_32_neon.S.S fastmul/bignum_kmul_32_64_neon.S.S fastmul/bignum_ksqr_16_32_neon.S.S fastmul/bignum_ksqr_32_64_neon.S.S fastmul/bignum_emontredc_8n_neon.S.S generic/bignum_copy_row_from_table.S.S generic/bignum_copy_row_from_table_8n_neon.S.S generic/bignum_copy_row_from_table_16_neon.S.S generic/bignum_copy_row_from_table_32_neon.S.S
FAILED: crypto/fipsmodule/bcm-delocated.S /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule/bcm-delocated.S
cd /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule && ./delocate -a /work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule/libbcm_c_generated_asm.a -o bcm-delocated.S -cc /usr/local/bin/zig-cc -cc-flags \ \ -Wno-newline-eof\ -Wa,--noexecstack /work/aws-lc/include/openssl/arm_arch.h /work/aws-lc/include/openssl/asm_base.h /work/aws-lc/include/openssl/target.h aesv8-armx.S aesv8-gcm-armv8.S aesv8-gcm-armv8-unroll8.S armv8-mont.S bn-armv8.S ghash-neon-armv8.S ghashv8-armx.S keccak1600-armv8.S md5-armv8.S p256-armv8-asm.S p256_beeu-armv8-asm.S sha1-armv8.S sha256-armv8.S sha512-armv8.S vpaes-armv8.S p384/bignum_add_p384.S.S p384/bignum_sub_p384.S.S p384/bignum_neg_p384.S.S p384/bignum_tomont_p384.S.S p384/bignum_deamont_p384.S.S p384/bignum_montmul_p384.S.S p384/bignum_montmul_p384_alt.S.S p384/bignum_montsqr_p384.S.S p384/bignum_montsqr_p384_alt.S.S p384/bignum_nonzero_6.S.S p384/bignum_littleendian_6.S.S p521/bignum_add_p521.S.S p521/bignum_sub_p521.S.S p521/bignum_neg_p521.S.S p521/bignum_mul_p521.S.S p521/bignum_mul_p521_alt.S.S p521/bignum_sqr_p521.S.S p521/bignum_sqr_p521_alt.S.S p521/bignum_tolebytes_p521.S.S p521/bignum_fromlebytes_p521.S.S curve25519/bignum_mod_n25519.S.S curve25519/bignum_neg_p25519.S.S curve25519/bignum_madd_n25519.S.S curve25519/bignum_madd_n25519_alt.S.S curve25519/edwards25519_decode.S.S curve25519/edwards25519_decode_alt.S.S curve25519/edwards25519_encode.S.S curve25519/edwards25519_scalarmulbase.S.S curve25519/edwards25519_scalarmulbase_alt.S.S curve25519/edwards25519_scalarmuldouble.S.S curve25519/edwards25519_scalarmuldouble_alt.S.S curve25519/curve25519_x25519_byte.S.S curve25519/curve25519_x25519_byte_alt.S.S curve25519/curve25519_x25519base_byte.S.S curve25519/curve25519_x25519base_byte_alt.S.S fastmul/bignum_kmul_16_32.S.S fastmul/bignum_kmul_32_64.S.S fastmul/bignum_ksqr_16_32.S.S fastmul/bignum_ksqr_32_64.S.S fastmul/bignum_emontredc_8n.S.S generic/bignum_ge.S.S generic/bignum_mul.S.S generic/bignum_optsub.S.S generic/bignum_sqr.S.S fastmul/bignum_kmul_16_32_neon.S.S fastmul/bignum_kmul_32_64_neon.S.S fastmul/bignum_ksqr_16_32_neon.S.S fastmul/bignum_ksqr_32_64_neon.S.S fastmul/bignum_emontredc_8n_neon.S.S generic/bignum_copy_row_from_table.S.S generic/bignum_copy_row_from_table_8n_neon.S.S generic/bignum_copy_row_from_table_16_neon.S.S generic/bignum_copy_row_from_table_32_neon.S.S
error while parsing "/work/build/linux-arm64-fips/cmake-build/crypto/fipsmodule/libbcm_c_generated_asm.a":
parse error near Unknown (line 1 symbol 1 - line 1 symbol 1):
""
ninja: build stopped: subcommand failed.
Problem:
An invalid
libbcm_c_generated_asm.ais generated whenbcm.cis compiled with Zig, leading todelocatefailing with a parse error. This only happens when-DFIPS=1is set.I'm working with
83d85826595641bb2f23c6108f2e031fcd5cd505commit, as that's whataws-lc-fips-sys0.13.14mentions inCargo.toml.I'm sharing a minimal reproduction of the issue: https://github.com/RafalSumislawski/aws-lc-zig-fips-repro
Why it fails?
AWS-LC's FIPS CMakeList defines a normal static library target named
bcm_c_generated_asmfromcrypto/fipsmodule/bcm.c, adds the regular include/definition setup for that target, and setsCOMPILE_OPTIONS "-S"so the compiler emits assembly instead of an object file. As a result thebcm.ccompile command includes both assembly-output and object/dependency flags:GCC/Clang tolerate this command shape and emit assembly. Zig does not produce an archive member that
delocatecan parse, so the archive starts with object-like data instead of assembly text.The build then runs
delocate. That command passes the generated static archive with-a $<TARGET_FILE:bcm_c_generated_asm>, sodelocateexpects the archive member produced bybcm_c_generated_asmto be textual assembly.Fix?
This can either be seen as a
zig ccissue: "zig ccdoesn't behave exactly like clang"Or an AWS-LC issue: "A compiler command containing
-Sas well as-MD/-MT/-MFis questionable, and just happens to work with clang"I managed to build aws-lc with zig using shims that removed the surplus flags.
So this could be fixed here in aws-lc, by generating
bcm.ctextual assembly with a dedicated custom command that does not include-c,-MD,-MT, or-MF, rather than relying on the current normal CMake object/static-library compile rule plusCOMPILE_OPTIONS "-S".Context (or why do I care about using zig here)
I'm trying to build FIPS-compliant rust AWS lambda functions using
cargo lambda. Using zig as C compiler is the default https://www.cargo-lambda.info/guide/cross-compiling.html#cross-compiling-with-the-zig-toolchain and in my experience most reliable way of cross compiling rust lambdas across arm64/x86_64 MacOS/LinuxRelevant details
AWS-LC commit: 83d8582
System information: I've provided a reproduction in a docker container. My local setup is an M1 Mac, but it's mostly irrelevant
Build log: