diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-11-07 09:11:24 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-11-07 11:13:54 +0100 |
commit | 1fb6d1b577b51e0cb9ff48fa7a7a1b73630585b3 (patch) | |
tree | 9b68bfa8913d726701fc0f7928cf27ca99421a4c /lib/nettle | |
parent | 0756453bac4b1e4dcec06caf76534eb14bba5a5c (diff) | |
download | gnutls-1fb6d1b577b51e0cb9ff48fa7a7a1b73630585b3.tar.gz |
fips140-2: moved PCT-test in wrap_nettle_generate_keys
This allows it to run in any potential scenario, i.e., any
call of _gnutls_pk_generate_keys().
Diffstat (limited to 'lib/nettle')
-rw-r--r-- | lib/nettle/pk.c | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 851bda7102..b281684d56 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -1175,8 +1175,97 @@ int _gnutls_ecdh_compute_key(gnutls_ecc_curve_t curve, gnutls_pk_params_clear(&priv); return ret; } -#endif +static int pct_test(gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params) +{ +int ret; +gnutls_datum_t sig = {NULL, 0}; +const char const_data[20] = "onetwothreefourfive"; +gnutls_datum_t ddata, tmp = {NULL,0}; +char* gen_data = NULL; + + if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) { + unsigned hash_len; + + _gnutls_dsa_q_to_hash(algo, params, &hash_len); + gen_data = gnutls_malloc(hash_len); + gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len); + + ddata.data = (void*)gen_data; + ddata.size = hash_len; + } else { + ddata.data = (void*)const_data; + ddata.size = sizeof(const_data); + } + + switch (algo) { + case GNUTLS_PK_RSA: + ret = _gnutls_pk_encrypt(algo, &sig, &ddata, params); + if (ret < 0) { + ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); + goto cleanup; + } + + if (ddata.size == sig.size && memcmp(ddata.data, sig.data, sig.size) == 0) { + ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_pk_decrypt(algo, &tmp, &sig, params); + if (ret < 0) { + ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); + gnutls_assert(); + goto cleanup; + } + + if (tmp.size != ddata.size || memcmp(tmp.data, ddata.data, tmp.size) != 0) { + ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); + gnutls_assert(); + goto cleanup; + } + + free(sig.data); + sig.data = NULL; + + /* Here we don't know the purpose of the key. Check both + * signing and encryption. + */ + case GNUTLS_PK_EC: /* we only do keys for ECDSA */ + case GNUTLS_PK_DSA: + ret = _gnutls_pk_sign(algo, &sig, &ddata, params); + if (ret < 0) { + ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); + goto cleanup; + } + + ret = _gnutls_pk_verify(algo, &ddata, &sig, params); + if (ret < 0) { + ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); + gnutls_assert(); + goto cleanup; + } + break; + case GNUTLS_PK_DH: + case GNUTLS_PK_ECDHX: + ret = 0; + goto cleanup; + default: + ret = gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM); + goto cleanup; + } + + ret = 0; +cleanup: + if (ret == GNUTLS_E_PK_GENERATION_ERROR) { + _gnutls_switch_lib_state(LIB_STATE_ERROR); + } + gnutls_free(gen_data); + gnutls_free(sig.data); + gnutls_free(tmp.data); + return ret; +} +#endif /* To generate a DH key either q must be set in the params or * level should be set to the number of required bits. @@ -1460,6 +1549,14 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo, return GNUTLS_E_INVALID_REQUEST; } +#ifdef ENABLE_FIPS140 + ret = pct_test(algo, params); + if (ret < 0) { + gnutls_assert(); + goto fail; + } +#endif + FAIL_IF_LIB_ERROR; return 0; @@ -1478,6 +1575,7 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo, return ret; } + static int wrap_nettle_pk_verify_priv_params(gnutls_pk_algorithm_t algo, const gnutls_pk_params_st * params) |