Fix DSA/DH so that legacy keys can still be generated by the default provider
authorShane Lontis <shane.lontis@oracle.com>
Tue, 11 Aug 2020 00:15:28 +0000 (10:15 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Mon, 17 Aug 2020 13:40:20 +0000 (23:40 +1000)
Fixes #12589

The 'type' parameter needed to be propagated to the ffc params during keygen,
so that the simple validation of params done during keygen can handle legacy keys for the default provider.
The fips provider ignores this change and only allows fips186-4 approved sizes.

Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/12623)

crypto/ffc/ffc_params.c
crypto/ffc/ffc_params_validate.c
include/internal/ffc.h
providers/implementations/keymgmt/dh_kmgmt.c
providers/implementations/keymgmt/dsa_kmgmt.c
test/recipes/15-test_gendsa.t

index d70aeea35bd6d4c403eface19312dbb3c1b4be69..ac767c0a1cb0fcc0c6ed42ae64262cf09de32093 100644 (file)
@@ -117,6 +117,14 @@ void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags)
     params->flags = flags;
 }
 
+void ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, int enable)
+{
+    if (enable)
+        params->flags |= flags;
+    else
+        params->flags &= ~flags;
+}
+
 int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props)
 {
     params->mdname = alg;
index 821ff3e88a3a1aea983a7b9c9ef33e0900cca502..9221b13d17fdaba4ba34cdf30306c1ef429d3b92 100644 (file)
@@ -66,7 +66,7 @@ int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
 {
     size_t L, N;
 
-    if (params->p == NULL || params->q == NULL) {
+    if (params == NULL || params->p == NULL || params->q == NULL) {
         *res = FFC_CHECK_INVALID_PQ;
         return FFC_PARAM_RET_STATUS_FAILED;
     }
@@ -99,7 +99,12 @@ int ffc_params_simple_validate(OPENSSL_CTX *libctx, FFC_PARAMS *params, int type
     params->flags = FFC_PARAM_FLAG_VALIDATE_G;
     params->gindex = FFC_UNVERIFIABLE_GINDEX;
 
-    ret = ffc_params_FIPS186_4_validate(libctx, params, type, &res, NULL);
+#ifndef FIPS_MODULE
+    if (save_flags & FFC_PARAM_FLAG_VALIDATE_LEGACY)
+        ret = ffc_params_FIPS186_2_validate(libctx, params, type, &res, NULL);
+    else
+#endif
+        ret = ffc_params_FIPS186_4_validate(libctx, params, type, &res, NULL);
     params->flags = save_flags;
     params->gindex = save_gindex;
     return ret != FFC_PARAM_RET_STATUS_FAILED;
index b352b8d3459e65cb75e6987febe215c09ece5007..3a4dcc9dcb82e49d9a57a8256460314e9fa9dd14 100644 (file)
 #define FFC_PARAM_RET_STATUS_UNVERIFIABLE_G 2
 
 /* Validation flags */
-# define FFC_PARAM_FLAG_VALIDATE_PQ  0x01
-# define FFC_PARAM_FLAG_VALIDATE_G   0x02
+# define FFC_PARAM_FLAG_VALIDATE_PQ    0x01
+# define FFC_PARAM_FLAG_VALIDATE_G     0x02
 # define FFC_PARAM_FLAG_VALIDATE_ALL                                           \
     (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G)
+#define FFC_PARAM_FLAG_VALIDATE_LEGACY 0x04
 
 /*
  * NB: These values must align with the equivalently named macros in
@@ -124,6 +125,7 @@ void ffc_params_set_gindex(FFC_PARAMS *params, int index);
 void ffc_params_set_pcounter(FFC_PARAMS *params, int index);
 void ffc_params_set_h(FFC_PARAMS *params, int index);
 void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags);
+void ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, int enable);
 int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props);
 
 int ffc_params_set_validate_params(FFC_PARAMS *params,
index 0ea6ce778425b7454312bc14501d2f4090441180..002cdec1f9b655f007b6368f95d8a84cd23083e5 100644 (file)
@@ -653,6 +653,8 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
             goto end;
         if (gctx->priv_len > 0)
             DH_set_length(dh, (long)gctx->priv_len);
+        ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY,
+                                gctx->gen_type == DH_PARAMGEN_TYPE_FIPS_186_2);
         if (DH_generate_key(dh) <= 0)
             goto end;
     }
index d9c6007650579582b229196bc487c7d0856f6516..855fa18c38256b0dc3b7e8de0737ba6f53e5e288 100644 (file)
@@ -529,6 +529,8 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
                                          gencb) <= 0)
              goto end;
     }
+    ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY,
+                            gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_186_2);
     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
         if (ffc->p == NULL
             || ffc->q == NULL
index 4344cde95c1a9796cbe9045c8ebee92c3758c52d..4dc387cac566b6e04d52b936572fb9e0b5f72203 100644 (file)
@@ -19,7 +19,7 @@ setup("test_gendsa");
 plan skip_all => "This test is unsupported in a no-dsa build"
     if disabled("dsa");
 
-plan tests => 8;
+plan tests => 10;
 
 ok(run(app([ 'openssl', 'genpkey', '-genparam',
              '-algorithm', 'DSA',
@@ -40,6 +40,13 @@ ok(run(app([ 'openssl', 'genpkey', '-genparam',
              '-text'])),
    "genpkey DSA params fips186_2");
 
+ok(run(app([ 'openssl', 'genpkey', '-genparam',
+             '-algorithm', 'DSA',
+             '-pkeyopt', 'type:fips186_2',
+             '-pkeyopt', 'dsa_paramgen_bits:1024',
+             '-out', 'dsagen.legacy.pem'])),
+   "genpkey DSA params fips186_2 PEM");
+
 ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'DSA',
              '-pkeyopt', 'type:group',
              '-text'])),
@@ -62,6 +69,12 @@ ok(run(app([ 'openssl', 'genpkey', '-genparam',
              '-out', 'dsagen.der'])),
    "genpkey DSA params fips186_4 DER");
 
+ok(run(app([ 'openssl', 'genpkey',
+             '-paramfile', 'dsagen.legacy.pem',
+             '-pkeyopt', 'type:fips186_2',
+             '-text'])),
+   "genpkey DSA fips186_2 with PEM params");
+
 # The seed and counter should be the ones generated from the param generation
 # Just put some dummy ones in to show it works.
 ok(run(app([ 'openssl', 'genpkey',