]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ssl_evp_cipher_fetch(): Avoid using 3DES from the FIPS provider
authorTomas Mraz <tomas@openssl.org>
Tue, 30 Jul 2024 07:31:11 +0000 (09:31 +0200)
committerTomas Mraz <tomas@openssl.org>
Thu, 1 Aug 2024 15:29:39 +0000 (17:29 +0200)
Avoid using a fetched cipher that is decrypt-only
which is the case for 3DES from the fips provider.

Add a decrypt-only parameter to the EVP_CIPHER and test it
in libssl when fetching.

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25028)

doc/man3/EVP_EncryptInit.pod
providers/implementations/ciphers/cipher_tdes.h
providers/implementations/ciphers/cipher_tdes_common.c
ssl/ssl_lib.c
util/perl/OpenSSL/paramnames.pm

index 41b5e1077729bfaa139cb21b66a3254ec3f04d2b..0bad8d48738358febeb5a83dfce403c5849054e6 100644 (file)
@@ -733,6 +733,12 @@ Gets 1 if the cipher algorithm I<cipher> supports the gettable EVP_CIPHER_CTX
 parameter B<OSSL_CIPHER_PARAM_RANDOM_KEY>. Only DES and 3DES set this to 1,
 all other OpenSSL ciphers return 0.
 
+=item "decrypt-only" (B<OSSL_CIPHER_PARAM_DECRYPT_ONLY) <integer>
+
+Gets 1 if the cipher algorithm I<cipher> implementation supports only
+the decryption operation such as the 3DES ciphers in the fips provider.
+Otherwise gets 0 or the parameter might not be present at all.
+
 =back
 
 =head2 Gettable and Settable EVP_CIPHER_CTX parameters
index 765ec8b5e1364b499ab1f2b6000f8757e051743a..d0bd79b7118cfe6829d8b4d7c5c4ae9c3311b19c 100644 (file)
@@ -42,8 +42,8 @@ static void *tdes_##type##_##lcmode##_newctx(void *provctx)                    \
 static OSSL_FUNC_cipher_get_params_fn tdes_##type##_##lcmode##_get_params;     \
 static int tdes_##type##_##lcmode##_get_params(OSSL_PARAM params[])            \
 {                                                                              \
-    return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,    \
-                                          flags, kbits, blkbits, ivbits);      \
+    return ossl_tdes_get_params(params, EVP_CIPH_##UCMODE##_MODE,              \
+                                flags, kbits, blkbits, ivbits);                \
 }                                                                              \
 const OSSL_DISPATCH ossl_tdes_##type##_##lcmode##_functions[] = {              \
     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_tdes_einit },        \
@@ -74,6 +74,9 @@ const OSSL_DISPATCH ossl_tdes_##type##_##lcmode##_functions[] = {              \
 
 void *ossl_tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
                        size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw);
+int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags,
+                         size_t kbits, size_t blkbits, size_t ivbits);
+
 OSSL_FUNC_cipher_dupctx_fn ossl_tdes_dupctx;
 OSSL_FUNC_cipher_freectx_fn ossl_tdes_freectx;
 OSSL_FUNC_cipher_encrypt_init_fn ossl_tdes_einit;
index 1c7572c77d879b4391e31ca620e739d3c46ef24f..60f0707951d9928882393e705cc3adabf1df60fb 100644 (file)
@@ -185,3 +185,23 @@ int ossl_tdes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
         return 0;
     return ossl_cipher_generic_set_ctx_params(vctx, params);
 }
+
+int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags,
+                         size_t kbits, size_t blkbits, size_t ivbits)
+{
+#ifdef FIPS_MODULE
+    const int decrypt_only = 1;
+#else
+    const int decrypt_only = 0;
+#endif
+    OSSL_PARAM *p;
+
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_DECRYPT_ONLY);
+    if (p != NULL && !OSSL_PARAM_set_int(p, decrypt_only)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
+
+    return ossl_cipher_generic_get_params(params, md, flags,
+                                          kbits, blkbits, ivbits);
+}
index ccb9ac1dd1cec4b52cb7e91f5dfdf07d2080e98d..f1fe71866015634c63084c81ad271bddc67d93e3 100644 (file)
@@ -22,6 +22,7 @@
 #include <openssl/ct.h>
 #include <openssl/trace.h>
 #include <openssl/core_names.h>
+#include <openssl/provider.h>
 #include "internal/cryptlib.h"
 #include "internal/nelem.h"
 #include "internal/refcount.h"
@@ -7235,6 +7236,20 @@ const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx,
      */
     ERR_set_mark();
     ciph = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), properties);
+    if (ciph != NULL) {
+        OSSL_PARAM params[2];
+        int decrypt_only = 0;
+
+        params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_DECRYPT_ONLY,
+                                             &decrypt_only);
+        params[1] = OSSL_PARAM_construct_end();
+        if (EVP_CIPHER_get_params((EVP_CIPHER *)ciph, params)
+            && decrypt_only) {
+            /* If a cipher is decrypt-only, it is unusable */
+            EVP_CIPHER_free((EVP_CIPHER *)ciph);
+            ciph = NULL;
+        }
+    }
     ERR_pop_to_mark();
     return ciph;
 }
index 5fdeea4b885abd24412f79cb196371fe3cc10e09..223181652da5ace13db5bbca7900097b832bfbed 100644 (file)
@@ -117,6 +117,7 @@ my %params = (
     'CIPHER_PARAM_RC2_KEYBITS' =>          "keybits",     # size_t
     'CIPHER_PARAM_SPEED' =>                "speed",       # uint
     'CIPHER_PARAM_CTS_MODE' =>             "cts_mode",    # utf8_string
+    'CIPHER_PARAM_DECRYPT_ONLY' =>         "decrypt-only",  # int, 0 or 1
     'CIPHER_PARAM_FIPS_ENCRYPT_CHECK' =>   "encrypt-check", # int
     'CIPHER_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
 # For passing the AlgorithmIdentifier parameter in DER form