diff options
| author | Trust-Worthy <[email protected]> | 2026-10-01 00:22:45 +0200 |
|---|---|---|
| committer | Tomas Mraz <[email protected]> | 2026-10-21 18:59:44 +0200 |
| commit | 77bde2b32b4563f1fe4248eafdcd2bd6dfb29dc3 (patch) | |
| tree | 151474c8e1c65633db7d1ae0f62c27b898cd8858 /test/evp_aead_test.c | |
| parent | Reject a NULL input to update in the other AEADs (diff) | |
| download | openssl-77bde2b32b4563f1fe4248eafdcd2bd6dfb29dc3.tar.gz openssl-77bde2b32b4563f1fe4248eafdcd2bd6dfb29dc3.zip | |
Add test for an update with no input
An update with no input and a nonzero length must fail, except for the
CCM message length. test_evp_aead_update_null_input checks this for
every AEAD, and that a rejected update writes no output.
Assisted-by: Claude:claude-opus-5-5
Reviewed-by: Paul Dale <[email protected]>
Reviewed-by: Neil Horman <[email protected]>
Merge-date: Wed Oct 21 16:59:57 2026
Merged-from: https://github.com/openssl/openssl/pull/33157
Diffstat (limited to 'test/evp_aead_test.c')
| -rw-r--r-- | test/evp_aead_test.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/test/evp_aead_test.c b/test/evp_aead_test.c index d0ec6876b49..48c217ffc60 100644 --- a/test/evp_aead_test.c +++ b/test/evp_aead_test.c @@ -858,6 +858,95 @@ err: return ret; } +/* + * An update with no input and a nonzero length must fail, except for the + * CCM message length, which is passed with no input and no output. This is + * checked for both encryption and decryption. + */ +static int test_evp_aead_update_null_input(int idx) +{ + const AEAD_DATA *info = &aead_list[idx]; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char key[EVP_MAX_KEY_LENGTH] = { 0 }; + unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char out[16] = { 0xAB }, untouched[16] = { 0xAB }; + int outl = 0, testresult = 0; + + /* encrypt: no input, no output -- valid only as the CCM message length */ + ERR_clear_error(); + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_EncryptInit_ex2(ctx, info->ciph, key, iv, NULL))) + goto err; + if (info->mode == EVP_CIPH_CCM_MODE) { + if (!TEST_true(EVP_EncryptUpdate(ctx, NULL, &outl, NULL, 16))) { + TEST_info("encrypt CCM length rejected: idx=%d cipher=%s", + idx, info->name); + goto err; + } + } else if (!TEST_false(EVP_EncryptUpdate(ctx, NULL, &outl, NULL, 16)) + || !TEST_err_r(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER)) { + TEST_info("encrypt no input, no output: idx=%d cipher=%s", + idx, info->name); + goto err; + } + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* encrypt: no input with an output buffer -- always fails, writes nothing */ + ERR_clear_error(); + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_EncryptInit_ex2(ctx, info->ciph, key, iv, NULL)) + || !TEST_false(EVP_EncryptUpdate(ctx, out, &outl, NULL, 16)) + || !TEST_err_r(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER) + || !TEST_int_eq(outl, 0) + || !TEST_mem_eq(out, sizeof(out), untouched, sizeof(untouched))) { + TEST_info("encrypt no input, with output: idx=%d cipher=%s", + idx, info->name); + goto err; + } + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* decrypt: no input, no output -- valid only as the CCM message length */ + ERR_clear_error(); + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_DecryptInit_ex2(ctx, info->ciph, key, iv, NULL))) + goto err; + if (info->mode == EVP_CIPH_CCM_MODE) { + if (!TEST_true(EVP_DecryptUpdate(ctx, NULL, &outl, NULL, 16))) { + TEST_info("decrypt CCM length rejected: idx=%d cipher=%s", + idx, info->name); + goto err; + } + } else if (!TEST_false(EVP_DecryptUpdate(ctx, NULL, &outl, NULL, 16)) + || !TEST_err_r(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER)) { + TEST_info("decrypt no input, no output: idx=%d cipher=%s", + idx, info->name); + goto err; + } + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + + /* decrypt: no input with an output buffer -- always fails, writes nothing */ + ERR_clear_error(); + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_DecryptInit_ex2(ctx, info->ciph, key, iv, NULL)) + || !TEST_false(EVP_DecryptUpdate(ctx, out, &outl, NULL, 16)) + || !TEST_err_r(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER) + || !TEST_int_eq(outl, 0) + || !TEST_mem_eq(out, sizeof(out), untouched, sizeof(untouched))) { + TEST_info("decrypt no input, with output: idx=%d cipher=%s", + idx, info->name); + goto err; + } + + testresult = 1; +err: + ERR_clear_error(); + EVP_CIPHER_CTX_free(ctx); + return testresult; +} + int setup_tests(void) { size_t i = 0; @@ -879,6 +968,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_evp_aead_get_tag_pairwise, OSSL_NELEM(aead_list)); ADD_ALL_TESTS(test_evp_final_no_tag, OSSL_NELEM(aead_list)); ADD_ALL_TESTS(test_evp_aead_enc_retval, OSSL_NELEM(aead_list)); + ADD_ALL_TESTS(test_evp_aead_update_null_input, OSSL_NELEM(aead_list)); return 1; } |
