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:
@@ -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"
|
||||
|
||||
67
fips-hash.sh
67
fips-hash.sh
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user