Move the caching of cipher constants into evp_cipher_from_dispatch
authorMatt Caswell <matt@openssl.org>
Tue, 22 Dec 2020 11:54:16 +0000 (11:54 +0000)
committerDmitry Belyavskiy <beldmit@gmail.com>
Wed, 23 Dec 2020 20:12:18 +0000 (21:12 +0100)
Previously we cached the cipher constants in EVP_CIPHER_fetch(). However,
this means we do the caching every time we call that function, even if
the core has previusly fetched the cipher and cached it already. This
means we can end up re-caching the constants even though they are already
present. This also means we could be updating these constants from
multiple threads at the same time.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/13730)

crypto/err/openssl.txt
crypto/evp/evp_enc.c
crypto/evp/evp_err.c
include/crypto/evperr.h
include/openssl/evperr.h

index 60f343eb7d755ca45c38f122723f763e752f22a8..5440e47093aa06227466e0e2521a2dbc7a284f1f 100644 (file)
@@ -2528,6 +2528,7 @@ EVP_R_BAD_ALGORITHM_NAME:200:bad algorithm name
 EVP_R_BAD_DECRYPT:100:bad decrypt
 EVP_R_BAD_KEY_LENGTH:195:bad key length
 EVP_R_BUFFER_TOO_SMALL:155:buffer too small
+EVP_R_CACHE_CONSTANTS_FAILED:225:cache constants failed
 EVP_R_CAMELLIA_KEY_SETUP_FAILED:157:camellia key setup failed
 EVP_R_CANNOT_GET_PARAMETERS:197:cannot get parameters
 EVP_R_CANNOT_SET_PARAMETERS:198:cannot set parameters
index 7818ab25ea22661e61d54e813d8432a4f33b85db..c1c8f1cf2865ed0bbf503d70b93d4314b058d125 100644 (file)
@@ -1470,6 +1470,12 @@ static void *evp_cipher_from_dispatch(const int name_id,
     if (prov != NULL)
         ossl_provider_up_ref(prov);
 
+    if (!evp_cipher_cache_constants(cipher)) {
+        EVP_CIPHER_free(cipher);
+        ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED);
+        cipher = NULL;
+    }
+
     return cipher;
 }
 
@@ -1491,10 +1497,6 @@ EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
                           evp_cipher_from_dispatch, evp_cipher_up_ref,
                           evp_cipher_free);
 
-    if (cipher != NULL && !evp_cipher_cache_constants(cipher)) {
-        EVP_CIPHER_free(cipher);
-        cipher = NULL;
-    }
     return cipher;
 }
 
index c2259f0beb4c230886881dbf37082072fbcc81d9..894f0cebcb39712b48e46afa38f0de41c092ea3f 100644 (file)
@@ -23,6 +23,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT), "bad decrypt"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_KEY_LENGTH), "bad key length"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CACHE_CONSTANTS_FAILED),
+    "cache constants failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
     "camellia key setup failed"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_GET_PARAMETERS),
index 7ca726d51cd469611f1bc76fd4e1ccc48fff61f1..2bfc71ad3c6f7a4a5cbcd8f94ae7fbf9809f4323 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
index 2fdd99336f3588b86eaf31181cb396a587f89db3..4e9989899f5d263941e20fa1b001fe78b59be199 100644 (file)
 # define EVP_R_BAD_DECRYPT                                100
 # define EVP_R_BAD_KEY_LENGTH                             195
 # define EVP_R_BUFFER_TOO_SMALL                           155
+# define EVP_R_CACHE_CONSTANTS_FAILED                     225
 # define EVP_R_CAMELLIA_KEY_SETUP_FAILED                  157
 # define EVP_R_CANNOT_GET_PARAMETERS                      197
 # define EVP_R_CANNOT_SET_PARAMETERS                      198