1
0
mirror of https://github.com/wolfSSL/wolfssl.git synced 2026-10-24 04:09:07 +03:00

fips-hash: detect in core HMAC digest from fips_test.c

fips-hash.sh now works out the in core integrity digest from the length
of the verifyCore literal in fips_test.c (64 hex SHA-256, 96 hex SHA-384,
128 hex SHA-512), falling back to a WC_SHA256 HMAC type named in the
source for placeholder values. A reported hash of the wrong length is
rejected instead of being written, and the rewrite is verified.

fips-hash-offline.sh gains HMAC-SHA-512 for v7 and checks coreKey
against the per digest key size (128 bytes for v7) instead of assuming
it matches the digest length.
This commit is contained in:
jackctj117
2026-10-13 12:40:50 -06:00
parent 6090053cbb
commit 2cdf44b253
2 changed files with 72 additions and 9 deletions

View File

@@ -27,12 +27,15 @@
# This reproduces, at build time and against the final ELF image, exactly what
# DoInCoreCheck() in wolfcrypt/src/fips_test.c computes at run time:
#
# HMAC-SHA256( coreKey,
# HMAC-SHAxxx( coreKey,
# .text bytes in [wolfCrypt_FIPS_first, wolfCrypt_FIPS_last)
# ||
# .rodata bytes in [wolfCrypt_FIPS_ro_start, wolfCrypt_FIPS_ro_end)
# with the verifyCore[] bytes skipped )
#
# where SHAxxx is SHA-256 (or SHA-384) up to FIPS v6.0.0 and SHA-512 from
# v7.0.0 on, selected below from the size of verifyCore[].
#
# Because verifyCore[] is excluded from the digest, overwriting it with the
# computed value does not change the digest, so a single pass over the linked
# binary is sufficient -- no rebuild and no scraping of the module's reported
@@ -117,16 +120,19 @@ keyaddr=$((0x$KEY_H))
# Select the digest from the size of verifyCore[] (= digest_bytes*2 + 1).
digest_bytes=$(( (VCSZ - 1) / 2 ))
# The coreKey size follows the digest up to v6.0.0; v7 (HMAC-SHA-512) uses a
# full 128-byte SHA-512 block-size key.
case "$digest_bytes" in
32) ALG=sha256 ;;
48) ALG=sha384 ;;
32) ALG=sha256; key_bytes=32 ;;
48) ALG=sha384; key_bytes=48 ;;
64) ALG=sha512; key_bytes=128 ;;
*) die "unexpected verifyCore size ($VCSZ); cannot determine digest" ;;
esac
# Read the HMAC key (coreKey) as ASCII hex straight out of the binary.
keyoff=$(vaddr_to_off "$keyaddr") || die "cannot map coreKey address to file offset"
KEYHEX=$(extract "$keyoff" $((KEYSZ - 1)))
[ "${#KEYHEX}" -eq $((digest_bytes * 2)) ] || die "coreKey length mismatch in binary"
[ "${#KEYHEX}" -eq $((key_bytes * 2)) ] || die "coreKey length mismatch in binary"
# File offsets for the measured regions.
codeoff=$(vaddr_to_off "$first") || die "cannot map wolfCrypt_FIPS_first"

View File

@@ -20,12 +20,69 @@ then
exit 1
fi
# Take the hash exactly as long as reported: the in core digest is SHA-256 (64
# hex) up to FIPS v6.0.0 and SHA-512 (128 hex) from v7.0.0 on.
# Work out which digest the in core integrity HMAC uses in this fips_test.c,
# so the reported hash can be checked before it is written: HMAC-SHA-256 (64
# hex) up to FIPS v6.0.0, HMAC-SHA-384 (96 hex) for v5.3+ NO_SHA256 builds and
# HMAC-SHA-512 (128 hex) from v7.0.0 on. The length of the current verifyCore
# literal is authoritative; v7 enforces it with a static assert.
VCCOUNT=$(grep -c '^".*";' wolfcrypt/src/fips_test.c)
if test "$VCCOUNT" -ne 1
then
echo "fips-hash: expected one verifyCore line in fips_test.c, found $VCCOUNT"
exit 1
fi
VCHEX=$(sed -n 's/^"\([0-9A-Fa-f]*\)";.*$/\1/p' wolfcrypt/src/fips_test.c)
HEXLEN=${#VCHEX}
case "$HEXLEN" in
64) ALG=SHA256 ;;
96) ALG=SHA384 ;;
128) ALG=SHA512 ;;
*)
# Placeholder of unknown length: fall back to an HMAC type named
# directly in the source (pre v7 trees hard code WC_SHA256).
if grep -q 'wc_HmacSetKey_fips(&hmac, *WC_SHA256' \
wolfcrypt/src/fips_test.c
then
ALG=SHA256
HEXLEN=64
else
echo "fips-hash: cannot determine in core digest" \
"(verifyCore is $HEXLEN hex)"
exit 1
fi
;;
esac
if test "$ALG" != "SHA256" && \
grep -q 'wc_HmacSetKey_fips(&hmac, *WC_SHA256' wolfcrypt/src/fips_test.c
then
echo "fips-hash: warning: fips_test.c names WC_SHA256 but verifyCore" \
"is $HEXLEN hex; using $ALG"
fi
echo "fips-hash: in core HMAC-$ALG ($HEXLEN hex)"
NEWHASH=$(./wolfcrypt/test/testwolfcrypt | \
sed -n 's/^hash = \([0-9A-Fa-f][0-9A-Fa-f]*\).*$/\1/p' | head -1)
if test -n "$NEWHASH"
if test -z "$NEWHASH"
then
cp wolfcrypt/src/fips_test.c wolfcrypt/src/fips_test.c.bak
sed "s/^\".*\";/\"${NEWHASH}\";/" wolfcrypt/src/fips_test.c.bak >wolfcrypt/src/fips_test.c
# Only reported on a callback (e.g. in core failure); nothing to update.
exit 0
fi
if test "${#NEWHASH}" -ne "$HEXLEN"
then
echo "fips-hash: testwolfcrypt reported a ${#NEWHASH} hex hash but" \
"fips_test.c expects HMAC-$ALG ($HEXLEN hex); not updating"
exit 1
fi
cp wolfcrypt/src/fips_test.c wolfcrypt/src/fips_test.c.bak
sed "s/^\".*\";/\"${NEWHASH}\";/" wolfcrypt/src/fips_test.c.bak >wolfcrypt/src/fips_test.c
if ! grep -q "^\"${NEWHASH}\";" wolfcrypt/src/fips_test.c
then
echo "fips-hash: failed to update verifyCore in fips_test.c"
exit 1
fi