]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Test EVP Cipher updating the context's IV
authorIngo Franzki <ifranzki@linux.ibm.com>
Wed, 11 Aug 2021 10:53:09 +0000 (12:53 +0200)
committerTomas Mraz <tomas@openssl.org>
Mon, 16 Aug 2021 10:59:31 +0000 (12:59 +0200)
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 <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/16292)

test/evp_extra_test.c

index 754b2d1bf105d1912921db1529a7ad2172e2916d..16b3542efa6d2a04de124ab253dc95b85c6da5ac 100644 (file)
@@ -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;
 }