summaryrefslogtreecommitdiff
path: root/lib/nettle
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-11-07 09:11:24 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-11-07 11:13:54 +0100
commit1fb6d1b577b51e0cb9ff48fa7a7a1b73630585b3 (patch)
tree9b68bfa8913d726701fc0f7928cf27ca99421a4c /lib/nettle
parent0756453bac4b1e4dcec06caf76534eb14bba5a5c (diff)
downloadgnutls-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.c100
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)