OPT_NO_CONDITIONAL_ERRORS,
OPT_NO_SECURITY_CHECKS,
OPT_TLS_PRF_EMS_CHECK, OPT_NO_SHORT_MAC,
+ OPT_DISALLOW_SIGNATURE_X931_PADDING,
OPT_DISALLOW_DRGB_TRUNC_DIGEST,
OPT_HKDF_DIGEST_CHECK,
OPT_TLS13_KDF_DIGEST_CHECK,
"Disallow DSA signing"},
{"tdes_encrypt_disabled", OPT_DISALLOW_TDES_ENCRYPT, '-',
"Disallow Triple-DES encryption"},
+ {"rsa_sign_x931_disabled", OPT_DISALLOW_SIGNATURE_X931_PADDING, '-',
+ "Disallow X931 Padding for RSA signing"},
OPT_SECTION("Input"),
{"in", OPT_IN, '<', "Input config file, used when verifying"},
unsigned int x963kdf_digest_check : 1;
unsigned int dsa_sign_disabled : 1;
unsigned int tdes_encrypt_disabled : 1;
+ unsigned int sign_x931_padding_disabled : 1;
} FIPS_OPTS;
/* Pedantic FIPS compliance */
1, /* x963kdf_digest_check */
1, /* dsa_sign_disabled */
1, /* tdes_encrypt_disabled */
+ 1, /* sign_x931_padding_disabled */
};
/* Default FIPS settings for backward compatibility */
0, /* x963kdf_digest_check */
0, /* dsa_sign_disabled */
0, /* tdes_encrypt_disabled */
+ 0, /* sign_x931_padding_disabled */
};
static int check_non_pedantic_fips(int pedantic, const char *name)
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
+ || BIO_printf(out, "%s = %s\n",
+ OSSL_PROV_FIPS_PARAM_RSA_SIGN_X931_PAD_DISABLED,
+ opts->sign_x931_padding_disabled ? "1" : "0") <= 0
|| !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
module_mac_len))
goto end;
case OPT_DISALLOW_TDES_ENCRYPT:
fips_opts.tdes_encrypt_disabled = 1;
break;
+ case OPT_DISALLOW_SIGNATURE_X931_PADDING:
+ fips_opts.sign_x931_padding_disabled = 1;
+ break;
case OPT_QUIET:
quiet = 1;
/* FALLTHROUGH */
rsa->_method_mod_n))
goto err;
+ /* For X9.31: Assuming e is odd it does a 12 mod 16 test */
if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret)[0] & 0xf) != 12))
if (!BN_sub(ret, rsa->n, ret))
goto err;
#include <openssl/rsa.h>
#include <openssl/objects.h>
+/*
+ * X9.31 Embeds the hash inside the following data structure
+ *
+ * header (4 bits = 0x6)
+ * padding (consisting of zero or more 4 bit values of a sequence of 0xB,
+ * ending with the terminator 0xA)
+ * hash(Msg) hash of a message (the output size is related to the hash function)
+ * trailer (consists of 2 bytes)
+ * The 1st byte is related to a part number for a hash algorithm
+ * (See RSA_X931_hash_id()), followed by the fixed value 0xCC
+ *
+ * The RSA modulus size n (which for X9.31 is 1024 + 256*s) is the size of the data
+ * structure, which determines the padding size.
+ * i.e. len(padding) = n - len(header) - len(hash) - len(trailer)
+ *
+ * Params:
+ * to The output buffer to write the data structure to.
+ * tolen The size of 'to' in bytes (it is the size of the n)
+ * from The input hash followed by the 1st byte of the trailer.
+ * flen The size of the input hash + 1 (trailer byte)
+ */
int RSA_padding_add_X931(unsigned char *to, int tlen,
const unsigned char *from, int flen)
{
unsigned char *p;
/*
- * Absolute minimum amount of padding is 1 header nibble, 1 padding
- * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+ * We need at least 1 byte for header + padding (0x6A)
+ * And 2 trailer bytes (but we subtract 1 since flen includes 1 trailer byte)
*/
-
j = tlen - flen - 2;
if (j < 0) {
return j;
}
-/* Translate between X931 hash ids and NIDs */
+/*
+ * Translate between X9.31 hash ids and NIDs
+ * The returned values relate to ISO/IEC 10118 part numbers which consist of
+ * a hash algorithm and hash number. The returned values are used as the
+ * first byte of the 'trailer'.
+ */
int RSA_X931_hash_id(int nid)
{
[B<-dsa_sign_disabled>]
[B<-no_short_mac>]
[B<-tdes_encrypt_disabled>]
+[B<-rsa_sign_x931_disabled>]
[B<-self_test_onload>]
[B<-self_test_oninstall>]
[B<-corrupt_desc> I<selftest_description>]
Triple-DES decryption is still allowed for legacy purposes.
See SP800-131Ar2 for details.
+=item B<-rsa_sign_x931_disabled>
+
+Configure the module to not allow X9.31 padding be used when signing with RSA.
+See FIPS 140-3 IG C.K for details.
+
=item B<-self_test_onload>
Do not write the two fields related to the "test status indicator" and
=item "digest-check" (B<OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK>) <integer>
+=item "sign-x931-pad-check" (B<SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK>) <int>
+
These common parameters are described in L<provider-signature(7)>.
=item "pad-mode" (B<OSSL_SIGNATURE_PARAM_PAD_MODE>) <UTF8 string>
=item "x931" (B<OSSL_PKEY_RSA_PAD_MODE_X931>)
+This padding mode is no longer supported by the FIPS provider for signature
+generation, but may be used for signature verification for legacy use cases.
+(This is a FIPS 140-3 requirement)
+
=item "pss" (B<OSSL_PKEY_RSA_PAD_MODE_PSS>)
=back
=item RSA, see L<EVP_SIGNATURE-RSA(7)>
+The B<X931> padding mode "OSSL_PKEY_RSA_PAD_MODE_X931" is no longer supported
+for signature generation, but may be used for verification for legacy use cases.
+(This is a FIPS 140-3 requirement)
+
=item DSA, see L<EVP_SIGNATURE-DSA(7)>
=item ED25519, see L<EVP_SIGNATURE-ED25519(7)>
The default value of 1 causes an error when a signing algorithm is used. (This
is triggered by deprecated signing algorithms).
Setting this to 0 will ignore the error and set the approved "fips-indicator" to 0.
+
+=item "sign-x931-pad-check" (B<SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK>) <int>
+
+If required this parameter should be set before the padding mode is set
+The default value of 1 causes an error if the padding mode is set to X9.31 padding
+for a RSA signing operation. 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.
*/
# define OSSL_PROV_FIPS_PARAM_TDES_ENCRYPT_DISABLED "tdes-encrypt-disabled"
+/*
+ * A boolean that determines if X9.31 padding can be used for RSA signing.
+ * X9.31 RSA has been removed from FIPS 186-5, and is no longer approved for
+ * signing. it may still be used for verification for legacy purposes.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_RSA_SIGN_X931_PAD_DISABLED "rsa-sign-x931-pad-disabled"
+
# ifdef __cplusplus
}
# endif
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);
+int FIPS_rsa_sign_x931_disallowed(OSSL_LIB_CTX *libctx);
#endif
FIPS_OPTION fips_x963kdf_digest_check;
FIPS_OPTION fips_dsa_sign_disallowed;
FIPS_OPTION fips_tdes_encrypt_disallowed;
+ FIPS_OPTION fips_rsa_sign_x931_disallowed;
} FIPS_GLOBAL;
static void init_fips_option(FIPS_OPTION *opt, int enabled)
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);
+ init_fips_option(&fgbl->fips_rsa_sign_x931_disallowed, 0);
return fgbl;
}
NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED, OSSL_PARAM_INTEGER,
NULL, 0),
+ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED,
+ OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_END
};
fips_dsa_sign_disallowed);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TDES_ENCRYPT_DISABLED,
fips_tdes_encrypt_disallowed);
+ FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_RSA_SIGN_X931_PAD_DISABLED,
+ fips_rsa_sign_x931_disallowed);
#undef FIPS_FEATURE_OPTION
*p = OSSL_PARAM_construct_end();
fips_dsa_sign_disallowed);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED,
fips_tdes_encrypt_disallowed);
+ FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED,
+ fips_rsa_sign_x931_disallowed);
#undef FIPS_FEATURE_GET
return 1;
}
FIPS_SET_OPTION(fgbl, fips_x963kdf_digest_check);
FIPS_SET_OPTION(fgbl, fips_dsa_sign_disallowed);
FIPS_SET_OPTION(fgbl, fips_tdes_encrypt_disallowed);
+ FIPS_SET_OPTION(fgbl, fips_rsa_sign_x931_disallowed);
#undef FIPS_SET_OPTION
ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
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)
+FIPS_FEATURE_CHECK(FIPS_rsa_sign_x931_disallowed,
+ fips_rsa_sign_x931_disallowed)
#undef FIPS_FEATURE_CHECK
sig, prsactx->rsa, RSA_X931_PADDING);
clean_tbuf(prsactx);
break;
-
case RSA_PKCS1_PADDING:
{
unsigned int sltmp;
return known_gettable_ctx_params;
}
+#ifdef FIPS_MODULE
+static int rsa_x931_padding_allowed(PROV_RSA_CTX *ctx)
+{
+ int approved = ((ctx->operation & EVP_PKEY_OP_SIGN) == 0);
+
+ if (!approved) {
+ if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2,
+ ctx->libctx,
+ "RSA Sign set ctx", "X931 Padding",
+ FIPS_rsa_sign_x931_disallowed)) {
+ ERR_raise(ERR_LIB_PROV,
+ PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif
+
static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
{
PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK))
return 0;
+ if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE2, params,
+ OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK))
+ return 0;
+
pad_mode = prsactx->pad_mode;
saltlen = prsactx->saltlen;
err_extra_text = "No padding not allowed with RSA-PSS";
goto cont;
case RSA_X931_PADDING:
+#ifdef FIPS_MODULE
+ /* X9.31 only allows sizes of 1024 + 256 * s (bits) */
+ if ((RSA_bits(prsactx->rsa) & 0xFF) != 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ /* RSA Signing with X9.31 padding is not allowed in FIPS 140-3 */
+ if (!rsa_x931_padding_allowed(prsactx))
+ return 0;
+#endif
err_extra_text = "X.931 padding not allowed with RSA-PSS";
cont:
if (RSA_test_flags(prsactx->rsa,
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK)
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK)
+ OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK)
OSSL_PARAM_END
};
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK)
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK)
+ OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK)
OSSL_PARAM_END
};
OSSL_PARAM_int("ems_check", NULL),
OSSL_PARAM_int("sign-check", NULL),
OSSL_PARAM_int("encrypt-check", NULL),
+ OSSL_PARAM_int("sign-x931-pad-check", NULL),
OSSL_PARAM_END
};
Input = "Hello"
Result = DIGESTVERIFYINIT_ERROR
+# RSA Signing with X931 is not approved in FIPS 140-3
+FIPSversion = >=3.4.0
+Sign = RSA-2048
+Ctrl = rsa_padding_mode:x931
+Input = "0123456789ABCDEF123456789ABC"
+Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+Result = PKEY_CTRL_ERROR
+
##################################################
# Check that the indicator callback is triggered
Key = RSA-512
Input = "Hello"
Result = VERIFY_ERROR
+
+# RSA Signing with X931 is not approved in FIPS 140-3
+FIPSversion = >=3.4.0
+Sign = RSA-2048
+Unapproved = 1
+CtrlInit = sign-x931-pad-check:0
+Ctrl = digest:SHA256
+Ctrl = rsa_padding_mode:x931
+Input = "0123456789ABCDEF123456789ABCDEFG"
+Output = 4b75f521e2e6eeda3f2dcb84ebdacbadeab8ffc1ecdf06c7c4e38727e082a8f5e71be66cdee6d14da1d3a0f18ff20914f71b5308363c81e7471688f4f201e82603ea6a7f31da89cd846b30e2893fd956e76b3d23d40f733e0358e3883526158c74577ba43cc664eaeb909818e75b89fc764cf4575517f87251f8d3cf29b1532f33e6183d454bddd6f255d0ca4415d957eb90dbc55d047f48a01c6e68d5ab46327a158ff7a3383b5b0446b8cd4a91b8859abd3285020a1613ef17d3f8562147828bb36be65505eeec77e968d04e172e2851ff1d7ef523b4022deb72d5fbf78db6738d170098586b904d1c369cedb5e3fe1b909a8dd8ac3beb521af2510d044580
my $kdf_digest_check = 1;
my $dsa_sign_disabled = 1;
my $tdes_encrypt_disabled = 1;
+my $rsa_sign_x931_pad_disabled = 1;
my $activate = 1;
my $version = 1;
sskdf-digest-check = $kdf_digest_check
x963kdf-digest-check = $kdf_digest_check
tdes-encrypt-disabled = $tdes_encrypt_disabled
+rsa-sign-x931-pad-disabled = $rsa_sign_x931_pad_disabled
_____
'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
+ 'PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED' => "rsa-sign-x931-pad-disabled", # uint
# Self test callback parameters
'PROV_PARAM_SELF_TEST_PHASE' => "st-phase",# utf8_string
'SIGNATURE_PARAM_FIPS_DIGEST_CHECK' => '*PKEY_PARAM_FIPS_DIGEST_CHECK',
'SIGNATURE_PARAM_FIPS_KEY_CHECK' => '*PKEY_PARAM_FIPS_KEY_CHECK',
'SIGNATURE_PARAM_FIPS_SIGN_CHECK' => "sign-check",
+ 'SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK' => "sign-x931-pad-check",
'SIGNATURE_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
# Asym cipher parameters