[openssl] master update

Matt Caswell matt at openssl.org
Fri Nov 29 11:03:58 UTC 2019


The branch master has been updated
       via  b4be6937f2a80aa48afd1e3de50749874e4ad9b5 (commit)
       via  4b9c750be83644aca15a98e75b566e7f6c3644d7 (commit)
      from  cff64af5532d3a1b0e2e9adf88454887efba01b2 (commit)


- Log -----------------------------------------------------------------
commit b4be6937f2a80aa48afd1e3de50749874e4ad9b5
Author: Matt Caswell <matt at openssl.org>
Date:   Fri May 31 14:32:55 2019 +0100

    Add a test for NULL chunks in encrypt/decrypt
    
    Issue #8675 describes a problem where calling EVP_DecryptUpdate() with an
    empty chunk causes the result to be different compared to if you do not
    use an empty chunk. This adds a test for that case.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10530)

commit 4b9c750be83644aca15a98e75b566e7f6c3644d7
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Nov 27 16:06:34 2019 +0000

    Make sure we handle input NULL with length 0
    
    If we call EVP_EncryptUpdate/EVP_DecryptUpdate with length 0 we should
    be able to handle it. Most importantly we shouldn't get different
    results if we do this compared to if we don't!
    
    An exception is made for CCM mode which has special handling for this in
    the low level cipher function.
    
    Fixes #8675
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10530)

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

Summary of changes:
 providers/common/ciphers/cipher_common.c           |  5 ++
 providers/common/ciphers/cipher_gcm.c              |  5 ++
 providers/implementations/ciphers/cipher_aes_ocb.c |  5 ++
 providers/implementations/ciphers/cipher_aes_siv.c |  5 ++
 providers/implementations/ciphers/cipher_aes_wrp.c |  5 ++
 .../ciphers/cipher_chacha20_poly1305.c             |  5 ++
 .../implementations/ciphers/cipher_tdes_wrap.c     |  2 +
 test/evp_extra_test.c                              | 69 ++++++++++++++++++++++
 8 files changed, 101 insertions(+)

