From 5d994f91efe9a723f080741d8a163817d560ae63 Mon Sep 17 00:00:00 2001 From: Paul Adelsbach Date: Tue, 10 Mar 2026 11:42:06 -0700 Subject: [PATCH] Fix aead set random IV --- debian/install-wolfprov.sh | 11 ++- scripts/test-wp-cs.sh | 5 +- src/wp_aes_aead.c | 6 +- test/test_aestag.c | 154 +++++++++++++++++++++++++++++++++++++ test/unit.c | 1 + test/unit.h | 1 + 6 files changed, 169 insertions(+), 9 deletions(-) diff --git a/debian/install-wolfprov.sh b/debian/install-wolfprov.sh index 4ff6ac57..99432df8 100755 --- a/debian/install-wolfprov.sh +++ b/debian/install-wolfprov.sh @@ -195,8 +195,14 @@ main() { work_dir=$(mktemp -d) printf "Working directory: $work_dir\n" pushd $work_dir 2>&1 > /dev/null - cp -r $REPO_ROOT . - cd $(basename $REPO_ROOT) + repo_name=$(basename "$REPO_ROOT") + if git clone --depth 1 "file://$REPO_ROOT" "$repo_name"; then + : + else + echo "Shallow clone failed, falling back to local clone" + git clone "$REPO_ROOT" "$repo_name" + fi + cd "$repo_name" wolfprov_build $fips_mode $debug_mode if [ $no_install -eq 0 ]; then @@ -218,4 +224,3 @@ main() { # Run main function with all arguments main "$@" - diff --git a/scripts/test-wp-cs.sh b/scripts/test-wp-cs.sh index 514aa0f6..99a8cf55 100755 --- a/scripts/test-wp-cs.sh +++ b/scripts/test-wp-cs.sh @@ -284,9 +284,9 @@ openssl version -a || true if [ "${AM_BWRAPPED-}" != "yes" ]; then # Perform the build only if not in the bubble printf "Cleaning up previous builds\n" - ${SCRIPT_DIR}/build-wolfprovider.sh --clean --distclean + ${SCRIPT_DIR}/build-wolfprovider.sh --clean --distclean || exit 1 printf "Building wolfProvider\n" - ${SCRIPT_DIR}/build-wolfprovider.sh + ${SCRIPT_DIR}/build-wolfprovider.sh || exit 1 printf "OPENSSL_BIN: $OPENSSL_BIN\n" $OPENSSL_BIN version -a || true @@ -321,4 +321,3 @@ else printf "$FAIL tests failed.\n" exit 1 fi - diff --git a/src/wp_aes_aead.c b/src/wp_aes_aead.c index 4d921c91..318497dc 100644 --- a/src/wp_aes_aead.c +++ b/src/wp_aes_aead.c @@ -666,8 +666,8 @@ static int wp_aead_set_ctx_params(wp_AeadCtx* ctx, const OSSL_PARAM params[]) ok = wp_aead_set_param_tls1_iv_fixed(ctx, params); } else if (ok && (ctx->mode == EVP_CIPH_GCM_MODE) && - (XMEMCMP(params->key, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, - sizeof(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED)) == 0)) { + (XMEMCMP(params->key, OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, + sizeof(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV)) == 0)) { ok = wp_aead_set_param_tls1_iv_rand(ctx, params); } @@ -925,7 +925,7 @@ static int wp_aesgcm_set_rand_iv(wp_AeadCtx *ctx, unsigned char *in, XMEMCPY(ctx->origIv, ctx->iv, ctx->ivLen); #endif XMEMCPY(ctx->iv + ctx->ivLen - inLen, in, inLen); - ctx->ivState = IV_STATE_COPIED; + ctx->ivState = IV_STATE_BUFFERED; } WOLFPROV_LEAVE(WP_LOG_COMP_AES, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); diff --git a/test/test_aestag.c b/test/test_aestag.c index 1515b4b2..bc21c4e1 100644 --- a/test/test_aestag.c +++ b/test/test_aestag.c @@ -1042,6 +1042,160 @@ int test_aes128_gcm_tls(void *data) EVP_GCM_TLS_FIXED_IV_LEN, 0); } +/******************************************************************************/ + +/* Test that OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV correctly sets the + * explicit/random portion of the IV on the decrypt side via the OSSL_PARAM + * interface. This exercises the fix in wp_aead_set_ctx_params where the + * parameter key comparison was corrected from AEAD_TLS1_IV_FIXED to + * AEAD_TLS1_SET_IV_INV. */ +static int test_aes_gcm_set_iv_inv_dec(const EVP_CIPHER *cipher, + unsigned char *key, unsigned char *iv, int ivFixedLen, int ivLen, + unsigned char *aad, unsigned char *msg, int len, + unsigned char *enc, unsigned char *tag, unsigned char *dec) +{ + int err; + EVP_CIPHER_CTX *ctx; + int decLen; + unsigned int tagLen = 16; + OSSL_PARAM params[2]; + + err = (ctx = EVP_CIPHER_CTX_new()) == NULL; + /* Init decrypt with key. */ + if (err == 0) { + err = EVP_DecryptInit(ctx, cipher, key, NULL) != 1; + } + /* Set the fixed IV portion - this also sets ivGen. */ + if (err == 0) { + err = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, + ivFixedLen, iv) != 1; + } + /* Use OSSL_PARAM AEAD_TLS1_SET_IV_INV to set the explicit/random part + * of the IV from the encrypt side. This is the code path fixed by the + * commit. */ + if (err == 0) { + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, + (void *)(iv + ivFixedLen), ivLen - ivFixedLen); + params[1] = OSSL_PARAM_construct_end(); + err = EVP_CIPHER_CTX_set_params(ctx, params) != 1; + } + /* Set tag for verification. */ + if (err == 0) { + err = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tagLen, + (void *)tag) != 1; + } + /* AAD. */ + if (err == 0) { + err = EVP_DecryptUpdate(ctx, NULL, &decLen, aad, + (int)strlen((char *)aad)) != 1; + } + /* Decrypt. */ + if (err == 0) { + err = EVP_DecryptUpdate(ctx, dec, &decLen, enc, len) != 1; + } + if (err == 0) { + err = EVP_DecryptFinal_ex(ctx, dec + decLen, &decLen) != 1; + } + if (err == 0 && dec != NULL && msg != NULL) { + PRINT_BUFFER("Decrypted", dec, len); + if (memcmp(dec, msg, len) != 0) { + err = 1; + } + } + + EVP_CIPHER_CTX_free(ctx); + return err; +} + +static int test_aes_gcm_set_iv_inv(void *data, const char *cipher, + int keyLen, int ivFixedLen, int ivLen) +{ + int err = 0; + unsigned char msg[] = "Test pattern"; + unsigned char key[32]; + unsigned char iv[12]; + unsigned char aad[] = "AAD"; + unsigned char enc[sizeof(msg)]; + unsigned char tag[AES_BLOCK_SIZE]; + unsigned char dec[sizeof(msg)]; + EVP_CIPHER* ocipher; + EVP_CIPHER* wcipher; + + (void)data; + + ocipher = EVP_CIPHER_fetch(osslLibCtx, cipher, ""); + wcipher = EVP_CIPHER_fetch(wpLibCtx, cipher, ""); + + if (RAND_bytes(key, keyLen) == 0) { + err = 1; + } + if (err == 0) { + if (RAND_bytes(iv, sizeof(iv)) == 0) { + err = 1; + } + } + + if (err == 0) { + PRINT_BUFFER("Key", key, keyLen); + PRINT_BUFFER("IV", iv, ivLen); + PRINT_BUFFER("Message", msg, sizeof(msg)); + } + + /* Encrypt with OpenSSL using fixed IV, decrypt with wolfProvider + * using OSSL_PARAM SET_IV_INV. */ + if (err == 0) { + PRINT_MSG("Encrypt with OpenSSL (fixed IV)"); + err = test_aes_tag_fixed_enc(ocipher, key, iv, ivFixedLen, ivLen, + aad, msg, sizeof(msg), enc, tag); + } + if (err == 0) { + PRINT_MSG("Decrypt with wolfprovider (SET_IV_INV via OSSL_PARAM)"); + err = test_aes_gcm_set_iv_inv_dec(wcipher, key, iv, ivFixedLen, ivLen, + aad, msg, sizeof(msg), enc, tag, + dec); + } + + /* Encrypt with wolfProvider using fixed IV, decrypt with wolfProvider + * using OSSL_PARAM SET_IV_INV. */ + if (err == 0) { + PRINT_MSG("Encrypt with wolfprovider (fixed IV)"); + err = test_aes_tag_fixed_enc(wcipher, key, iv, ivFixedLen, ivLen, + aad, msg, sizeof(msg), enc, tag); + } + if (err == 0) { + PRINT_MSG("Decrypt with wolfprovider (SET_IV_INV via OSSL_PARAM)"); + err = test_aes_gcm_set_iv_inv_dec(wcipher, key, iv, ivFixedLen, ivLen, + aad, msg, sizeof(msg), enc, tag, + dec); + } + + /* Encrypt with wolfProvider using fixed IV, decrypt with OpenSSL + * using OSSL_PARAM SET_IV_INV. */ + if (err == 0) { + PRINT_MSG("Encrypt with wolfprovider (fixed IV)"); + err = test_aes_tag_fixed_enc(wcipher, key, iv, ivFixedLen, ivLen, + aad, msg, sizeof(msg), enc, tag); + } + if (err == 0) { + PRINT_MSG("Decrypt with OpenSSL (SET_IV_INV via OSSL_PARAM)"); + err = test_aes_gcm_set_iv_inv_dec(ocipher, key, iv, ivFixedLen, ivLen, + aad, msg, sizeof(msg), enc, tag, + dec); + } + + EVP_CIPHER_free(wcipher); + EVP_CIPHER_free(ocipher); + + return err; +} + +int test_aes128_gcm_set_iv_inv(void *data) +{ + return test_aes_gcm_set_iv_inv(data, "AES-128-GCM", 16, + EVP_GCM_TLS_FIXED_IV_LEN, 12); +} + #endif /* WP_HAVE_AESGCM */ /******************************************************************************/ diff --git a/test/unit.c b/test/unit.c index 75c106bc..0e03de10 100644 --- a/test/unit.c +++ b/test/unit.c @@ -267,6 +267,7 @@ TEST_CASE test_case[] = { TEST_DECL(test_aes256_gcm, NULL), TEST_DECL(test_aes128_gcm_fixed, NULL), TEST_DECL(test_aes128_gcm_tls, NULL), + TEST_DECL(test_aes128_gcm_set_iv_inv, NULL), #endif #ifdef WP_HAVE_AESCCM TEST_DECL(test_aes128_ccm, NULL), diff --git a/test/unit.h b/test/unit.h index e79101cd..7f9ebbd8 100644 --- a/test/unit.h +++ b/test/unit.h @@ -194,6 +194,7 @@ int test_aes192_gcm(void *data); int test_aes256_gcm(void *data); int test_aes128_gcm_fixed(void *data); int test_aes128_gcm_tls(void *data); +int test_aes128_gcm_set_iv_inv(void *data); #endif /* WP_HAVE_AESGCM */