]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add FIPS indicator support for Triple-DES encryption.
authorslontis <shane.lontis@oracle.com>
Mon, 22 Jul 2024 07:24:53 +0000 (17:24 +1000)
committerslontis <shane.lontis@oracle.com>
Fri, 26 Jul 2024 04:26:49 +0000 (14:26 +1000)
This leaves 3DES with the FIPS query "FIPS=yes", which allows
Triple-DES to be used for Decryption by default.

Disallow CMAC using Triple-DES in FIPS.
This does not use a FIPS indicator.

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/24960)

17 files changed:
apps/fipsinstall.c
doc/man1/openssl-fipsinstall.pod.in
doc/man3/EVP_EncryptInit.pod
doc/man7/EVP_CIPHER-DES.pod
include/openssl/fips_names.h
providers/common/include/prov/fipscommon.h
providers/fips/fipsprov.c
providers/implementations/ciphers/cipher_tdes.h
providers/implementations/ciphers/cipher_tdes_common.c
providers/implementations/macs/cmac_prov.c
test/evp_libctx_test.c
test/evp_test.c
test/recipes/30-test_evp_data/evpciph_des3_common.txt
test/recipes/30-test_evp_data/evpmac_cmac_des.txt
test/recipes/80-test_cms.t
util/mk-fipsmodule-cnf.pl
util/perl/OpenSSL/paramnames.pm

index 3b7d0819ecc7dcf689c09b6f5405962248a01662..5c585da4f233e819f37950b84883ededc7b1318b 100644 (file)
@@ -47,6 +47,7 @@ typedef enum OPTION_choice {
     OPT_SSKDF_DIGEST_CHECK,
     OPT_X963KDF_DIGEST_CHECK,
     OPT_DISALLOW_DSA_SIGN,
+    OPT_DISALLOW_TDES_ENCRYPT,
     OPT_SELF_TEST_ONLOAD, OPT_SELF_TEST_ONINSTALL
 } OPTION_CHOICE;
 
@@ -88,6 +89,8 @@ const OPTIONS fipsinstall_options[] = {
      "Enable digest check for X963KDF"},
     {"dsa_sign_disabled", OPT_DISALLOW_DSA_SIGN, '-',
      "Disallow DSA signing"},
+    {"tdes_encrypt_disabled", OPT_DISALLOW_TDES_ENCRYPT, '-',
+     "Disallow Triple-DES encryption"},
     OPT_SECTION("Input"),
     {"in", OPT_IN, '<', "Input config file, used when verifying"},
 
@@ -118,6 +121,7 @@ typedef struct {
     unsigned int sskdf_digest_check : 1;
     unsigned int x963kdf_digest_check : 1;
     unsigned int dsa_sign_disabled : 1;
+    unsigned int tdes_encrypt_disabled : 1;
 } FIPS_OPTS;
 
 /* Pedantic FIPS compliance */
@@ -135,6 +139,7 @@ static const FIPS_OPTS pedantic_opts = {
     1,      /* sskdf_digest_check */
     1,      /* x963kdf_digest_check */
     1,      /* dsa_sign_disabled */
+    1,      /* tdes_encrypt_disabled */
 };
 
 /* Default FIPS settings for backward compatibility */
@@ -152,6 +157,7 @@ static FIPS_OPTS fips_opts = {
     0,      /* sskdf_digest_check */
     0,      /* x963kdf_digest_check */
     0,      /* dsa_sign_disabled */
+    0,      /* tdes_encrypt_disabled */
 };
 
 static int check_non_pedantic_fips(int pedantic, const char *name)
@@ -295,6 +301,8 @@ static int write_config_fips_section(BIO *out, const char *section,
                       opts->x963kdf_digest_check ? "1": "0") <= 0
         || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_DSA_SIGN_DISABLED,
                       opts->dsa_sign_disabled ? "1" : "0") <= 0
+        || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED,
+                      opts->tdes_encrypt_disabled ? "1" : "0") <= 0
         || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
                       module_mac_len))
         goto end;
@@ -505,6 +513,9 @@ int fipsinstall_main(int argc, char **argv)
         case OPT_DISALLOW_DSA_SIGN:
             fips_opts.dsa_sign_disabled = 1;
             break;
+        case OPT_DISALLOW_TDES_ENCRYPT:
+            fips_opts.tdes_encrypt_disabled = 1;
+            break;
         case OPT_QUIET:
             quiet = 1;
             /* FALLTHROUGH */
