Fix IV length caching in EVP encryption code
authorHugo Landau <hlandau@openssl.org>
Thu, 10 Mar 2022 12:42:05 +0000 (12:42 +0000)
committerPauli <pauli@openssl.org>
Tue, 15 Mar 2022 10:05:05 +0000 (21:05 +1100)
The IV length cache value was being invalidated excessively, causing IV
length caching to be ineffective.

Related to #17064.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17862)

crypto/evp/evp_enc.c

index 7ae92df98b0e6ef7a98f30702bbf097db1fff093..02566ae949ab0595773128a2cbcb4f794af0c7bc 100644 (file)
@@ -62,13 +62,20 @@ int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
     ENGINE_finish(ctx->engine);
 #endif
     memset(ctx, 0, sizeof(*ctx));
-    ctx->iv_len = 0;
+    ctx->iv_len = -1;
     return 1;
 }
 
 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
 {
-    return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX));
+    EVP_CIPHER_CTX *ctx;
+
+    ctx = OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX));
+    if (ctx == NULL)
+        return NULL;
+
+    ctx->iv_len = -1;
+    return ctx;
 }
 
 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
@@ -90,8 +97,6 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx,
     ENGINE *tmpimpl = NULL;
 #endif
 
-    ctx->iv_len = -1;
-
     /*
      * enc == 1 means we are encrypting.
      * enc == 0 means we are decrypting.
@@ -1267,13 +1272,17 @@ int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[])
         r = ctx->cipher->set_ctx_params(ctx->algctx, params);
         if (r > 0) {
             p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
-            if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->key_len))
+            if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->key_len)) {
                 r = 0;
+                ctx->key_len = -1;
+            }
         }
         if (r > 0) {
             p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
-            if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->iv_len))
+            if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->iv_len)) {
                 r = 0;
+                ctx->iv_len = -1;
+            }
         }
     }
     return r;