gnutls/gnutls_ECDSA_signing.patch
Pedro Monreal Gonzalez 5fcfc4e55e Accepting request 1003480 from home:pmonrealgonzalez:branches:security:tls
- 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
2022-09-14 08:41:21 +00:00

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) {