index 0524c0fef12906778ba7566fd61194bcf60897a7..e9d6d140f1f0625fedc3b414b1884cee5032e710 100644 (file)
@@ -32,6 +32,7 @@ B<openssl fipsinstall>
 [B<-x963kdf_digest_check>]
 [B<-dsa_sign_disabled>]
 [B<-no_short_mac>]
+[B<-tdes_encrypt_disabled>]
 [B<-self_test_onload>]
 [B<-self_test_oninstall>]
 [B<-corrupt_desc> I<selftest_description>]
@@ -244,6 +245,12 @@ See NIST SP 800-131Ar2 for details.
 Configure the module to not allow DSA signing (DSA signature verification is
 still allowed). See FIPS 140-3 IG C.K for details.
 
+=item B<-tdes_encrypt_disabled>
+
+Configure the module to not allow Triple-DES encryption.
+Triple-DES decryption is still allowed for legacy purposes.
+See SP800-131Ar2 for details.
+
 =item B<-self_test_onload>
 
 Do not write the two fields related to the "test status indicator" and
index f89fc9ae05068076efa01c404c14aa536f0d33c9..41b5e1077729bfaa139cb21b66a3254ec3f04d2b 100644 (file)
@@ -893,6 +893,12 @@ Gets the result of running the "tls1multi_aad" operation.
 
 Used to pass the TLS MAC data.
 
