openssl/0044-FIPS-140-3-keychecks.patch
Dmitry Belyavskiy fa195e46a2 Pairwise consistency tests should use Digest+Sign/Verify
Resolves: rhbz#2178034
2023-03-14 17:27:15 +01:00

451 lines
16 KiB
Diff

diff -up openssl-3.0.1/crypto/dh/dh_key.c.fips3 openssl-3.0.1/crypto/dh/dh_key.c
--- openssl-3.0.1/crypto/dh/dh_key.c.fips3 2022-07-18 16:01:41.159543735 +0200
+++ openssl-3.0.1/crypto/dh/dh_key.c 2022-07-18 16:24:30.251388248 +0200
@@ -43,6 +43,9 @@ int ossl_dh_compute_key(unsigned char *k
BN_MONT_CTX *mont = NULL;
BIGNUM *z = NULL, *pminus1;
int ret = -1;
+#ifdef FIPS_MODULE
+ int validate = 0;
+#endif
if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) {
ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
@@ -54,6 +57,13 @@ int ossl_dh_compute_key(unsigned char *k
return 0;
}
+#ifdef FIPS_MODULE
+ if (DH_check_pub_key(dh, pub_key, &validate) <= 0) {
+ ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID);
+ return 0;
+ }
+#endif
+
ctx = BN_CTX_new_ex(dh->libctx);
if (ctx == NULL)
goto err;
@@ -262,6 +272,9 @@ static int generate_key(DH *dh)
#endif
BN_CTX *ctx = NULL;
BIGNUM *pub_key = NULL, *priv_key = NULL;
+#ifdef FIPS_MODULE
+ int validate = 0;
+#endif
if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) {
ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
@@ -354,8 +367,23 @@ static int generate_key(DH *dh)
if (!ossl_dh_generate_public_key(ctx, dh, priv_key, pub_key))
goto err;
+#ifdef FIPS_MODULE
+ if (DH_check_pub_key(dh, pub_key, &validate) <= 0) {
+ ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID);
+ goto err;
+ }
+#endif
+
dh->pub_key = pub_key;
dh->priv_key = priv_key;
+#ifdef FIPS_MODULE
+ if (ossl_dh_check_pairwise(dh) <= 0) {
+ dh->pub_key = dh->priv_key = NULL;
+ ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID);
+ goto err;
+ }
+#endif
+
dh->dirty_cnt++;
ok = 1;
err:
diff -up openssl-3.0.1/crypto/ec/ec_key.c.fips3 openssl-3.0.1/crypto/ec/ec_key.c
diff -up openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c.fips3 openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c
--- openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c.fips3 2022-07-25 13:42:46.814952053 +0200
+++ openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c 2022-07-25 13:52:12.292065706 +0200
@@ -488,6 +488,25 @@ int ecdh_plain_derive(void *vpecdhctx, u
}
ppubkey = EC_KEY_get0_public_key(pecdhctx->peerk);
+#ifdef FIPS_MODULE
+ {
+ BN_CTX *bn_ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(privk));
+ int check = 0;
+
+ if (bn_ctx == NULL) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+
+ check = ossl_ec_key_public_check(pecdhctx->peerk, bn_ctx);
+ BN_CTX_free(bn_ctx);
+
+ if (check <= 0) {
+ ERR_raise(ERR_LIB_PROV, EC_R_INVALID_PEER_KEY);
+ goto end;
+ }
+ }
+#endif
retlen = ECDH_compute_key(secret, size, ppubkey, privk, NULL);
diff -up openssl-3.0.1/crypto/ec/ec_key.c.fips3 openssl-3.0.1/crypto/ec/ec_key.c
--- openssl-3.0.1/crypto/ec/ec_key.c.fips3 2022-07-25 14:03:34.420222507 +0200
+++ openssl-3.0.1/crypto/ec/ec_key.c 2022-07-25 14:09:00.728164294 +0200
@@ -336,6 +336,11 @@ static int ec_generate_key(EC_KEY *eckey
OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg);
ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg);
+
+#ifdef FIPS_MODULE
+ ok &= ossl_ec_key_public_check(eckey, ctx);
+ ok &= ossl_ec_key_pairwise_check(eckey, ctx);
+#endif /* FIPS_MODULE */
}
err:
/* Step (9): If there is an error return an invalid keypair. */
diff -up openssl-3.0.1/crypto/rsa/rsa_gen.c.fips3 openssl-3.0.1/crypto/rsa/rsa_gen.c
--- openssl-3.0.1/crypto/rsa/rsa_gen.c.fips3 2022-07-25 17:02:17.807271297 +0200
+++ openssl-3.0.1/crypto/rsa/rsa_gen.c 2022-07-25 17:18:24.931959649 +0200
@@ -23,6 +23,7 @@
#include <time.h>
#include "internal/cryptlib.h"
#include <openssl/bn.h>
+#include <openssl/obj_mac.h>
#include <openssl/self_test.h>
#include "prov/providercommon.h"
#include "rsa_local.h"
@@ -476,52 +476,43 @@ static int rsa_keygen(OSSL_LIB_CTX *libc
static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg)
{
int ret = 0;
- unsigned int ciphertxt_len;
- unsigned char *ciphertxt = NULL;
- const unsigned char plaintxt[16] = {0};
- unsigned char *decoded = NULL;
- unsigned int decoded_len;
- unsigned int plaintxt_len = (unsigned int)sizeof(plaintxt_len);
- int padding = RSA_PKCS1_PADDING;
+ unsigned int signature_len;
+ unsigned char *signature = NULL;
OSSL_SELF_TEST *st = NULL;
+ static const unsigned char dgst[] = {
+ 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
+ 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28,
+ 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69
+ };
st = OSSL_SELF_TEST_new(cb, cbarg);
if (st == NULL)
goto err;
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
+ /* No special name for RSA signature PCT*/
OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1);
- ciphertxt_len = RSA_size(rsa);
+ signature_len = RSA_size(rsa);
- /*
- * RSA_private_encrypt() and RSA_private_decrypt() requires the 'to'
- * parameter to be a maximum of RSA_size() - allocate space for both.
- */
- ciphertxt = OPENSSL_zalloc(ciphertxt_len * 2);
- if (ciphertxt == NULL)
+ signature = OPENSSL_zalloc(signature_len);
+ if (signature == NULL)
goto err;
- decoded = ciphertxt + ciphertxt_len;
- ciphertxt_len = RSA_public_encrypt(plaintxt_len, plaintxt, ciphertxt, rsa,
- padding);
- if (ciphertxt_len <= 0)
+ if (RSA_sign(NID_sha256, dgst, sizeof(dgst), signature, &signature_len, rsa) <= 0)
goto err;
- if (ciphertxt_len == plaintxt_len
- && memcmp(ciphertxt, plaintxt, plaintxt_len) == 0)
+
+ if (signature_len <= 0)
goto err;
- OSSL_SELF_TEST_oncorrupt_byte(st, ciphertxt);
+ OSSL_SELF_TEST_oncorrupt_byte(st, signature);
- decoded_len = RSA_private_decrypt(ciphertxt_len, ciphertxt, decoded, rsa,
- padding);
- if (decoded_len != plaintxt_len
- || memcmp(decoded, plaintxt, decoded_len) != 0)
+ if (RSA_verify(NID_sha256, dgst, sizeof(dgst), signature, signature_len, rsa) <= 0)
goto err;
ret = 1;
err:
OSSL_SELF_TEST_onend(st, ret);
OSSL_SELF_TEST_free(st);
- OPENSSL_free(ciphertxt);
+ OPENSSL_free(signature);
return ret;
}
diff -up openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c.pairwise openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c
--- openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c.pairwise 2023-02-20 11:44:18.451884117 +0100
+++ openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c 2023-02-20 12:39:46.037063842 +0100
@@ -982,8 +982,17 @@ struct ec_gen_ctx {
int selection;
int ecdh_mode;
EC_GROUP *gen_group;
+#ifdef FIPS_MODULE
+ void *ecdsa_sig_ctx;
+#endif
};
+#ifdef FIPS_MODULE
+void *ecdsa_newctx(void *provctx, const char *propq);
+void ecdsa_freectx(void *vctx);
+int do_ec_pct(void *, const char *, void *);
+#endif
+
static void *ec_gen_init(void *provctx, int selection,
const OSSL_PARAM params[])
{
@@ -1002,6 +1011,10 @@ static void *ec_gen_init(void *provctx,
OPENSSL_free(gctx);
gctx = NULL;
}
+#ifdef FIPS_MODULE
+ if (gctx != NULL)
+ gctx->ecdsa_sig_ctx = ecdsa_newctx(provctx, NULL);
+#endif
return gctx;
}
@@ -1272,6 +1285,12 @@ static void *ec_gen(void *genctx, OSSL_C
if (gctx->ecdh_mode != -1)
ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode);
+#ifdef FIPS_MODULE
+ /* Pairwise consistency test */
+ if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
+ && do_ec_pct(gctx->ecdsa_sig_ctx, "sha256", ec) != 1)
+ goto err;
+#endif
if (gctx->group_check != NULL)
ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check);
@@ -1341,7 +1359,10 @@ static void ec_gen_cleanup(void *genctx)
if (gctx == NULL)
return;
-
+#ifdef FIPS_MODULE
+ ecdsa_freectx(gctx->ecdsa_sig_ctx);
+ gctx->ecdsa_sig_ctx = NULL;
+#endif
EC_GROUP_free(gctx->gen_group);
BN_free(gctx->p);
BN_free(gctx->a);
diff -up openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c.pairwise openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c
--- openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c.pairwise 2023-02-20 11:50:23.035194347 +0100
+++ openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c 2023-02-20 12:19:10.809768979 +0100
@@ -32,7 +32,7 @@
#include "crypto/ec.h"
#include "prov/der_ec.h"
-static OSSL_FUNC_signature_newctx_fn ecdsa_newctx;
+OSSL_FUNC_signature_newctx_fn ecdsa_newctx;
static OSSL_FUNC_signature_sign_init_fn ecdsa_sign_init;
static OSSL_FUNC_signature_verify_init_fn ecdsa_verify_init;
static OSSL_FUNC_signature_sign_fn ecdsa_sign;
@@ -43,7 +43,7 @@ static OSSL_FUNC_signature_digest_sign_f
static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_verify_init;
static OSSL_FUNC_signature_digest_verify_update_fn ecdsa_digest_signverify_update;
static OSSL_FUNC_signature_digest_verify_final_fn ecdsa_digest_verify_final;
-static OSSL_FUNC_signature_freectx_fn ecdsa_freectx;
+OSSL_FUNC_signature_freectx_fn ecdsa_freectx;
static OSSL_FUNC_signature_dupctx_fn ecdsa_dupctx;
static OSSL_FUNC_signature_get_ctx_params_fn ecdsa_get_ctx_params;
static OSSL_FUNC_signature_gettable_ctx_params_fn ecdsa_gettable_ctx_params;
@@ -104,7 +104,7 @@ typedef struct {
#endif
} PROV_ECDSA_CTX;
-static void *ecdsa_newctx(void *provctx, const char *propq)
+void *ecdsa_newctx(void *provctx, const char *propq)
{
PROV_ECDSA_CTX *ctx;
@@ -370,7 +370,7 @@ int ecdsa_digest_verify_final(void *vctx
return ecdsa_verify(ctx, sig, siglen, digest, (size_t)dlen);
}
-static void ecdsa_freectx(void *vctx)
+void ecdsa_freectx(void *vctx)
{
PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx;
@@ -581,6 +581,35 @@ static const OSSL_PARAM *ecdsa_settable_
return EVP_MD_settable_ctx_params(ctx->md);
}
+#ifdef FIPS_MODULE
+int do_ec_pct(void *vctx, const char *mdname, void *ec)
+{
+ static const char data[32];
+ unsigned char sigbuf[256];
+ size_t siglen = sizeof(sigbuf);
+
+ if (ecdsa_digest_sign_init(vctx, mdname, ec, NULL) <= 0)
+ return 0;
+
+ if (ecdsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0)
+ return 0;
+
+ if (ecdsa_digest_sign_final(vctx, sigbuf, &siglen, sizeof(sigbuf)) <= 0)
+ return 0;
+
+ if (ecdsa_digest_verify_init(vctx, mdname, ec, NULL) <= 0)
+ return 0;
+
+ if (ecdsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0)
+ return 0;
+
+ if (ecdsa_digest_verify_final(vctx, sigbuf, siglen) <= 0)
+ return 0;
+
+ return 1;
+}
+#endif
+
const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = {
{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx },
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init },
diff -up openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c.pairwise openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c
--- openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c.pairwise 2023-02-20 16:04:27.103364713 +0100
+++ openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c 2023-02-20 16:14:13.848119419 +0100
@@ -434,6 +434,7 @@ struct rsa_gen_ctx {
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
/* ACVP test parameters */
OSSL_PARAM *acvp_test_params;
+ void *prov_rsa_ctx;
#endif
};
@@ -447,6 +448,12 @@ static int rsa_gencb(int p, int n, BN_GE
return gctx->cb(params, gctx->cbarg);
}
+#ifdef FIPS_MODULE
+void *rsa_newctx(void *provctx, const char *propq);
+void rsa_freectx(void *vctx);
+int do_rsa_pct(void *, const char *, void *);
+#endif
+
static void *gen_init(void *provctx, int selection, int rsa_type,
const OSSL_PARAM params[])
{
@@ -474,6 +481,10 @@ static void *gen_init(void *provctx, int
if (!rsa_gen_set_params(gctx, params))
goto err;
+#ifdef FIPS_MODULE
+ if (gctx != NULL)
+ gctx->prov_rsa_ctx = rsa_newctx(provctx, NULL);
+#endif
return gctx;
err:
@@ -630,6 +641,11 @@ static void *rsa_gen(void *genctx, OSSL_
rsa = rsa_tmp;
rsa_tmp = NULL;
+#ifdef FIPS_MODULE
+ /* Pairwise consistency test */
+ if (do_rsa_pct(gctx->prov_rsa_ctx, "sha256", rsa) != 1)
+ goto err;
+#endif
err:
BN_GENCB_free(gencb);
RSA_free(rsa_tmp);
@@ -645,6 +662,8 @@ static void rsa_gen_cleanup(void *genctx
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
ossl_rsa_acvp_test_gen_params_free(gctx->acvp_test_params);
gctx->acvp_test_params = NULL;
+ rsa_freectx(gctx->prov_rsa_ctx);
+ gctx->prov_rsa_ctx = NULL;
#endif
BN_clear_free(gctx->pub_exp);
OPENSSL_free(gctx);
diff -up openssl-3.0.7/providers/implementations/signature/rsa_sig.c.pairwise openssl-3.0.7/providers/implementations/signature/rsa_sig.c
--- openssl-3.0.7/providers/implementations/signature/rsa_sig.c.pairwise 2023-02-20 16:04:22.548327811 +0100
+++ openssl-3.0.7/providers/implementations/signature/rsa_sig.c 2023-02-20 16:17:50.064871695 +0100
@@ -36,7 +36,7 @@
#define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1
-static OSSL_FUNC_signature_newctx_fn rsa_newctx;
+OSSL_FUNC_signature_newctx_fn rsa_newctx;
static OSSL_FUNC_signature_sign_init_fn rsa_sign_init;
static OSSL_FUNC_signature_verify_init_fn rsa_verify_init;
static OSSL_FUNC_signature_verify_recover_init_fn rsa_verify_recover_init;
@@ -49,7 +49,7 @@ static OSSL_FUNC_signature_digest_sign_f
static OSSL_FUNC_signature_digest_verify_init_fn rsa_digest_verify_init;
static OSSL_FUNC_signature_digest_verify_update_fn rsa_digest_signverify_update;
static OSSL_FUNC_signature_digest_verify_final_fn rsa_digest_verify_final;
-static OSSL_FUNC_signature_freectx_fn rsa_freectx;
+OSSL_FUNC_signature_freectx_fn rsa_freectx;
static OSSL_FUNC_signature_dupctx_fn rsa_dupctx;
static OSSL_FUNC_signature_get_ctx_params_fn rsa_get_ctx_params;
static OSSL_FUNC_signature_gettable_ctx_params_fn rsa_gettable_ctx_params;
@@ -172,7 +172,7 @@ static int rsa_check_parameters(PROV_RSA
return 1;
}
-static void *rsa_newctx(void *provctx, const char *propq)
+void *rsa_newctx(void *provctx, const char *propq)
{
PROV_RSA_CTX *prsactx = NULL;
char *propq_copy = NULL;
@@ -990,7 +990,7 @@ int rsa_digest_verify_final(void *vprsac
return rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen);
}
-static void rsa_freectx(void *vprsactx)
+void rsa_freectx(void *vprsactx)
{
PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
@@ -1504,6 +1504,35 @@ static const OSSL_PARAM *rsa_settable_ct
return EVP_MD_settable_ctx_params(prsactx->md);
}
+#ifdef FIPS_MODULE
+int do_rsa_pct(void *vctx, const char *mdname, void *rsa)
+{
+ static const char data[32];
+ unsigned char sigbuf[256];
+ size_t siglen = sizeof(sigbuf);
+
+ if (rsa_digest_sign_init(vctx, mdname, rsa, NULL) <= 0)
+ return 0;
+
+ if (rsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0)
+ return 0;
+
+ if (rsa_digest_sign_final(vctx, sigbuf, &siglen, sizeof(sigbuf)) <= 0)
+ return 0;
+
+ if (rsa_digest_verify_init(vctx, mdname, rsa, NULL) <= 0)
+ return 0;
+
+ if (rsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0)
+ return 0;
+
+ if (rsa_digest_verify_final(vctx, sigbuf, siglen) <= 0)
+ return 0;
+
+ return 1;
+}
+#endif
+
const OSSL_DISPATCH ossl_rsa_signature_functions[] = {
{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx },
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))rsa_sign_init },