diff options
author | Ingo Franzki <ifranzki@linux.ibm.com> | 2021-08-11 13:04:52 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-08-16 13:02:51 +0200 |
commit | f17e52778f1f7b2703de73e488e7f9229c11dce4 (patch) | |
tree | a07dad91007dc7f4201c0af007a60267ab0c47aa | |
parent | c719ea171ce16a919014e5ca2f5217ae35219bdd (diff) |
Test EVP Cipher updating the context's IV
Ensure that an EVP_CipherUpdate operation updates the context's
IV for AES CBC, CFB, OFB, and CTR. An application can get the
updated IV via EVP_CIPHER_CTX_iv().
The s390x implementation of the CFB and OFB ciphers in e_aes.c did not
update the IV in the context, but only within its s390x specific
context data.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16291)
-rw-r--r-- | test/evp_extra_test.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 418b467f52..bc02cea95d 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -3334,6 +3334,113 @@ static int test_evp_reset(int idx) } typedef struct { + const char *cipher; + int enc; +} EVP_UPDATED_IV_TEST_st; + +static const EVP_UPDATED_IV_TEST_st evp_updated_iv_tests[] = { + { + "aes-128-cfb", 1 + }, + { + "aes-128-cfb", 0 + }, + { + "aes-128-cfb1", 1 + }, + { + "aes-128-cfb1", 0 + }, + { + "aes-128-cfb8", 1 + }, + { + "aes-128-cfb8", 0 + }, + { + "aes-128-ofb", 1 + }, + { + "aes-128-ofb", 0 + }, + { + "aes-128-ctr", 1 + }, + { + "aes-128-ctr", 0 + }, + { + "aes-128-cbc", 1 + }, + { + "aes-128-cbc", 0 + } +}; + +/* + * Test that the IV in the context is updated during a crypto operation for CFB + * and OFB. + */ +static int test_evp_updated_iv(int idx) +{ + const EVP_UPDATED_IV_TEST_st *t = &evp_updated_iv_tests[idx]; + int outlen1, outlen2; + int testresult = 0; + unsigned char outbuf[1024]; + EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER *type = NULL; + unsigned char updated_iv[EVP_MAX_IV_LENGTH]; + int iv_len; + char *errmsg = NULL; + + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())) { + errmsg = "CTX_ALLOC"; + goto err; + } + if ((type = EVP_CIPHER_fetch(testctx, t->cipher, testpropq)) == NULL) { + TEST_info("cipher %s not supported, skipping", t->cipher); + goto ok; + } + + if (!TEST_true(EVP_CipherInit_ex(ctx, type, NULL, kCFBDefaultKey, iCFBIV, t->enc))) { + errmsg = "CIPHER_INIT"; + goto err; + } + if (!TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0))) { + errmsg = "PADDING"; + goto err; + } + if (!TEST_true(EVP_CipherUpdate(ctx, outbuf, &outlen1, cfbPlaintext, sizeof(cfbPlaintext)))) { + errmsg = "CIPHER_UPDATE"; + goto err; + } + if (!TEST_true(EVP_CIPHER_CTX_get_updated_iv(ctx, updated_iv, sizeof(updated_iv)))) { + errmsg = "CIPHER_CTX_GET_UPDATED_IV"; + goto err; + } + if (!TEST_true(iv_len = EVP_CIPHER_CTX_get_iv_length(ctx))) { + errmsg = "CIPHER_CTX_GET_IV_LEN"; + goto err; + } + if (!TEST_mem_ne(iCFBIV, sizeof(iCFBIV), updated_iv, iv_len)) { + errmsg = "IV_NOT_UPDATED"; + goto err; + } + if (!TEST_true(EVP_CipherFinal_ex(ctx, outbuf + outlen1, &outlen2))) { + errmsg = "CIPHER_FINAL"; + goto err; + } + ok: + testresult = 1; + err: + if (errmsg != NULL) + TEST_info("test_evp_updated_iv %d: %s", idx, errmsg); + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_free(type); + return testresult; +} + +typedef struct { const unsigned char *iv1; const unsigned char *iv2; const unsigned char *expected1; @@ -3851,6 +3958,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_evp_init_seq, OSSL_NELEM(evp_init_tests)); ADD_ALL_TESTS(test_evp_reset, OSSL_NELEM(evp_reset_tests)); ADD_ALL_TESTS(test_gcm_reinit, OSSL_NELEM(gcm_reinit_tests)); + ADD_ALL_TESTS(test_evp_updated_iv, OSSL_NELEM(evp_updated_iv_tests)); #ifndef OPENSSL_NO_DEPRECATED_3_0 ADD_ALL_TESTS(test_custom_pmeth, 12); |