+=item "fips-indicator" (B<OSSL_CIPHER_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
+
+A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
+This may be used after calling a cipher final operation such as
+EVP_EncryptFinal_ex(). It may return 0 if the "encrypt-check" option is set to 0.
+
 =back
 
 =head2 Settable EVP_CIPHER_CTX parameters
@@ -1039,6 +1045,16 @@ The IEEE Std. 1619-2007 variant of SM4-XTS algorithm.
 
 The default value is "GB".
 
+=item "encrypt-check" (B<OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK>) <integer>
+
+If required this parameter should be set early via an cipher encrypt init
+function such as EVP_EncryptInit_ex2().
+The default value of 1 causes an error when an encryption operation is triggered.
+Setting this to 0 will ignore the error and set the approved "fips-indicator" to
+0.
+This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
+set to 0.
+
 =back
 
 =head1 CONTROLS
index 25603f6fc6762d7b7f16fddcbeeeb7895f246bbe..3f177237044c24d9e5d4827edd04a0d3de44208e 100644 (file)
@@ -59,7 +59,7 @@ The following algorithms are available in the legacy provider:
 =head2 Parameters
 
 This implementation supports the parameters described in
-L<EVP_EncryptInit(3)/PARAMETERS>.
+L<EVP_EncryptInit(3)/PARAMETERS> including "encrypt-check" and "fips-indicator".
 
 =head1 SEE ALSO
 
index c72c639007280d123d43347b032020cd7d22623c..bdc667d65c2278b02291189cd058ecae758f4ba0 100644 (file)
@@ -133,6 +133,14 @@ extern "C" {
  */
 # define OSSL_PROV_FIPS_PARAM_DSA_SIGN_DISABLED "dsa-sign-disabled"
 
+/*
+ * A boolean that determines if Triple-DES encryption operations are allowed.
+ * See SP800-131A r2 for further information.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_TDES_ENCRYPT_DISABLED "tdes-encrypt-disabled"
+
 # ifdef __cplusplus
 }
 # endif
index 8468fa782585ee153650886cda0ccf1a533143db..43a92a4f3d034ddf8dc0f73f3113c5f4624dffca 100644 (file)
@@ -21,5 +21,6 @@ int FIPS_sshkdf_digest_check(OSSL_LIB_CTX *libctx);
 int FIPS_sskdf_digest_check(OSSL_LIB_CTX *libctx);
 int FIPS_x963kdf_digest_check(OSSL_LIB_CTX *libctx);
 int FIPS_dsa_sign_check(OSSL_LIB_CTX *libctx);
+int FIPS_tdes_encrypt_check(OSSL_LIB_CTX *libctx);
 
 #endif
index 31fb3338a1b13783e1f450bd4ad679932b570851..b844d293accf8800dd58e93984351288c9599fc3 100644 (file)
@@ -42,10 +42,7 @@ static OSSL_FUNC_provider_query_operation_fn fips_query;
 
 #define ALGC(NAMES, FUNC, CHECK)                \
     { { NAMES, FIPS_DEFAULT_PROPERTIES, FUNC }, CHECK }
-#define UNAPPROVED_ALGC(NAMES, FUNC, CHECK)     \
-    { { NAMES, FIPS_UNAPPROVED_PROPERTIES, FUNC }, CHECK }
 #define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
-#define UNAPPROVED_ALG(NAMES, FUNC) UNAPPROVED_ALGC(NAMES, FUNC, NULL)
 
 extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
 
@@ -99,6 +96,7 @@ typedef struct fips_global_st {
     FIPS_OPTION fips_sskdf_digest_check;
     FIPS_OPTION fips_x963kdf_digest_check;
     FIPS_OPTION fips_dsa_sign_disallowed;
+    FIPS_OPTION fips_tdes_encrypt_disallowed;
 } FIPS_GLOBAL;
 
 static void init_fips_option(FIPS_OPTION *opt, int enabled)
@@ -124,6 +122,7 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
     init_fips_option(&fgbl->fips_sskdf_digest_check, 0);
     init_fips_option(&fgbl->fips_x963kdf_digest_check, 0);
     init_fips_option(&fgbl->fips_dsa_sign_disallowed, 0);
+    init_fips_option(&fgbl->fips_tdes_encrypt_disallowed, 0);
     return fgbl;
 }
 
@@ -154,8 +153,10 @@ static const OSSL_PARAM fips_param_types[] = {
                     NULL, 0),
     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_X963KDF_DIGEST_CHECK, OSSL_PARAM_INTEGER,
                     NULL, 0),
-    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_DSA_SIGN_DISABLED,
-                    OSSL_PARAM_INTEGER, NULL, 0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_DSA_SIGN_DISABLED, OSSL_PARAM_INTEGER,
+                    NULL, 0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED, OSSL_PARAM_INTEGER,
+                    NULL, 0),
     OSSL_PARAM_END
 };
 
@@ -224,6 +225,8 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
                         fips_x963kdf_digest_check);
     FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_DSA_SIGN_DISABLED,
                         fips_dsa_sign_disallowed);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TDES_ENCRYPT_DISABLED,
+                        fips_tdes_encrypt_disallowed);
 #undef FIPS_FEATURE_OPTION
 
     *p = OSSL_PARAM_construct_end();
@@ -287,6 +290,8 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
                      fips_x963kdf_digest_check);
     FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_DSA_SIGN_DISABLED,
                      fips_dsa_sign_disallowed);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED,
+                     fips_tdes_encrypt_disallowed);
 #undef FIPS_FEATURE_GET
     return 1;
 }
@@ -425,8 +430,8 @@ static const OSSL_ALGORITHM_CAPABLE fips_ciphers[] = {
     ALGC(PROV_NAMES_AES_256_CBC_HMAC_SHA256, ossl_aes256cbc_hmac_sha256_functions,
          ossl_cipher_capable_aes_cbc_hmac_sha256),
 #ifndef OPENSSL_NO_DES
-    UNAPPROVED_ALG(PROV_NAMES_DES_EDE3_ECB, ossl_tdes_ede3_ecb_functions),
-    UNAPPROVED_ALG(PROV_NAMES_DES_EDE3_CBC, ossl_tdes_ede3_cbc_functions),
+    ALG(PROV_NAMES_DES_EDE3_ECB, ossl_tdes_ede3_ecb_functions),
+    ALG(PROV_NAMES_DES_EDE3_CBC, ossl_tdes_ede3_cbc_functions),
 #endif  /* OPENSSL_NO_DES */
     { { NULL, NULL, NULL }, NULL }
 };
@@ -829,6 +834,7 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
     FIPS_SET_OPTION(fgbl, fips_sskdf_digest_check);
     FIPS_SET_OPTION(fgbl, fips_x963kdf_digest_check);
     FIPS_SET_OPTION(fgbl, fips_dsa_sign_disallowed);
+    FIPS_SET_OPTION(fgbl, fips_tdes_encrypt_disallowed);
 #undef FIPS_SET_OPTION
 
     ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
@@ -1038,6 +1044,7 @@ FIPS_FEATURE_CHECK(FIPS_sshkdf_digest_check, fips_sshkdf_digest_check)
 FIPS_FEATURE_CHECK(FIPS_sskdf_digest_check, fips_sskdf_digest_check)
 FIPS_FEATURE_CHECK(FIPS_x963kdf_digest_check, fips_x963kdf_digest_check)
 FIPS_FEATURE_CHECK(FIPS_dsa_sign_check, fips_dsa_sign_disallowed)
+FIPS_FEATURE_CHECK(FIPS_tdes_encrypt_check, fips_tdes_encrypt_disallowed)
 
 #undef FIPS_FEATURE_CHECK
 
index 3c98ed241d39babf1c61f423f0a76abfe3c13339..765ec8b5e1364b499ab1f2b6000f8757e051743a 100644 (file)
@@ -10,6 +10,7 @@
 #include <openssl/des.h>
 #include <openssl/core_dispatch.h>
 #include "crypto/des_platform.h"
+#include "prov/fipsindicator.h"
 
 #define DES_BLOCK_SIZE 8
 #define TDES_IVLEN 8
@@ -25,6 +26,7 @@ typedef struct prov_tdes_ctx_st {
         void (*cbc) (const void *, void *, size_t,
                      const DES_key_schedule *, unsigned char *);
     } tstream;
+    OSSL_FIPS_IND_DECLARE
 
 } PROV_TDES_CTX;
 
