[openssl] master update

tomas at openssl.org tomas at openssl.org
Mon Aug 16 11:03:13 UTC 2021


The branch master has been updated
       via  f17e52778f1f7b2703de73e488e7f9229c11dce4 (commit)
       via  c719ea171ce16a919014e5ca2f5217ae35219bdd (commit)
      from  0449702abc95a3af24c049cb02c01ca6a8015cef (commit)


- Log -----------------------------------------------------------------
commit f17e52778f1f7b2703de73e488e7f9229c11dce4
Author: Ingo Franzki <ifranzki at linux.ibm.com>
Date:   Wed Aug 11 13:04:52 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 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 at linux.ibm.com>
    
    Reviewed-by: Patrick Steuer <patrick.steuer at de.ibm.com>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16291)

commit c719ea171ce16a919014e5ca2f5217ae35219bdd
Author: Ingo Franzki <ifranzki at 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.
    
    This implementation in e_aes.c now matches the code in cipher_aes_hw_s390x.inc
    that is used for the provider implementation.
    
    Signed-off-by: Ingo Franzki <ifranzki at linux.ibm.com>
    
    Reviewed-by: Patrick Steuer <patrick.steuer at de.ibm.com>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16291)

-----------------------------------------------------------------------

Summary of changes:
 crypto/evp/e_aes.c    |  12 ++++++
 test/evp_extra_test.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index 6d5506056e..52b9e87c1e 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -1010,9 +1010,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_get_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;
@@ -1041,6 +1044,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;
 }
@@ -1071,10 +1075,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_get_key_length(ctx);
     const int enc = EVP_CIPHER_CTX_is_encrypting(ctx);
+    const int ivlen = EVP_CIPHER_CTX_get_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;
@@ -1107,6 +1114,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;
 }
@@ -1134,8 +1142,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_get_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 418b467f52..bc02cea95d 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -3333,6 +3333,113 @@ static int test_evp_reset(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-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;
@@ -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);


More information about the openssl-commits mailing list