summaryrefslogtreecommitdiff
path: root/lib/nettle/pk.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nettle/pk.c')
-rw-r--r--lib/nettle/pk.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index b6bb735566..42d540cb46 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -242,6 +242,7 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
gnutls_datum_t * out,
const gnutls_pk_params_st * priv,
const gnutls_pk_params_st * pub,
+ const gnutls_datum_t * nonce,
unsigned int flags)
{
int ret;
@@ -252,6 +253,9 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
bigint_t k = NULL, ff = NULL, r = NULL;
unsigned int bits;
+ if (nonce != NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
f = pub->params[DH_Y];
x = priv->params[DH_X];
q = priv->params[DH_Q];
@@ -343,6 +347,9 @@ dh_cleanup:
out->data = NULL;
+ if (nonce != NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
curve = get_supported_nist_curve(priv->curve);
if (curve == NULL)
return
@@ -384,6 +391,9 @@ dh_cleanup:
{
unsigned size = gnutls_ecc_curve_get_size(priv->curve);
+ if (nonce != NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
/* The point is in pub, while the private part (scalar) in priv. */
if (size == 0 || priv->raw_priv.size != size)
@@ -407,6 +417,57 @@ dh_cleanup:
}
break;
}
+#if ENABLE_GOST
+ case GNUTLS_PK_GOST_01:
+ case GNUTLS_PK_GOST_12_256:
+ case GNUTLS_PK_GOST_12_512:
+ {
+ struct ecc_scalar ecc_priv;
+ struct ecc_point ecc_pub;
+ const struct ecc_curve *curve;
+
+ out->data = NULL;
+
+ curve = get_supported_gost_curve(priv->curve);
+ if (curve == NULL)
+ return
+ gnutls_assert_val
+ (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
+
+ if (nonce == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ ret = _gost_params_to_pubkey(pub, &ecc_pub, curve);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = _gost_params_to_privkey(priv, &ecc_priv, curve);
+ if (ret < 0) {
+ ecc_point_clear(&ecc_pub);
+ return gnutls_assert_val(ret);
+ }
+
+ out->size = 2 * gnutls_ecc_curve_get_size(priv->curve);
+ out->data = gnutls_malloc(out->size);
+ if (out->data == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto gost_cleanup;
+ }
+
+ out->size = gostdsa_vko(&ecc_priv, &ecc_pub,
+ nonce->size, nonce->data,
+ out->size, out->data);
+ if (out->size == 0)
+ ret = GNUTLS_E_INVALID_REQUEST;
+
+ gost_cleanup:
+ ecc_point_clear(&ecc_pub);
+ ecc_scalar_zclear(&ecc_priv);
+ if (ret < 0)
+ goto cleanup;
+ break;
+ }
+#endif
default:
gnutls_assert();
ret = GNUTLS_E_INTERNAL_ERROR;