@@ -64,9 +66,9 @@ const OSSL_DISPATCH ossl_tdes_##type##_##lcmode##_functions[] = {              \
     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
       (void (*)(void))ossl_tdes_gettable_ctx_params },                         \
     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
-     (void (*)(void))ossl_cipher_generic_set_ctx_params },                     \
+      (void (*)(void))ossl_tdes_set_ctx_params },                              \
     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
-     (void (*)(void))ossl_cipher_generic_settable_ctx_params },                \
+      (void (*)(void))ossl_tdes_settable_ctx_params },                         \
     OSSL_DISPATCH_END                                                          \
 }
 
@@ -78,6 +80,8 @@ OSSL_FUNC_cipher_encrypt_init_fn ossl_tdes_einit;
 OSSL_FUNC_cipher_decrypt_init_fn ossl_tdes_dinit;
 OSSL_FUNC_cipher_get_ctx_params_fn ossl_tdes_get_ctx_params;
 OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_tdes_gettable_ctx_params;
+OSSL_FUNC_cipher_set_ctx_params_fn ossl_tdes_set_ctx_params;
+OSSL_FUNC_cipher_settable_ctx_params_fn ossl_tdes_settable_ctx_params;
 
 #define PROV_CIPHER_HW_tdes_mode(type, mode)                                   \
 static const PROV_CIPHER_HW type##_##mode = {                                  \
index c80d9f16b1ea690c17738f0c4cde1564b801942b..1c7572c77d879b4391e31ca620e739d3c46ef24f 100644 (file)
@@ -19,6 +19,7 @@
 #include "cipher_tdes.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
+#include "prov/fipscommon.h"
 
 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)
@@ -29,9 +30,11 @@ void *ossl_tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
         return NULL;
 
     tctx = OPENSSL_zalloc(sizeof(*tctx));
-    if (tctx != NULL)
+    if (tctx != NULL) {
+        OSSL_FIPS_IND_INIT(tctx)
         ossl_cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags,
                                     hw, provctx);
+    }
     return tctx;
 }
 
@@ -46,6 +49,7 @@ void *ossl_tdes_dupctx(void *ctx)
     ret = OPENSSL_malloc(sizeof(*ret));
     if (ret == NULL)
         return NULL;
+    OSSL_FIPS_IND_COPY(ret, in)
     in->base.hw->copyctx(&ret->base, &in->base);
 
     return ret;
@@ -59,6 +63,19 @@ void ossl_tdes_freectx(void *vctx)
     OPENSSL_clear_free(ctx,  sizeof(*ctx));
 }
 
+#ifdef FIPS_MODULE
+static int tdes_encrypt_check_approved(PROV_TDES_CTX *ctx, int enc)
+{
+    /* Triple-DES encryption is not approved in FIPS 140-3 */
+    if (enc && !OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
+                                            ctx->base.libctx,
+                                            "Triple-DES", "Encryption",
+                                            FIPS_tdes_encrypt_check))
+        return 0;
+    return 1;
+}
+#endif
+
 static int tdes_init(void *vctx, const unsigned char *key, size_t keylen,
                      const unsigned char *iv, size_t ivlen,
                      const OSSL_PARAM params[], int enc)
@@ -92,7 +109,13 @@ static int tdes_init(void *vctx, const unsigned char *key, size_t keylen,
             return 0;
         ctx->key_set = 1;
     }
