Pedro Monreal Gonzalez
5fcfc4e55e
- FIPS: Additional modifications to the SLI. [bsc#1190698] * Mark CMAC and GMAC and non-approved in gnutls_pbkfd2(). * Mark HMAC keylength less than 112 bits as non-approved in gnutls_pbkfd2(). * Adapt the pbkdf2 selftest and the regression tests accordingly. * Add gnutls-FIPS-SLI-pbkdf2-verify-keylengths-only-SHA.patch - FIPS: Port GnuTLS to use jitterentropy [bsc#1202146, jsc#SLE-24941] * Add new dependency on jitterentropy * Add gnutls-FIPS-jitterentropy.patch - FIPS: * Add gnutls_ECDSA_signing.patch [bsc#1190698] - Check minimum keylength for symmetric key generation - Only allows ECDSA signature with valid set of hashes (SHA2 and SHA3) OBS-URL: https://build.opensuse.org/request/show/1003480 OBS-URL: https://build.opensuse.org/package/show/security:tls/gnutls?expand=0&rev=73
173 lines
4.7 KiB
Diff
173 lines
4.7 KiB
Diff
Index: gnutls-3.7.7/lib/crypto-api.c
|
|
===================================================================
|
|
--- gnutls-3.7.7.orig/lib/crypto-api.c
|
|
+++ gnutls-3.7.7/lib/crypto-api.c
|
|
@@ -1056,6 +1056,7 @@ gnutls_hash_hd_t gnutls_hash_copy(gnutls
|
|
int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size)
|
|
{
|
|
int ret;
|
|
+ bool not_approved = false;
|
|
|
|
FAIL_IF_LIB_ERROR;
|
|
|
|
@@ -1066,6 +1067,10 @@ int gnutls_key_generate(gnutls_datum_t *
|
|
if (_gnutls_fips_mode_enabled() != 0 &&
|
|
key_size > FIPS140_RND_KEY_SIZE)
|
|
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
+ if (key_size < 14) {
|
|
+ not_approved = true;
|
|
+ }
|
|
+
|
|
#endif
|
|
|
|
key->size = key_size;
|
|
@@ -1082,6 +1087,15 @@ int gnutls_key_generate(gnutls_datum_t *
|
|
return ret;
|
|
}
|
|
|
|
+#ifdef ENABLE_FIPS140
|
|
+ if (not_approved) {
|
|
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
|
|
+ } else {
|
|
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
|
|
+ }
|
|
+
|
|
+#endif
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
Index: gnutls-3.7.7/lib/fips.h
|
|
===================================================================
|
|
--- gnutls-3.7.7.orig/lib/fips.h
|
|
+++ gnutls-3.7.7/lib/fips.h
|
|
@@ -145,6 +145,30 @@ is_cipher_algo_allowed_in_fips(gnutls_ci
|
|
}
|
|
}
|
|
|
|
+inline static bool
|
|
+is_digest_algo_approved_for_sign_in_fips(gnutls_digest_algorithm_t algo)
|
|
+{
|
|
+ switch (algo) {
|
|
+ case GNUTLS_DIG_SHA224:
|
|
+ case GNUTLS_DIG_SHA256:
|
|
+ case GNUTLS_DIG_SHA384:
|
|
+ case GNUTLS_DIG_SHA512:
|
|
+ case GNUTLS_DIG_SHA3_224:
|
|
+ case GNUTLS_DIG_SHA3_256:
|
|
+ case GNUTLS_DIG_SHA3_384:
|
|
+ case GNUTLS_DIG_SHA3_512:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
+inline static bool
|
|
+is_digest_algo_allowed_for_sign_in_fips(gnutls_digest_algorithm_t algo)
|
|
+{
|
|
+ return is_digest_algo_approved_for_sign_in_fips(algo);
|
|
+}
|
|
+
|
|
#ifdef ENABLE_FIPS140
|
|
/* This will test the condition when in FIPS140-2 mode
|
|
* and return an error if necessary or ignore */
|
|
@@ -205,9 +229,33 @@ is_cipher_algo_allowed(gnutls_cipher_alg
|
|
|
|
return true;
|
|
}
|
|
+
|
|
+inline static bool
|
|
+is_digest_algo_allowed_for_sign(gnutls_digest_algorithm_t algo)
|
|
+{
|
|
+ gnutls_fips_mode_t mode = _gnutls_fips_mode_enabled();
|
|
+ if (_gnutls_get_lib_state() != LIB_STATE_SELFTEST &&
|
|
+ !is_digest_algo_allowed_for_sign_in_fips(algo)) {
|
|
+ switch (mode) {
|
|
+ case GNUTLS_FIPS140_LOG:
|
|
+ _gnutls_audit_log(NULL, "fips140-2: allowing access to %s\n",
|
|
+ gnutls_cipher_get_name(algo));
|
|
+ FALLTHROUGH;
|
|
+ case GNUTLS_FIPS140_DISABLED:
|
|
+ case GNUTLS_FIPS140_LAX:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
#else
|
|
# define is_mac_algo_allowed(x) true
|
|
# define is_cipher_algo_allowed(x) true
|
|
+# define is_digest_algo_allowed_for_sign(x) true
|
|
# define FIPS_RULE(condition, ret_error, ...)
|
|
#endif
|
|
|
|
Index: gnutls-3.7.7/lib/privkey.c
|
|
===================================================================
|
|
--- gnutls-3.7.7.orig/lib/privkey.c
|
|
+++ gnutls-3.7.7/lib/privkey.c
|
|
@@ -1284,10 +1284,24 @@ privkey_sign_and_hash_data(gnutls_privke
|
|
int ret;
|
|
gnutls_datum_t digest;
|
|
const mac_entry_st *me;
|
|
+ bool not_approved = false;
|
|
|
|
if (unlikely(se == NULL))
|
|
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
|
|
+ if (se->pk == GNUTLS_PK_ECDSA && !is_digest_algo_allowed_for_sign(se->hash)) {
|
|
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
|
|
+ return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
|
|
+ } else if (se->pk == GNUTLS_PK_ECDSA && !is_digest_algo_approved_for_sign_in_fips(se->hash)) {
|
|
+ not_approved = true;
|
|
+ }
|
|
+
|
|
+ if (not_approved) {
|
|
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
|
|
+ } else {
|
|
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
|
|
+ }
|
|
+
|
|
if (_gnutls_pk_is_not_prehashed(se->pk)) {
|
|
return privkey_sign_raw_data(signer, se, data, signature, params);
|
|
}
|
|
Index: gnutls-3.7.7/tests/fips-test.c
|
|
===================================================================
|
|
--- gnutls-3.7.7.orig/tests/fips-test.c
|
|
+++ gnutls-3.7.7/tests/fips-test.c
|
|
@@ -38,6 +38,7 @@ static void tls_log_func(int level, cons
|
|
fprintf(stderr, "<%d>| %s", level, str);
|
|
}
|
|
|
|
+static uint8_t key13[13];
|
|
static uint8_t key16[16];
|
|
static uint8_t iv16[16];
|
|
uint8_t key_data[64];
|
|
@@ -269,6 +270,7 @@ void doit(void)
|
|
gnutls_pubkey_t pubkey;
|
|
gnutls_x509_privkey_t xprivkey;
|
|
gnutls_privkey_t privkey;
|
|
+ gnutls_datum_t key_invalid = { key13, sizeof(key13) };
|
|
gnutls_datum_t key = { key16, sizeof(key16) };
|
|
gnutls_datum_t iv = { iv16, sizeof(iv16) };
|
|
gnutls_datum_t signature;
|
|
@@ -309,6 +311,14 @@ void doit(void)
|
|
/* Try crypto.h functionality */
|
|
test_ciphers();
|
|
|
|
+ /* Try creating key with less than 112 bits: not approved */
|
|
+ FIPS_PUSH_CONTEXT();
|
|
+ ret = gnutls_key_generate(&key_invalid, 13);
|
|
+ if (ret < 0) {
|
|
+ fail("gnutls_generate_key failed\n");
|
|
+ }
|
|
+ FIPS_POP_CONTEXT(NOT_APPROVED);
|
|
+
|
|
FIPS_PUSH_CONTEXT();
|
|
ret = gnutls_cipher_init(&ch, GNUTLS_CIPHER_AES_128_CBC, &key, &iv);
|
|
if (ret < 0) {
|