The branch OpenSSL_1_1_1-stable has been updated via bc8c36272067f8443f875164831ce3a5a739df3f (commit) via 32f7f60ccae59c7027010ec0b54c118ade087a41 (commit) from 75a4f263ba9d3ec1e9d55ca5024aee62aec70475 (commit)
- Log ----------------------------------------------------------------- commit bc8c36272067f8443f875164831ce3a5a739df3f Author: Ingo Franzki <ifran...@linux.ibm.com> Date: Wed Aug 11 12:53:09 2021 +0200 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 did not update the IV in the context, but only within its s390x specific context data. Signed-off-by: Ingo Franzki <ifran...@linux.ibm.com> Reviewed-by: Patrick Steuer <patrick.ste...@de.ibm.com> Reviewed-by: Tomas Mraz <to...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/16292) commit 32f7f60ccae59c7027010ec0b54c118ade087a41 Author: Ingo Franzki <ifran...@linux.ibm.com> Date: Wed Aug 11 09:39:46 2021 +0200 s390x: AES OFB/CFB: Maintain running IV from cipher context Copy the current IV from the cipher context into the kmo/kmf param before the operation, and copy the modified IV back to the context afterwards. Without this, an application that obtains the running IV from the context would still get the original IV, but not the updated one. Signed-off-by: Ingo Franzki <ifran...@linux.ibm.com> Reviewed-by: Patrick Steuer <patrick.ste...@de.ibm.com> Reviewed-by: Tomas Mraz <to...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/16292) ----------------------------------------------------------------------- Summary of changes: crypto/evp/e_aes.c | 12 ++++++ test/evp_extra_test.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index b5ea4032fd..73cadbf593 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -1240,9 +1240,12 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx); + const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); int n = cctx->res; int rem; + memcpy(cctx->kmo.param.cv, iv, ivlen); while (n && len) { *out = *in ^ cctx->kmo.param.cv[n]; n = (n + 1) & 0xf; @@ -1271,6 +1274,7 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } } + memcpy(iv, cctx->kmo.param.cv, ivlen); cctx->res = n; return 1; } @@ -1311,10 +1315,13 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); const int keylen = EVP_CIPHER_CTX_key_length(ctx); const int enc = EVP_CIPHER_CTX_encrypting(ctx); + const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); int n = cctx->res; int rem; unsigned char tmp; + memcpy(cctx->kmf.param.cv, iv, ivlen); while (n && len) { tmp = *in; *out = cctx->kmf.param.cv[n] ^ tmp; @@ -1347,6 +1354,7 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } } + memcpy(iv, cctx->kmf.param.cv, ivlen); cctx->res = n; return 1; } @@ -1382,8 +1390,12 @@ static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); + const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); + memcpy(cctx->kmf.param.cv, iv, ivlen); s390x_kmf(in, len, out, cctx->fc, &cctx->kmf.param); + memcpy(iv, cctx->kmf.param.cv, ivlen); return 1; } diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 754b2d1bf1..16b3542efa 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -797,7 +797,116 @@ static int test_gcm_reinit(int idx) return testresult; } +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-cfb128", 1 + }, + { + "aes-128-cfb128", 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; + const EVP_CIPHER *type = NULL; + const unsigned char *updated_iv; + int iv_len; + char *errmsg = NULL; + + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())) { + errmsg = "CTX_ALLOC"; + goto err; + } + if ((type = EVP_get_cipherbyname(t->cipher)) == 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_ptr(updated_iv = EVP_CIPHER_CTX_iv(ctx))) { + errmsg = "CIPHER_CTX_IV"; + goto err; + } + if (!TEST_true(iv_len = EVP_CIPHER_CTX_iv_length(ctx))) { + errmsg = "CIPHER_CTX_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); + return testresult; +} static APK_DATA keydata[] = { {kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), EVP_PKEY_RSA}, @@ -1690,6 +1799,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)); return 1; }