diff --git a/providers/common/ciphers/cipher_common.c b/providers/common/ciphers/cipher_common.c
index 8f39a168c8..83c370793b 100644
--- a/providers/common/ciphers/cipher_common.c
+++ b/providers/common/ciphers/cipher_common.c
@@ -291,6 +291,11 @@ int cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
diff --git a/providers/common/ciphers/cipher_gcm.c b/providers/common/ciphers/cipher_gcm.c
index f479bc8fda..619d4f61b0 100644
--- a/providers/common/ciphers/cipher_gcm.c
+++ b/providers/common/ciphers/cipher_gcm.c
@@ -210,6 +210,11 @@ int gcm_stream_update(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return -1;
diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c
index ba4e4f29f8..6b07caaa52 100644
--- a/providers/implementations/ciphers/cipher_aes_ocb.c
+++ b/providers/implementations/ciphers/cipher_aes_ocb.c
@@ -214,6 +214,11 @@ static int aes_ocb_block_update(void *vctx, unsigned char *out, size_t *outl,
     if (!ctx->key_set || !update_iv(ctx))
         return 0;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     /* Are we dealing with AAD or normal data here? */
     if (out == NULL) {
         buf = ctx->aad_buf;
diff --git a/providers/implementations/ciphers/cipher_aes_siv.c b/providers/implementations/ciphers/cipher_aes_siv.c
index 18be36e9b3..864ebc725e 100644
--- a/providers/implementations/ciphers/cipher_aes_siv.c
+++ b/providers/implementations/ciphers/cipher_aes_siv.c
@@ -76,6 +76,11 @@ static int siv_cipher(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c
index 028676943e..5dedde748a 100644
--- a/providers/implementations/ciphers/cipher_aes_wrp.c
+++ b/providers/implementations/ciphers/cipher_aes_wrp.c
@@ -164,6 +164,11 @@ static int aes_wrap_cipher(void *vctx,
     PROV_AES_WRAP_CTX *ctx = (PROV_AES_WRAP_CTX *)vctx;
     size_t len;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return -1;
diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c
index b92d8d545e..6bf88dbd9e 100644
--- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c
+++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c
@@ -262,6 +262,11 @@ static int chacha20_poly1305_cipher(void *vctx, unsigned char *out,
     PROV_CIPHER_HW_CHACHA20_POLY1305 *hw =
         (PROV_CIPHER_HW_CHACHA20_POLY1305 *)ctx->hw;
 
+    if (inl == 0) {
+        *outl = 0;
+        return 1;
+    }
+
     if (outsize < inl) {
         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
diff --git a/providers/implementations/ciphers/cipher_tdes_wrap.c b/providers/implementations/ciphers/cipher_tdes_wrap.c
index d899985202..fc49696fbd 100644
--- a/providers/implementations/ciphers/cipher_tdes_wrap.c
+++ b/providers/implementations/ciphers/cipher_tdes_wrap.c
@@ -145,6 +145,8 @@ static int tdes_wrap_update(void *vctx, unsigned char *out, size_t *outl,
                             size_t inl)
 {
     *outl = 0;
+    if (inl == 0)
+        return 1;
     if (outsize < inl) {
         PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
         return 0;
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index f4e792fb1d..ce487049f3 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -1346,6 +1346,72 @@ static int test_EVP_PKEY_CTX_get_set_params(void)
 }
 #endif
 
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+static int test_decrypt_null_chunks(void)
+{
+    EVP_CIPHER_CTX* ctx = NULL;
+    const unsigned char key[32] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+        0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1
+    };
+    unsigned char iv[12] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b
+    };
+    unsigned char msg[] = "It was the best of times, it was the worst of times";
+    unsigned char ciphertext[80];
+    unsigned char plaintext[80];
+    /* We initialise tmp to a non zero value on purpose */
+    int ctlen, ptlen, tmp = 99;
+    int ret = 0;
+    const int enc_offset = 10, dec_offset = 20;
+
+    if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
+            || !TEST_true(EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL,
+                                             key, iv))
+            || !TEST_true(EVP_EncryptUpdate(ctx, ciphertext, &ctlen, msg,
+                                            enc_offset))
+            /* Deliberate add a zero length update */
+            || !TEST_true(EVP_EncryptUpdate(ctx, ciphertext + ctlen, &tmp, NULL,
+                                            0))
+            || !TEST_int_eq(tmp, 0)
+            || !TEST_true(EVP_EncryptUpdate(ctx, ciphertext + ctlen, &tmp,
+                                            msg + enc_offset,
+                                            sizeof(msg) - enc_offset))
+            || !TEST_int_eq(ctlen += tmp, sizeof(msg))
+            || !TEST_true(EVP_EncryptFinal(ctx, ciphertext + ctlen, &tmp))
+            || !TEST_int_eq(tmp, 0))
+        goto err;
+
+    /* Deliberately initialise tmp to a non zero value */
+    tmp = 99;
+    if (!TEST_true(EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key,
+                                      iv))
+            || !TEST_true(EVP_DecryptUpdate(ctx, plaintext, &ptlen, ciphertext,
+                                            dec_offset))
+            /*
+             * Deliberately add a zero length update. We also deliberately do
+             * this at a different offset than for encryption.
+             */
+            || !TEST_true(EVP_DecryptUpdate(ctx, plaintext + ptlen, &tmp, NULL,
+                                            0))
+            || !TEST_int_eq(tmp, 0)
+            || !TEST_true(EVP_DecryptUpdate(ctx, plaintext + ptlen, &tmp,
+                                            ciphertext + dec_offset,
+                                            ctlen - dec_offset))
+            || !TEST_int_eq(ptlen += tmp, sizeof(msg))
+            || !TEST_true(EVP_DecryptFinal(ctx, plaintext + ptlen, &tmp))
+            || !TEST_int_eq(tmp, 0)
+            || !TEST_mem_eq(msg, sizeof(msg), plaintext, ptlen))
+        goto err;
+
+    ret = 1;
+ err:
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+#endif /* !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) */
+
 int setup_tests(void)
 {
     ADD_ALL_TESTS(test_EVP_DigestSignInit, 4);
@@ -1377,6 +1443,9 @@ int setup_tests(void)
 #endif
 #ifndef OPENSSL_NO_DSA
     ADD_TEST(test_EVP_PKEY_CTX_get_set_params);
+#endif
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+    ADD_TEST(test_decrypt_null_chunks);
 #endif
     return 1;
 }


More information about the openssl-commits mailing list