-    return ossl_cipher_generic_set_ctx_params(ctx, params);
+    if (!ossl_tdes_set_ctx_params(ctx, params))
+        return 0;
+#ifdef FIPS_MODULE
+    if (!tdes_encrypt_check_approved((PROV_TDES_CTX *)ctx, enc))
+        return 0;
+#endif
+    return 1;
 }
 
 int ossl_tdes_einit(void *vctx, const unsigned char *key, size_t keylen,
@@ -111,11 +134,11 @@ int ossl_tdes_dinit(void *vctx, const unsigned char *key, size_t keylen,
 
 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_tdes)
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0),
+    OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_tdes)
 
 static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
 {
-
     DES_cblock *deskey = ptr;
     size_t kl = ctx->keylen;
 
@@ -132,7 +155,7 @@ static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
 
 int ossl_tdes_get_ctx_params(void *vctx, OSSL_PARAM params[])
 {
-    PROV_CIPHER_CTX  *ctx = (PROV_CIPHER_CTX *)vctx;
+    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
     OSSL_PARAM *p;
 
     if (!ossl_cipher_generic_get_ctx_params(vctx, params))
@@ -143,5 +166,22 @@ int ossl_tdes_get_ctx_params(void *vctx, OSSL_PARAM params[])
         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY);
         return 0;
     }
+    if (!OSSL_FIPS_IND_GET_CTX_PARAM((PROV_TDES_CTX *)vctx, params))
+        return 0;
     return 1;
 }
+
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_tdes)
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL),
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),
+    OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK)
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_tdes)
+
+int ossl_tdes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM((PROV_TDES_CTX *)vctx,
+                                     OSSL_FIPS_IND_SETTABLE0, params,
+                                     OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK))
+        return 0;
+    return ossl_cipher_generic_set_ctx_params(vctx, params);
+}
index fa0b576b97123d0579e83eb131f474c31b7c6750..ec7be448eb2e150f1bc9bd2d6e7ee8b71eb3276c 100644 (file)
@@ -210,6 +210,19 @@ static int cmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE);
             return 0;
         }
+#ifdef FIPS_MODULE
+        {
+            const EVP_CIPHER *cipher = ossl_prov_cipher_cipher(&macctx->cipher);
+            int approved = EVP_CIPHER_is_a(cipher, "AES-256-CBC")
+                           || EVP_CIPHER_is_a(cipher, "AES-192-CBC")
+                           || EVP_CIPHER_is_a(cipher, "AES-128-CBC");
+
+            if (!approved) {
+                ERR_raise(ERR_LIB_PROV, EVP_R_UNSUPPORTED_CIPHER);
+                return 0;
+            }
+        }
+#endif
     }
 
     if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
index 3ca25d12f720bced680eb48b38611a74c56cf560..35a112719372b621ebd0dcf40353f84b462529c6 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include "internal/deprecated.h"
 #include <assert.h>
+#include <string.h>
 #include <openssl/evp.h>
 #include <openssl/provider.h>
 #include <openssl/dsa.h>
@@ -398,7 +399,6 @@ static int test_cipher_reinit(int test_id)
 
     /* DES3-WRAP uses random every update - so it will give a different value */
     diff = EVP_CIPHER_is_a(cipher, "DES3-WRAP");
-
     if (!TEST_true(EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv))
         || !TEST_true(EVP_EncryptUpdate(ctx, out1, &out1_len, in, sizeof(in)))
         || !TEST_true(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
@@ -519,7 +519,6 @@ err:
     return ret;
 }
 
