Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/cryptocb-setkey.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Crypto callback SETKEY tests

# START OF COMMON SECTION
on:
push:
branches: [ 'release/**' ]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches: [ '*' ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
# END OF COMMON SECTION

jobs:
# Native x86_64 'make check' with WOLF_CRYPTO_CB_SETKEY enabled
# (--enable-cryptocbutils=setkey). This is the only config that reproduces the
# TLS CBC MAC-then-Encrypt failure guarded by test_wc_CryptoCb_TLS_CBC_HMAC:
# a crypto-callback device that owns the HMAC key (services the SETKEY op)
# leaves the software ipad/opad uncomputed, so the constant-time raw-hash
# verify path (Hmac_UpdateFinal_CT) reads empty state and produces a wrong
# record MAC unless TLS_hmac routes callback-devId verification through the
# update/final HMAC path. Without SETKEY, wc_HmacSetKey always builds the
# software key state and the raw-hash path recomputes a correct MAC, so the
# test is compiled out and no other CI config exercises it.
# - setkey : the SETKEY utility alone, on the default feature set.
# - setkey-all : SETKEY alongside the COPY/FREE utilities and --enable-all,
# covering the device through the cryptocb copy/free paths.
# - setkey-swdev: SETKEY with --enable-swdev, which turns on
# WOLF_CRYPTO_CB_FIND. There a find callback maps
# INVALID_DEVID onto a registered device, so SETKEY,
# update and final must all dispatch on the same terms;
# test_wc_CryptoCb_Hmac_Find covers that.
make_check:
strategy:
fail-fast: false
matrix:
config:
- '--enable-cryptocb --enable-cryptocbutils=setkey'
- '--enable-cryptocb --enable-cryptocbutils --enable-all'
- '--enable-cryptocb --enable-cryptocbutils=setkey --enable-swdev'
name: make check (${{ matrix.config }})
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v5
name: Checkout wolfSSL

- name: Build and test crypto callback SETKEY
run: |
./autogen.sh
./configure ${{ matrix.config }}
make -j 4
make check

- name: Print errors
if: ${{ failure() }}
run: |
for file in scripts/*.log test-suite.log
do
if [ -f "$file" ]; then
echo "${file}:"
cat "$file"
echo "========================================================================"
fi
done
35 changes: 34 additions & 1 deletion src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,8 +1196,26 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,

#endif

/* A crypto-callback device that services the HMAC SETKEY operation owns the
* key: wc_HmacSetKey() returns before it derives the software ipad/opad, so
* the raw-hash constant-time path has no software hash state to read. Only
* WOLF_CRYPTO_CB_SETKEY builds can reach that state; every other crypto
* callback build still computes the software key material and the raw-hash
* path stays correct. With WOLF_CRYPTO_CB_FIND the find callback can map any
* device id -- INVALID_DEVID included -- onto a registered device, matching
* how wc_CryptoCb_SetKey()/wc_CryptoCb_Hmac() themselves dispatch, so no HMAC
* can be assumed software backed. */
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
#ifdef WOLF_CRYPTO_CB_FIND
#define TLS_HMAC_DEV_BACKED(h) (1)
#else
#define TLS_HMAC_DEV_BACKED(h) ((h)->devId != INVALID_DEVID)
#endif
#endif

#if defined(WOLFSSL_NO_HASH_RAW) || defined(HAVE_FIPS) || \
defined(HAVE_SELFTEST) || defined(HAVE_BLAKE2B)
defined(HAVE_SELFTEST) || defined(HAVE_BLAKE2B) || \
defined(TLS_HMAC_DEV_BACKED)

/* Calculate the HMAC of the header + message data.
* Constant time implementation using normal hashing operations.
Expand Down Expand Up @@ -1467,6 +1485,21 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
if (verify && padSz >= 0) {
#if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
!defined(HAVE_SELFTEST)
#ifdef TLS_HMAC_DEV_BACKED
/* Key may be owned by a crypto-callback device, leaving the
* software hash state the raw-hash path reads uncomputed. Use the
* update/final variant: the padding-time equalization (dummy
* blocks) is preserved and the timing profile is the device's,
* outside the Lucky13 software threat model. A device that
* declines the HMAC and falls through to software then runs the
* same update/final variant FIPS and selftest builds always use
* (see the #else branch). */
if (TLS_HMAC_DEV_BACKED(hmac)) {
ret = Hmac_UpdateFinal(hmac, digest, in,
totalSz, myInner, innerSz);
Comment on lines +1498 to +1499
}
else
#endif
#ifdef HAVE_BLAKE2B
if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) {
ret = Hmac_UpdateFinal(hmac, digest, in,
Expand Down
Loading