|
|
e79d4b |
From 237695d30c9f716333cfa077554a6e1ae0d2c589 Mon Sep 17 00:00:00 2001
|
|
|
e79d4b |
From: rpm-build <rpm-build>
|
|
|
e79d4b |
Date: Sat, 20 Aug 2022 09:52:08 +0900
|
|
|
e79d4b |
Subject: [PATCH] gnutls-3.7.6-fips-rsa-key-sizes.patch
|
|
|
e79d4b |
|
|
|
e79d4b |
---
|
|
|
e79d4b |
lib/nettle/pk.c | 54 ++++---
|
|
|
e79d4b |
tests/Makefile.am | 3 +-
|
|
|
e79d4b |
tests/fips-rsa-sizes.c | 328 +++++++++++++++++++++++++++++++++++++++++
|
|
|
e79d4b |
3 files changed, 361 insertions(+), 24 deletions(-)
|
|
|
e79d4b |
create mode 100644 tests/fips-rsa-sizes.c
|
|
|
e79d4b |
|
|
|
e79d4b |
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
|
|
|
e79d4b |
index eba246f..f38016b 100644
|
|
|
e79d4b |
--- a/lib/nettle/pk.c
|
|
|
e79d4b |
+++ b/lib/nettle/pk.c
|
|
|
e79d4b |
@@ -1247,20 +1247,20 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
|
|
|
e79d4b |
|
|
|
e79d4b |
_rsa_params_to_privkey(pk_params, &priv;;
|
|
|
e79d4b |
|
|
|
e79d4b |
- /* RSA key size should be 2048-bit or larger in FIPS
|
|
|
e79d4b |
- * 140-3. In addition to this, only SHA-2 is allowed
|
|
|
e79d4b |
- * for SigGen; it is checked in pk_prepare_hash lib/pk.c
|
|
|
e79d4b |
- */
|
|
|
e79d4b |
- if (unlikely(priv.size < 256)) {
|
|
|
e79d4b |
- not_approved = true;
|
|
|
e79d4b |
- }
|
|
|
e79d4b |
-
|
|
|
e79d4b |
ret = _rsa_params_to_pubkey(pk_params, &pub;;
|
|
|
e79d4b |
if (ret < 0) {
|
|
|
e79d4b |
gnutls_assert();
|
|
|
e79d4b |
goto cleanup;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
+ /* RSA modulus size should be 2048-bit or larger in FIPS
|
|
|
e79d4b |
+ * 140-3. In addition to this, only SHA-2 is allowed
|
|
|
e79d4b |
+ * for SigGen; it is checked in pk_prepare_hash lib/pk.c
|
|
|
e79d4b |
+ */
|
|
|
e79d4b |
+ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
|
|
|
e79d4b |
+ not_approved = true;
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
mpz_init(s);
|
|
|
e79d4b |
|
|
|
e79d4b |
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
|
|
|
e79d4b |
@@ -1298,22 +1298,22 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
|
|
|
e79d4b |
|
|
|
e79d4b |
_rsa_params_to_privkey(pk_params, &priv;;
|
|
|
e79d4b |
|
|
|
e79d4b |
- /* RSA key size should be 2048-bit or larger in FIPS
|
|
|
e79d4b |
+ ret = _rsa_params_to_pubkey(pk_params, &pub;;
|
|
|
e79d4b |
+ if (ret < 0) {
|
|
|
e79d4b |
+ gnutls_assert();
|
|
|
e79d4b |
+ goto cleanup;
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* RSA modulus size should be 2048-bit or larger in FIPS
|
|
|
e79d4b |
* 140-3. In addition to this, only SHA-2 is allowed
|
|
|
e79d4b |
* for SigGen; however, Nettle only support SHA256,
|
|
|
e79d4b |
* SHA384, and SHA512 for RSA-PSS (see
|
|
|
e79d4b |
* _rsa_pss_sign_digest_tr in this file for details).
|
|
|
e79d4b |
*/
|
|
|
e79d4b |
- if (unlikely(priv.size < 256)) {
|
|
|
e79d4b |
+ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
|
|
|
e79d4b |
not_approved = true;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
- ret = _rsa_params_to_pubkey(pk_params, &pub;;
|
|
|
e79d4b |
- if (ret < 0) {
|
|
|
e79d4b |
- gnutls_assert();
|
|
|
e79d4b |
- goto cleanup;
|
|
|
e79d4b |
- }
|
|
|
e79d4b |
-
|
|
|
e79d4b |
mpz_init(s);
|
|
|
e79d4b |
|
|
|
e79d4b |
ret =
|
|
|
e79d4b |
@@ -1643,6 +1643,7 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
|
|
|
e79d4b |
case GNUTLS_PK_RSA:
|
|
|
e79d4b |
{
|
|
|
e79d4b |
struct rsa_public_key pub;
|
|
|
e79d4b |
+ size_t bits;
|
|
|
e79d4b |
|
|
|
e79d4b |
ret = _rsa_params_to_pubkey(pk_params, &pub;;
|
|
|
e79d4b |
if (ret < 0) {
|
|
|
e79d4b |
@@ -1650,12 +1651,19 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
|
|
|
e79d4b |
goto cleanup;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
- /* RSA key size should be 2048-bit or larger in FIPS
|
|
|
e79d4b |
- * 140-3. In addition to this, only SHA-1 and SHA-2 are
|
|
|
e79d4b |
- * allowed for SigVer; it is checked in
|
|
|
e79d4b |
- * _pkcs1_rsa_verify_sig in lib/pubkey.c
|
|
|
e79d4b |
+ bits = mpz_sizeinbase(pub.n, 2);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* In FIPS 140-3, RSA key size should be larger than
|
|
|
e79d4b |
+ * 2048-bit or one of the known lengths (1024, 1280,
|
|
|
e79d4b |
+ * 1536, 1792; i.e., multiple of 256-bits).
|
|
|
e79d4b |
+ *
|
|
|
e79d4b |
+ * In addition to this, only SHA-1 and SHA-2 are allowed
|
|
|
e79d4b |
+ * for SigVer; it is checked in _pkcs1_rsa_verify_sig in
|
|
|
e79d4b |
+ * lib/pubkey.c.
|
|
|
e79d4b |
*/
|
|
|
e79d4b |
- if (unlikely(pub.size < 256)) {
|
|
|
e79d4b |
+ if (unlikely(bits < 2048 &&
|
|
|
e79d4b |
+ bits != 1024 && bits != 1280 &&
|
|
|
e79d4b |
+ bits != 1536 && bits != 1792)) {
|
|
|
e79d4b |
not_approved = true;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
@@ -1701,13 +1709,13 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
|
|
|
e79d4b |
goto cleanup;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
- /* RSA key size should be 2048-bit or larger in FIPS
|
|
|
e79d4b |
+ /* RSA modulus size should be 2048-bit or larger in FIPS
|
|
|
e79d4b |
* 140-3. In addition to this, only SHA-1 and SHA-2 are
|
|
|
e79d4b |
* allowed for SigVer, while Nettle only supports
|
|
|
e79d4b |
* SHA256, SHA384, and SHA512 for RSA-PSS (see
|
|
|
e79d4b |
* _rsa_pss_verify_digest in this file for the details).
|
|
|
e79d4b |
*/
|
|
|
e79d4b |
- if (unlikely(pub.size < 256)) {
|
|
|
e79d4b |
+ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
|
|
|
e79d4b |
not_approved = true;
|
|
|
e79d4b |
}
|
|
|
e79d4b |
|
|
|
e79d4b |
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
|
|
e79d4b |
index 7a7a4af..dd21e45 100644
|
|
|
e79d4b |
--- a/tests/Makefile.am
|
|
|
e79d4b |
+++ b/tests/Makefile.am
|
|
|
e79d4b |
@@ -233,7 +233,8 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
|
|
|
e79d4b |
tls13-without-timeout-func buffer status-request-revoked \
|
|
|
e79d4b |
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
|
|
|
e79d4b |
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
|
|
|
e79d4b |
- x509-upnconstraint pkcs7-verify-double-free
|
|
|
e79d4b |
+ x509-upnconstraint pkcs7-verify-double-free \
|
|
|
e79d4b |
+ fips-rsa-sizes
|
|
|
e79d4b |
|
|
|
e79d4b |
ctests += tls-channel-binding
|
|
|
e79d4b |
|
|
|
e79d4b |
diff --git a/tests/fips-rsa-sizes.c b/tests/fips-rsa-sizes.c
|
|
|
e79d4b |
new file mode 100644
|
|
|
e79d4b |
index 0000000..84b9aff
|
|
|
e79d4b |
--- /dev/null
|
|
|
e79d4b |
+++ b/tests/fips-rsa-sizes.c
|
|
|
e79d4b |
@@ -0,0 +1,328 @@
|
|
|
e79d4b |
+/*
|
|
|
e79d4b |
+ * Copyright (C) 2022 Red Hat, Inc.
|
|
|
e79d4b |
+ *
|
|
|
e79d4b |
+ * Author: Alexander Sosedkin
|
|
|
e79d4b |
+ *
|
|
|
e79d4b |
+ * This file is part of GnuTLS.
|
|
|
e79d4b |
+ *
|
|
|
e79d4b |
+ * GnuTLS is free software; you can redistribute it and/or modify it
|
|
|
e79d4b |
+ * under the terms of the GNU General Public License as published by
|
|
|
e79d4b |
+ * the Free Software Foundation; either version 3 of the License, or
|
|
|
e79d4b |
+ * (at your option) any later version.
|
|
|
e79d4b |
+ *
|
|
|
e79d4b |
+ * GnuTLS is distributed in the hope that it will be useful, but
|
|
|
e79d4b |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
e79d4b |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
e79d4b |
+ * General Public License for more details.
|
|
|
e79d4b |
+ *
|
|
|
e79d4b |
+ * You should have received a copy of the GNU General Public License
|
|
|
e79d4b |
+ * along with GnuTLS; if not, write to the Free Software Foundation,
|
|
|
e79d4b |
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
e79d4b |
+ */
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+#include <assert.h>
|
|
|
e79d4b |
+#include <stdio.h>
|
|
|
e79d4b |
+#include <utils.h>
|
|
|
e79d4b |
+#include <gnutls/gnutls.h>
|
|
|
e79d4b |
+#include <gnutls/abstract.h>
|
|
|
e79d4b |
+#include <gnutls/x509.h>
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+#define FIPS_PUSH_CONTEXT() do { \
|
|
|
e79d4b |
+ ret = gnutls_fips140_push_context(fips_context); \
|
|
|
e79d4b |
+ if (ret < 0) { \
|
|
|
e79d4b |
+ fail("gnutls_fips140_push_context failed\n"); \
|
|
|
e79d4b |
+ } \
|
|
|
e79d4b |
+} while (0)
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+#define FIPS_POP_CONTEXT(state) do { \
|
|
|
e79d4b |
+ ret = gnutls_fips140_pop_context(); \
|
|
|
e79d4b |
+ if (ret < 0) { \
|
|
|
e79d4b |
+ fail("gnutls_fips140_context_pop failed\n"); \
|
|
|
e79d4b |
+ } \
|
|
|
e79d4b |
+ fips_state = gnutls_fips140_get_operation_state(fips_context); \
|
|
|
e79d4b |
+ if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
|
|
|
e79d4b |
+ fail("operation state is not " # state " (%d)\n", \
|
|
|
e79d4b |
+ fips_state); \
|
|
|
e79d4b |
+ } \
|
|
|
e79d4b |
+} while (0)
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
|
|
|
e79d4b |
+ unsigned int size);
|
|
|
e79d4b |
+void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
|
|
|
e79d4b |
+ unsigned int size);
|
|
|
e79d4b |
+void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey);
|
|
|
e79d4b |
+void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
|
|
|
e79d4b |
+ gnutls_pubkey_t pubkey);
|
|
|
e79d4b |
+void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
|
|
|
e79d4b |
+ unsigned int size)
|
|
|
e79d4b |
+{
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
+ gnutls_x509_privkey_t xprivkey;
|
|
|
e79d4b |
+ gnutls_fips140_context_t fips_context;
|
|
|
e79d4b |
+ gnutls_fips140_operation_state_t fips_state;
|
|
|
e79d4b |
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ fprintf(stderr, "%d-bit\n", size);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* x509 generation as well just because why not */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ assert(gnutls_x509_privkey_init(&xprivkey) == 0);
|
|
|
e79d4b |
+ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_SUCCESS)
|
|
|
e79d4b |
+ fail("%d-bit x509_privkey_init (%d)\n", size, ret);
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(APPROVED);
|
|
|
e79d4b |
+ gnutls_x509_privkey_deinit(xprivkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ assert(gnutls_privkey_init(privkey) == 0);
|
|
|
e79d4b |
+ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_SUCCESS)
|
|
|
e79d4b |
+ fail("%d-bit privkey_init (%d)\n", size, ret);
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(APPROVED);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ assert(gnutls_pubkey_init(pubkey) == 0);
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ ret = gnutls_pubkey_import_privkey(*pubkey, *privkey,
|
|
|
e79d4b |
+ GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_SUCCESS)
|
|
|
e79d4b |
+ fail("%d-bit pubkey_import_privkey (%d)\n", size, ret);
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(INITIAL);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_fips140_context_deinit(fips_context);
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
|
|
|
e79d4b |
+ unsigned int size)
|
|
|
e79d4b |
+{
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
+ gnutls_x509_privkey_t xprivkey;
|
|
|
e79d4b |
+ gnutls_fips140_context_t fips_context;
|
|
|
e79d4b |
+ gnutls_fips140_operation_state_t fips_state;
|
|
|
e79d4b |
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ fprintf(stderr, "%d-bit\n", size);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* short x509 generation: ERROR, blocked */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ assert(gnutls_x509_privkey_init(&xprivkey) == 0);
|
|
|
e79d4b |
+ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_PK_GENERATION_ERROR)
|
|
|
e79d4b |
+ fail("%d-bit x509_privkey_init (%d)\n", size, ret);
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(ERROR);
|
|
|
e79d4b |
+ gnutls_x509_privkey_deinit(xprivkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* short key generation: ERROR, blocked */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ assert(gnutls_privkey_init(privkey) == 0);
|
|
|
e79d4b |
+ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_PK_GENERATION_ERROR)
|
|
|
e79d4b |
+ fail("%d-bit privkey_init (%d)\n", size, ret);
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(ERROR);
|
|
|
e79d4b |
+ gnutls_privkey_deinit(*privkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* Disable FIPS to generate them anyway */
|
|
|
e79d4b |
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0);
|
|
|
e79d4b |
+ assert(gnutls_fips140_mode_enabled() == GNUTLS_FIPS140_LAX);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ assert(gnutls_x509_privkey_init(&xprivkey) == 0);
|
|
|
e79d4b |
+ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_SUCCESS)
|
|
|
e79d4b |
+ fail("%d-bit x509_privkey_init (%d)\n", size, ret);
|
|
|
e79d4b |
+ gnutls_x509_privkey_deinit(xprivkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ assert(gnutls_privkey_init(privkey) == 0);
|
|
|
e79d4b |
+ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_SUCCESS)
|
|
|
e79d4b |
+ fail("%d-bit privkey_init (%d)\n", size, ret);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ assert(gnutls_pubkey_init(pubkey) == 0);
|
|
|
e79d4b |
+ ret = gnutls_pubkey_import_privkey(*pubkey, *privkey,
|
|
|
e79d4b |
+ GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
|
|
|
e79d4b |
+ if (ret != GNUTLS_E_SUCCESS)
|
|
|
e79d4b |
+ fail("%d-bit pubkey_import_privkey (%d)\n", size, ret);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_STRICT, 0);
|
|
|
e79d4b |
+ assert(gnutls_fips140_mode_enabled());
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_fips140_context_deinit(fips_context);
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
+ gnutls_fips140_context_t fips_context;
|
|
|
e79d4b |
+ gnutls_fips140_operation_state_t fips_state;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_datum_t signature;
|
|
|
e79d4b |
+ gnutls_datum_t plaintext = {
|
|
|
e79d4b |
+ .data = (unsigned char* const) "Hello world!",
|
|
|
e79d4b |
+ .size = 12
|
|
|
e79d4b |
+ };
|
|
|
e79d4b |
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* RSA sign: approved */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
|
|
|
e79d4b |
+ &plaintext, &signature);
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_privkey_sign_data failed\n");
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(APPROVED);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* RSA verify: approved */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
|
|
|
e79d4b |
+ &plaintext, &signature);
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_pubkey_verify_data2 failed\n");
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(APPROVED);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_free(signature.data);
|
|
|
e79d4b |
+ gnutls_fips140_context_deinit(fips_context);
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
|
|
|
e79d4b |
+ gnutls_pubkey_t pubkey) {
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
+ gnutls_fips140_context_t fips_context;
|
|
|
e79d4b |
+ gnutls_fips140_operation_state_t fips_state;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_datum_t signature;
|
|
|
e79d4b |
+ gnutls_datum_t plaintext = {
|
|
|
e79d4b |
+ .data = (unsigned char* const) "Hello world!",
|
|
|
e79d4b |
+ .size = 12
|
|
|
e79d4b |
+ };
|
|
|
e79d4b |
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* small key RSA sign: not approved */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
|
|
|
e79d4b |
+ &plaintext, &signature);
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_privkey_sign_data failed\n");
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(NOT_APPROVED);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* small key RSA verify: not approved */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
|
|
|
e79d4b |
+ &plaintext, &signature);
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_pubkey_verify_data2 failed\n");
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(NOT_APPROVED);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_free(signature.data);
|
|
|
e79d4b |
+ gnutls_pubkey_deinit(pubkey);
|
|
|
e79d4b |
+ gnutls_privkey_deinit(privkey);
|
|
|
e79d4b |
+ gnutls_fips140_context_deinit(fips_context);
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
|
|
|
e79d4b |
+ int ret;
|
|
|
e79d4b |
+ gnutls_fips140_context_t fips_context;
|
|
|
e79d4b |
+ gnutls_fips140_operation_state_t fips_state;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_datum_t signature;
|
|
|
e79d4b |
+ gnutls_datum_t plaintext = {
|
|
|
e79d4b |
+ .data = (unsigned char* const) "Hello world!",
|
|
|
e79d4b |
+ .size = 12
|
|
|
e79d4b |
+ };
|
|
|
e79d4b |
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* 1024, 1280, 1536, 1792 key RSA sign: not approved */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
|
|
|
e79d4b |
+ &plaintext, &signature);
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_privkey_sign_data failed\n");
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(NOT_APPROVED);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* Disable FIPS to sign them anyway */
|
|
|
e79d4b |
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0);
|
|
|
e79d4b |
+ assert(gnutls_fips140_mode_enabled() == GNUTLS_FIPS140_LAX);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
|
|
|
e79d4b |
+ &plaintext, &signature);
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_privkey_sign_data failed\n");
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_STRICT, 0);
|
|
|
e79d4b |
+ assert(gnutls_fips140_mode_enabled());
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* 1024, 1280, 1536, 1792 key RSA verify: approved (exception) */
|
|
|
e79d4b |
+ FIPS_PUSH_CONTEXT();
|
|
|
e79d4b |
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
|
|
|
e79d4b |
+ &plaintext, &signature);
|
|
|
e79d4b |
+ if (ret < 0)
|
|
|
e79d4b |
+ fail("gnutls_pubkey_verify_data2 failed\n");
|
|
|
e79d4b |
+ FIPS_POP_CONTEXT(APPROVED);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_free(signature.data);
|
|
|
e79d4b |
+ gnutls_pubkey_deinit(pubkey);
|
|
|
e79d4b |
+ gnutls_privkey_deinit(privkey);
|
|
|
e79d4b |
+ gnutls_fips140_context_deinit(fips_context);
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+void doit(void)
|
|
|
e79d4b |
+{
|
|
|
e79d4b |
+ gnutls_fips140_context_t fips_context;
|
|
|
e79d4b |
+ gnutls_privkey_t privkey;
|
|
|
e79d4b |
+ gnutls_pubkey_t pubkey;
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ if (gnutls_fips140_mode_enabled() == 0) {
|
|
|
e79d4b |
+ success("We are not in FIPS140 mode\n");
|
|
|
e79d4b |
+ exit(77); /* SKIP */
|
|
|
e79d4b |
+ }
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* 512-bit RSA: no generate, no sign, no verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 512);
|
|
|
e79d4b |
+ sign_verify_unsuccessfully(privkey, pubkey);
|
|
|
e79d4b |
+ /* 512-bit RSA again (to be safer about going in and out of FIPS) */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 512);
|
|
|
e79d4b |
+ sign_verify_unsuccessfully(privkey, pubkey);
|
|
|
e79d4b |
+ /* 600-bit RSA: no generate, no sign, no verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 600);
|
|
|
e79d4b |
+ sign_verify_unsuccessfully(privkey, pubkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* 768-bit RSA not-an-exception: nogenerate, nosign, verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 768);
|
|
|
e79d4b |
+ sign_verify_unsuccessfully(privkey, pubkey);
|
|
|
e79d4b |
+ /* 1024-bit RSA exception: nogenerate, nosign, verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 1024);
|
|
|
e79d4b |
+ nosign_verify(privkey, pubkey);
|
|
|
e79d4b |
+ /* 1280-bit RSA exception: nogenerate, nosign, verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 1280);
|
|
|
e79d4b |
+ nosign_verify(privkey, pubkey);
|
|
|
e79d4b |
+ /* 1500-bit RSA not-an-exception: nogenerate, nosign, noverify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 1500);
|
|
|
e79d4b |
+ sign_verify_unsuccessfully(privkey, pubkey);
|
|
|
e79d4b |
+ /* 1536-bit RSA exception: nogenerate, nosign, verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 1536);
|
|
|
e79d4b |
+ nosign_verify(privkey, pubkey);
|
|
|
e79d4b |
+ /* 1792-bit RSA exception: nogenerate, nosign, verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 1792);
|
|
|
e79d4b |
+ nosign_verify(privkey, pubkey);
|
|
|
e79d4b |
+ /* 2000-bit RSA not-an-exception: nogenerate, nosign, noverify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 2000);
|
|
|
e79d4b |
+ sign_verify_unsuccessfully(privkey, pubkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ /* 2048-bit RSA: generate, sign, verify */
|
|
|
e79d4b |
+ generate_successfully(&privkey, &pubkey, 2048);
|
|
|
e79d4b |
+ sign_verify_successfully(privkey, pubkey);
|
|
|
e79d4b |
+ /* 2432-bit RSA: nogenerate, sign, verify */
|
|
|
e79d4b |
+ generate_unsuccessfully(&privkey, &pubkey, 2432);
|
|
|
e79d4b |
+ sign_verify_successfully(privkey, pubkey);
|
|
|
e79d4b |
+ /* 3072-bit RSA: generate, sign, verify */
|
|
|
e79d4b |
+ generate_successfully(&privkey, &pubkey, 3072);
|
|
|
e79d4b |
+ sign_verify_successfully(privkey, pubkey);
|
|
|
e79d4b |
+
|
|
|
e79d4b |
+ gnutls_fips140_context_deinit(fips_context);
|
|
|
e79d4b |
+}
|
|
|
e79d4b |
--
|
|
|
e79d4b |
2.37.2
|
|
|
e79d4b |
|