-
 static int name_cmp(const char * const *a, const char * const *b)
 {
     return OPENSSL_strcasecmp(*a, *b);
@@ -531,6 +530,10 @@ static void collect_cipher_names(EVP_CIPHER *cipher, void *cipher_names_list)
     const char *name = EVP_CIPHER_get0_name(cipher);
     char *namedup = NULL;
 
+    /* Skip Triple-DES encryption operations in FIPS mode */
+    if (OSSL_PROVIDER_available(libctx, "fips")
+            && strncmp(name, "DES", 3) == 0)
+        return;
     assert(name != NULL);
     /* the cipher will be freed after returning, strdup is needed */
     if ((namedup = OPENSSL_strdup(name)) != NULL
@@ -614,13 +617,18 @@ static int test_cipher_tdes_randkey(void)
     EVP_CIPHER_CTX *ctx = NULL;
     EVP_CIPHER *tdes_cipher = NULL, *aes_cipher = NULL;
     unsigned char key[24] = { 0 };
+    OSSL_PARAM params[2];
+    int check = 0;
 
+    params[0] = OSSL_PARAM_construct_int("encrypt-check", &check);
+    params[1] = OSSL_PARAM_construct_end();
     ret = TEST_ptr(aes_cipher = EVP_CIPHER_fetch(libctx, "AES-256-CBC", NULL))
           && TEST_int_eq(EVP_CIPHER_get_flags(aes_cipher) & EVP_CIPH_RAND_KEY, 0)
           && TEST_ptr(tdes_cipher = EVP_CIPHER_fetch(libctx, "DES-EDE3-CBC", NULL))
           && TEST_int_ne(EVP_CIPHER_get_flags(tdes_cipher) & EVP_CIPH_RAND_KEY, 0)
           && TEST_ptr(ctx = EVP_CIPHER_CTX_new())
-          && TEST_true(EVP_CipherInit_ex(ctx, tdes_cipher, NULL, NULL, NULL, 1))
+          && TEST_true(EVP_CipherInit_ex2(ctx, tdes_cipher, NULL, NULL, 1,
+                                          params))
           && TEST_int_gt(EVP_CIPHER_CTX_rand_key(ctx, key), 0);
 
     EVP_CIPHER_CTX_free(ctx);
index 5d720d56e01b1af5741ac0eedf16b871d6628468..efe4253f9f08cad30d518082e9e2b452829bbdad 100644 (file)
@@ -206,6 +206,7 @@ static const OSSL_PARAM settable_ctx_params[] = {
     OSSL_PARAM_int("digest-check", NULL),
     OSSL_PARAM_int("ems_check", NULL),
     OSSL_PARAM_int("sign-check", NULL),
+    OSSL_PARAM_int("encrypt-check", NULL),
     OSSL_PARAM_END
 };
 
@@ -272,6 +273,18 @@ static int kdf_check_fips_approved(EVP_KDF_CTX *ctx, EVP_TEST *t)
     return check_fips_approved(t, approved);
 }
 
+static int cipher_check_fips_approved(EVP_CIPHER_CTX *ctx, EVP_TEST *t)
+{
+    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+    int approved = 1;
+
+    params[0] = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_FIPS_APPROVED_INDICATOR,
+                                         &approved);
+    if (!EVP_CIPHER_CTX_get_params(ctx, params))
+        return 0;
+    return check_fips_approved(t, approved);
+}
+
 /*
  * Compare two memory regions for equality, returning zero if they differ.
  * However, if there is expected to be an error and the actual error
@@ -855,6 +868,7 @@ typedef struct cipher_data_st {
     unsigned char *mac_key;
     size_t mac_key_len;
     const char *xts_standard;
+    STACK_OF(OPENSSL_STRING) *init_controls; /* collection of controls */
 } CIPHER_DATA;
 
 
@@ -906,6 +920,7 @@ static int cipher_test_init(EVP_TEST *t, const char *alg)
     if (!TEST_ptr(cdat = OPENSSL_zalloc(sizeof(*cdat))))
         return 0;
 
+    cdat->init_controls = sk_OPENSSL_STRING_new_null();
     cdat->cipher = cipher;
     cdat->fetched_cipher = fetched_cipher;
     cdat->enc = -1;
@@ -945,6 +960,7 @@ static void cipher_test_cleanup(EVP_TEST *t)
     OPENSSL_free(cdat->tag);
     OPENSSL_free(cdat->mac_key);
     EVP_CIPHER_free(cdat->fetched_cipher);
+    ctrlfree(cdat->init_controls);
 }
 
 static int cipher_test_parse(EVP_TEST *t, const char *keyword,
@@ -1027,11 +1043,14 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
         cdat->xts_standard = value;
         return 1;
     }
+    if (strcmp(keyword, "CtrlInit") == 0)
+        return ctrladd(cdat->init_controls, value);
     return 0;
 }
 
 static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign,
-                           size_t inp_misalign, int frag, int in_place)
+                           size_t inp_misalign, int frag, int in_place,
+                           const OSSL_PARAM initparams[])
 {
     CIPHER_DATA *expected = t->data;
     unsigned char *in, *expected_out, *tmp = NULL;
@@ -1081,7 +1100,8 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign,
         in = memcpy(tmp + out_misalign + in_len + 2 * EVP_MAX_BLOCK_LENGTH +
                     inp_misalign, in, in_len);
     }
-    if (!EVP_CipherInit_ex(ctx_base, expected->cipher, NULL, NULL, NULL, enc)) {
+    if (!EVP_CipherInit_ex2(ctx_base, expected->cipher, NULL, NULL, enc,
+                            initparams)) {
         t->err = "CIPHERINIT_ERROR";
         goto err;
     }
@@ -1355,6 +1375,11 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign,
         t->err = "CIPHERFINAL_ERROR";
         goto err;
     }
