Blame SOURCES/gnutls-3.3.8-dh-fips-tests.patch

873a72
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
873a72
index b9ca0cb..ac8a922 100644
873a72
--- a/lib/gnutls_global.c
873a72
+++ b/lib/gnutls_global.c
873a72
@@ -297,6 +297,7 @@ int gnutls_global_init(void)
873a72
 	 * res == not in fips140 mode
873a72
 	 */
873a72
 	if (res != 0) {
873a72
+		_gnutls_debug_log("FIPS140-2 mode: %d\n", res);
873a72
 		_gnutls_priority_update_fips();
873a72
 
873a72
 		/* first round of self checks, these are done on the
873a72
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
873a72
index 5de541d..cbd62d7 100644
873a72
--- a/lib/libgnutls.map
873a72
+++ b/lib/libgnutls.map
873a72
@@ -1043,6 +1043,10 @@ GNUTLS_FIPS140 {
873a72
 	_gnutls_prf_raw;
873a72
 	_gnutls_encode_ber_rs_raw;
873a72
 	_rsa_generate_fips186_4_keypair;
873a72
+	_gnutls_dh_compute_key;
873a72
+	_gnutls_dh_generate_key;
873a72
+	_gnutls_ecdh_generate_key;
873a72
+	_gnutls_ecdh_compute_key;
873a72
 };
873a72
 
873a72
 GNUTLS_PRIVATE {
873a72
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
873a72
index fbc3da1..1b61051 100644
873a72
--- a/lib/nettle/pk.c
873a72
+++ b/lib/nettle/pk.c
873a72
@@ -844,7 +844,7 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
873a72
 #endif
873a72
 
873a72
 			params->params_nr = 0;
873a72
-			
873a72
+
873a72
 			ret = _gnutls_mpi_init_multi(&params->params[DSA_P], &params->params[DSA_Q],
873a72
 					&params->params[DSA_G], NULL);
873a72
 			if (ret < 0) {
873a72
@@ -891,6 +891,249 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
873a72
 	return ret;
873a72
 }
873a72
 
873a72
+#ifdef ENABLE_FIPS140
873a72
+int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params,
873a72
+			    gnutls_datum_t *priv_key, gnutls_datum_t *pub_key);
873a72
+
873a72
+int _gnutls_dh_compute_key(gnutls_dh_params_t dh_params,
873a72
+			   const gnutls_datum_t *priv_key, const gnutls_datum_t *pub_key,
873a72
+			   const gnutls_datum_t *peer_key, gnutls_datum_t *Z);
873a72
+
873a72
+int _gnutls_ecdh_compute_key(gnutls_ecc_curve_t curve,
873a72
+			   const gnutls_datum_t *x, const gnutls_datum_t *y,
873a72
+			   const gnutls_datum_t *k,
873a72
+			   const gnutls_datum_t *peer_x, const gnutls_datum_t *peer_y,
873a72
+			   gnutls_datum_t *Z);
873a72
+
873a72
+int _gnutls_ecdh_generate_key(gnutls_ecc_curve_t curve,
873a72
+			      gnutls_datum_t *x, gnutls_datum_t *y,
873a72
+			      gnutls_datum_t *k);
873a72
+
873a72
+
873a72
+int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params,
873a72
+			    gnutls_datum_t *priv_key, gnutls_datum_t *pub_key)
873a72
+{
873a72
+	gnutls_pk_params_st params;
873a72
+	int ret;
873a72
+
873a72
+	gnutls_pk_params_init(&params);
873a72
+	params.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]);
873a72
+	params.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]);
873a72
+
873a72
+	params.params_nr = 3; /* include empty q */
873a72
+	params.algo = GNUTLS_PK_DH;
873a72
+
873a72
+	priv_key->data = NULL;
873a72
+	pub_key->data = NULL;
873a72
+
873a72
+	ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, &params);
873a72
+	if (ret < 0) {
873a72
+		return gnutls_assert_val(ret);
873a72
+	}
873a72
+
873a72
+	ret =
873a72
+	    _gnutls_mpi_dprint_lz(params.params[DH_X], priv_key);
873a72
+	if (ret < 0) {
873a72
+		gnutls_assert();
873a72
+		goto fail;
873a72
+	}
873a72
+
873a72
+	ret =
873a72
+	    _gnutls_mpi_dprint_lz(params.params[DH_Y], pub_key);
873a72
+	if (ret < 0) {
873a72
+		gnutls_assert();
873a72
+		goto fail;
873a72
+	}
873a72
+
873a72
+	ret = 0;
873a72
+	goto cleanup;
873a72
+ fail:
873a72
+ 	gnutls_free(pub_key->data);
873a72
+ 	gnutls_free(priv_key->data);
873a72
+ cleanup:
873a72
+ 	gnutls_pk_params_clear(&params);
873a72
+ 	return ret;
873a72
+}
873a72
+
873a72
+int _gnutls_dh_compute_key(gnutls_dh_params_t dh_params,
873a72
+			   const gnutls_datum_t *priv_key, const gnutls_datum_t *pub_key,
873a72
+			   const gnutls_datum_t *peer_key, gnutls_datum_t *Z)
873a72
+{
873a72
+	gnutls_pk_params_st pub, priv;
873a72
+	int ret;
873a72
+
873a72
+	gnutls_pk_params_init(&pub;;
873a72
+	gnutls_pk_params_init(&priv;;
873a72
+	pub.algo = GNUTLS_PK_DH;
873a72
+
873a72
+	if (_gnutls_mpi_init_scan_nz
873a72
+		    (&pub.params[DH_Y], peer_key->data,
873a72
+		     peer_key->size) != 0) {
873a72
+		ret =
873a72
+		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	priv.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]);
873a72
+	priv.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]);
873a72
+
873a72
+	if (_gnutls_mpi_init_scan_nz
873a72
+		    (&priv.params[DH_X], priv_key->data,
873a72
+		     priv_key->size) != 0) {
873a72
+		ret =
873a72
+		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	priv.params_nr = 3; /* include empty q */
873a72
+	priv.algo = GNUTLS_PK_DH;
873a72
+
873a72
+	Z->data = NULL;
873a72
+
873a72
+	ret = _gnutls_pk_derive(GNUTLS_PK_DH, Z, &priv, &pub;;
873a72
+	if (ret < 0) {
873a72
+		gnutls_assert();
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	ret = 0;
873a72
+ cleanup:
873a72
+ 	gnutls_pk_params_clear(&pub;;
873a72
+ 	gnutls_pk_params_clear(&priv;;
873a72
+ 	return ret;
873a72
+}
873a72
+
873a72
+int _gnutls_ecdh_generate_key(gnutls_ecc_curve_t curve,
873a72
+			      gnutls_datum_t *x, gnutls_datum_t *y,
873a72
+			      gnutls_datum_t *k)
873a72
+{
873a72
+	gnutls_pk_params_st params;
873a72
+	int ret;
873a72
+
873a72
+	gnutls_pk_params_init(&params);
873a72
+	params.flags = curve;
873a72
+	params.algo = GNUTLS_PK_EC;
873a72
+
873a72
+	x->data = NULL;
873a72
+	y->data = NULL;
873a72
+	k->data = NULL;
873a72
+
873a72
+	ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, &params);
873a72
+	if (ret < 0) {
873a72
+		return gnutls_assert_val(ret);
873a72
+	}
873a72
+
873a72
+	ret =
873a72
+	    _gnutls_mpi_dprint_lz(params.params[ECC_X], x);
873a72
+	if (ret < 0) {
873a72
+		gnutls_assert();
873a72
+		goto fail;
873a72
+	}
873a72
+
873a72
+	ret =
873a72
+	    _gnutls_mpi_dprint_lz(params.params[ECC_Y], y);
873a72
+	if (ret < 0) {
873a72
+		gnutls_assert();
873a72
+		goto fail;
873a72
+	}
873a72
+
873a72
+	ret =
873a72
+	    _gnutls_mpi_dprint_lz(params.params[ECC_K], k);
873a72
+	if (ret < 0) {
873a72
+		gnutls_assert();
873a72
+		goto fail;
873a72
+	}
873a72
+
873a72
+	ret = 0;
873a72
+	goto cleanup;
873a72
+ fail:
873a72
+ 	gnutls_free(y->data);
873a72
+ 	gnutls_free(x->data);
873a72
+ 	gnutls_free(k->data);
873a72
+ cleanup:
873a72
+ 	gnutls_pk_params_clear(&params);
873a72
+ 	return ret;
873a72
+}
873a72
+
873a72
+int _gnutls_ecdh_compute_key(gnutls_ecc_curve_t curve,
873a72
+			   const gnutls_datum_t *x, const gnutls_datum_t *y,
873a72
+			   const gnutls_datum_t *k,
873a72
+			   const gnutls_datum_t *peer_x, const gnutls_datum_t *peer_y,
873a72
+			   gnutls_datum_t *Z)
873a72
+{
873a72
+	gnutls_pk_params_st pub, priv;
873a72
+	int ret;
873a72
+
873a72
+	gnutls_pk_params_init(&pub;;
873a72
+	gnutls_pk_params_init(&priv;;
873a72
+
873a72
+	pub.algo = GNUTLS_PK_EC;
873a72
+	pub.flags = curve;
873a72
+
873a72
+	if (_gnutls_mpi_init_scan_nz
873a72
+		    (&pub.params[ECC_Y], peer_y->data,
873a72
+		     peer_y->size) != 0) {
873a72
+		ret =
873a72
+		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	if (_gnutls_mpi_init_scan_nz
873a72
+		    (&pub.params[ECC_X], peer_x->data,
873a72
+		     peer_x->size) != 0) {
873a72
+		ret =
873a72
+		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	priv.params_nr = 2;
873a72
+
873a72
+	if (_gnutls_mpi_init_scan_nz
873a72
+		    (&priv.params[ECC_Y], y->data,
873a72
+		     y->size) != 0) {
873a72
+		ret =
873a72
+		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	if (_gnutls_mpi_init_scan_nz
873a72
+		    (&priv.params[ECC_X], x->data,
873a72
+		     x->size) != 0) {
873a72
+		ret =
873a72
+		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	if (_gnutls_mpi_init_scan_nz
873a72
+		    (&priv.params[ECC_K], k->data,
873a72
+		     k->size) != 0) {
873a72
+		ret =
873a72
+		    gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+
873a72
+	priv.params_nr = 3;
873a72
+	priv.algo = GNUTLS_PK_EC;
873a72
+	priv.flags = curve;
873a72
+
873a72
+	Z->data = NULL;
873a72
+
873a72
+	ret = _gnutls_pk_derive(GNUTLS_PK_EC, Z, &priv, &pub;;
873a72
+	if (ret < 0) {
873a72
+		gnutls_assert();
873a72
+		goto cleanup;
873a72
+	}
873a72
+
873a72
+	ret = 0;
873a72
+ cleanup:
873a72
+ 	gnutls_pk_params_clear(&pub;;
873a72
+ 	gnutls_pk_params_clear(&priv;;
873a72
+ 	return ret;
873a72
+}
873a72
+#endif
873a72
+
873a72
+
873a72
 /* To generate a DH key either q must be set in the params or
873a72
  * level should be set to the number of required bits.
873a72
  */
873a72
@@ -1398,12 +1641,12 @@ static int calc_rsa_exp(gnutls_pk_params_st * params)
873a72
 {
873a72
 	bigint_t tmp;
873a72
 	int ret;
873a72
-	
873a72
+
873a72
 	if (params->params_nr < RSA_PRIVATE_PARAMS - 2) {
873a72
 		gnutls_assert();
873a72
 		return GNUTLS_E_INTERNAL_ERROR;
873a72
 	}
873a72
-	
873a72
+
873a72
 	params->params[6] = params->params[7] = NULL;
873a72
 
873a72
 	ret = _gnutls_mpi_init_multi(&tmp, &params->params[6], &params->params[7], NULL);