+    if (!cipher_check_fips_approved(ctx, t)) {
+        t->err = "FIPSAPPROVED_ERROR";
+        goto err;
+    }
+
     if (!enc && expected->tls_aad) {
         if (expected->tls_version >= TLS1_1_VERSION
             && (EVP_CIPHER_is_a(expected->cipher, "AES-128-CBC-HMAC-SHA1")
@@ -1414,6 +1439,8 @@ static int cipher_test_run(EVP_TEST *t)
     CIPHER_DATA *cdat = t->data;
     int rv, frag, fragmax, in_place;
     size_t out_misalign, inp_misalign;
+    OSSL_PARAM initparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+    size_t params_n = 0;
 
     TEST_info("RUNNING TEST FOR CIPHER %s\n", EVP_CIPHER_get0_name(cdat->cipher));
     if (!cdat->key) {
@@ -1432,6 +1459,12 @@ static int cipher_test_run(EVP_TEST *t)
         return 0;
     }
 
+    if (sk_OPENSSL_STRING_num(cdat->init_controls) > 0) {
+        if (!ctrl2params(t, cdat->init_controls, NULL,
+                         initparams, OSSL_NELEM(initparams), &params_n))
+            return 0;
+    }
+
     fragmax = (cipher_test_valid_fragmentation(cdat) == 0) ? 0 : 1;
     for (in_place = 1; in_place >= 0; in_place--) {
         static char aux_err[64];
@@ -1463,31 +1496,26 @@ static int cipher_test_run(EVP_TEST *t)
                     }
                     if (cdat->enc) {
                         rv = cipher_test_enc(t, 1, out_misalign, inp_misalign,
-                                             frag, in_place);
-                        /* Not fatal errors: return */
-                        if (rv != 1) {
-                            if (rv < 0)
-                                return 0;
-                            return 1;
-                        }
+                                             frag, in_place, initparams);
+                        if (rv != 1)
+                            goto end;
                     }
                     if (cdat->enc != 1) {
                         rv = cipher_test_enc(t, 0, out_misalign, inp_misalign,
-                                             frag, in_place);
-                        /* Not fatal errors: return */
-                        if (rv != 1) {
-                            if (rv < 0)
-                                return 0;
-                            return 1;
-                        }
+                                             frag, in_place, initparams);
+                        if (rv != 1)
+                            goto end;
                     }
                 }
             }
         }
     }
+    ctrl2params_free(initparams, params_n, 0);
     t->aux_err = NULL;
-
     return 1;
+ end:
+    ctrl2params_free(initparams, params_n, 0);
+    return (rv < 0 ? 0 : 1);
 }
 
 static const EVP_TEST_METHOD cipher_test_method = {
index aa238df2d90a2faaceeaab8b26d3689c9d086e8e..fa4c4f06a69113071c4769cd08cbd23da9363e68 100644 (file)
@@ -14,6 +14,7 @@
 Title = DES3 Tests
 
 # DES EDE3 CBC tests (from destest)
+FIPSversion = <3.4.0
 Cipher = DES-EDE3-CBC
 Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
 IV = fedcba9876543210
@@ -24,6 +25,7 @@ NextIV = 1c673812cfde9675
 # DES EDE3 ECB test
 # FIPS(3.0.0): has a bug in the IV length #17591
 FIPSversion = >3.0.0
+FIPSversion = <3.4.0
 Cipher = DES-EDE3-ECB
 Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
 Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
@@ -35,3 +37,45 @@ Cipher = DES-EDE-ECB
 Key = 0123456789abcdeffedcba9876543210
 Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
 Ciphertext = 4d1332e49f380e23d80a0d8b2bae5e4e6a0094171abcfc27df2bfd40da9f4e4d
+
+# DES EDE3 CBC tests (from destest)
+
+# Test that DES3 CBC mode encryption fails because it is not FIPS approved
+FIPSversion = >=3.4.0
+Cipher = DES-EDE3-CBC
+Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+Result = CIPHERINIT_ERROR
+
+# Test that DES3 EBC mode encryption fails because it is not FIPS approved
+FIPSversion = >=3.4.0
+Cipher = DES-EDE3-ECB
+Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 62c10cc9efbf15aaa5ae2e487b690e56d8b1dfb8f5c5b293855e77dd9024b1b1
+Result = CIPHERINIT_ERROR
+
+Title = DES3 FIPS Indicator Tests
+
+# Test that DES3 CBC mode encryption is not FIPS approved
+FIPSversion = >=3.4.0
+Cipher = DES-EDE3-CBC
+Unapproved = 1
+CtrlInit = encrypt-check:0
+Operation = ENCRYPT
+Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+
+# Test that DES3 ECB mode encryption is not FIPS approved
+FIPSversion = >=3.4.0
+Cipher = DES-EDE3-ECB
+Operation = ENCRYPT
+Unapproved = 1
+CtrlInit = encrypt-check:0
+Key = 0123456789abcdeff1e0d3c2b5a49786fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 62c10cc9efbf15aaa5ae2e487b690e56d8b1dfb8f5c5b293855e77dd9024b1b1
index cf42927e11d8492fa17fda0082aaa6cdf568bbfb..d23abe1f974e7c3c0d8f3cb1de2c466f983ce1e1 100644 (file)
 
 Title = CMAC tests (from FIPS module)
 
+FIPSversion = <3.4.0
 MAC = CMAC
 Algorithm = DES-EDE3-CBC
 Key = 89BCD952A8C8AB371AF48AC7D07085D5EFF702E6D62CDC23
 Input = FA620C1BBE97319E9A0CF0492121F7A20EB08A6A709DCBD00AAF38E4F99E754E
 Output = 8F49A1B7D6AA2258
 
+FIPSversion = <3.4.0
 MAC = CMAC by EVP_PKEY
 Algorithm = DES-EDE3-CBC
 Key = 89BCD952A8C8AB371AF48AC7D07085D5EFF702E6D62CDC23
 Input = FA620C1BBE97319E9A0CF0492121F7A20EB08A6A709DCBD00AAF38E4F99E754E
 Output = 8F49A1B7D6AA2258
-
index 84e0fe2d8798a392f975b27bdcaf2e10df1a525e..c103b3055a04bf229502bf0019fd1536d13e2fa9 100644 (file)
@@ -380,7 +380,7 @@ my @smime_cms_tests = (
     ],
 
     [ "encrypted content test streaming PEM format, triple DES key",
-      [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
+      [ "{cmd1}", @defaultprov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
         "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
         "-stream", "-out", "{output}.cms" ],
       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
index 6ff8fc20b7c72ed794a78f15ddcb9a22de763b40..1ca841c52d183c8df75d10b214bba58ee48d7984 100644 (file)
@@ -17,6 +17,7 @@ my $no_short_mac = 1;
 my $drgb_no_trunc_dgst = 1;
 my $kdf_digest_check = 1;
 my $dsa_sign_disabled = 1;
+my $tdes_encrypt_disabled = 1;
 
 my $activate = 1;
 my $version = 1;
@@ -50,15 +51,16 @@ activate = $activate
 install-version = $version
 conditional-errors = $conditional_errors
 security-checks = $security_checks
+module-mac = $module_mac
 tls1-prf-ems-check = $ems_check
 no-short-mac = $no_short_mac
 drbg-no-trunc-md = $drgb_no_trunc_dgst
 dsa-sign-disabled = $dsa_sign_disabled
-module-mac = $module_mac
 hkdf-digest-check = $kdf_digest_check
 tls13-kdf-digest-check = $kdf_digest_check
 tls1-prf-digest-check = $kdf_digest_check
 sshkdf-digest-check = $kdf_digest_check
 sskdf-digest-check = $kdf_digest_check
 x963kdf-digest-check = $kdf_digest_check
+tdes-encrypt-disabled = $tdes_encrypt_disabled
 _____
index 09235c08c291d79d7a4937287314463755b7a6ab..6a138e1c009d50de56b56852a298881ac318c49e 100644 (file)
@@ -41,6 +41,7 @@ my %params = (
     'PROV_PARAM_SSKDF_DIGEST_CHECK' =>     "sskdf-digest-check",     # uint
     'PROV_PARAM_X963KDF_DIGEST_CHECK' =>   "x963kdf-digest-check",   # uint
     'PROV_PARAM_DSA_SIGN_DISABLED' =>      "dsa-sign-disabled",      # uint
+    'PROV_PARAM_TDES_ENCRYPT_DISABLED' =>  "tdes-encrypt-disabled",  # uint
 
 # Self test callback parameters
     'PROV_PARAM_SELF_TEST_PHASE' =>  "st-phase",# utf8_string
@@ -109,6 +110,8 @@ my %params = (
     'CIPHER_PARAM_RC2_KEYBITS' =>          "keybits",     # size_t
     'CIPHER_PARAM_SPEED' =>                "speed",       # uint
     'CIPHER_PARAM_CTS_MODE' =>             "cts_mode",    # utf8_string
+    '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
     'CIPHER_PARAM_ALGORITHM_ID_PARAMS' =>  "alg_id_param",# octet_string
     'CIPHER_PARAM_XTS_STANDARD' =>         "xts_standard",# utf8_string