summaryrefslogtreecommitdiff
path: root/lib/nettle/pk.c
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2019-07-29 14:01:11 +0200
committerDaiki Ueno <dueno@redhat.com>2019-08-08 13:14:46 +0200
commit8eb3a29336ea11f6b417ce7e25d53513509bdd87 (patch)
treee2b29005194ac51d83b540c716088fe32358a6ee /lib/nettle/pk.c
parent3dd0df9e1a499c7b31bf7b4a315e797d2195c1ba (diff)
downloadgnutls-8eb3a29336ea11f6b417ce7e25d53513509bdd87.tar.gz
pk: implement deterministic ECDSA/DSA
This exposes the deterministic ECDSA/DSA functionality through the GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE flag. Signed-off-by: Daiki Ueno <dueno@redhat.com>
Diffstat (limited to 'lib/nettle/pk.c')
-rw-r--r--lib/nettle/pk.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index 08117c2d82..ebd6481cf7 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -54,6 +54,8 @@
#include "gost/gostdsa.h"
#include "gost/ecc-gost-curve.h"
#endif
+#include "int/ecdsa-compute-k.h"
+#include "int/dsa-compute-k.h"
#include <gnettle.h>
#include <fips.h>
@@ -86,6 +88,12 @@ static void rnd_nonce_func(void *_ctx, size_t length, uint8_t * data)
}
}
+static void rnd_mpz_func(void *_ctx, size_t length, uint8_t * data)
+{
+ mpz_t *k = _ctx;
+ nettle_mpz_get_str_256 (length, data, *k);
+}
+
static void
ecc_scalar_zclear (struct ecc_scalar *s)
{
@@ -782,6 +790,9 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_signature sig;
int curve_id = pk_params->curve;
const struct ecc_curve *curve;
+ mpz_t k;
+ void *random_ctx;
+ nettle_random_func *random_func;
curve = get_supported_nist_curve(curve_id);
if (curve == NULL)
@@ -808,7 +819,23 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
hash_len = vdata->size;
}
- ecdsa_sign(&priv, NULL, rnd_nonce_func, hash_len,
+ mpz_init(k);
+ if (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE) {
+ ret = _gnutls_ecdsa_compute_k(k,
+ curve_id,
+ pk_params->params[ECC_K],
+ sign_params->dsa_dig,
+ vdata->data,
+ vdata->size);
+ if (ret < 0)
+ goto ecdsa_cleanup;
+ random_ctx = &k;
+ random_func = rnd_mpz_func;
+ } else {
+ random_ctx = NULL;
+ random_func = rnd_nonce_func;
+ }
+ ecdsa_sign(&priv, random_ctx, random_func, hash_len,
vdata->data, &sig);
/* prevent memory leaks */
@@ -824,6 +851,7 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
ecdsa_cleanup:
dsa_signature_clear(&sig);
ecc_scalar_zclear(&priv);
+ mpz_clear(k);
if (ret < 0) {
gnutls_assert();
@@ -836,6 +864,9 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_params pub;
bigint_t priv;
struct dsa_signature sig;
+ mpz_t k;
+ void *random_ctx;
+ nettle_random_func *random_func;
memset(&priv, 0, sizeof(priv));
memset(&pub, 0, sizeof(pub));
@@ -856,8 +887,26 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
hash_len = vdata->size;
}
+ mpz_init(k);
+ if (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE) {
+ ret = _gnutls_dsa_compute_k(k,
+ pub.q,
+ TOMPZ(priv),
+ sign_params->dsa_dig,
+ vdata->data,
+ vdata->size);
+ if (ret < 0)
+ goto dsa_fail;
+ /* cancel-out dsa_sign's addition of 1 to random data */
+ mpz_sub_ui (k, k, 1);
+ random_ctx = &k;
+ random_func = rnd_mpz_func;
+ } else {
+ random_ctx = NULL;
+ random_func = rnd_nonce_func;
+ }
ret =
- dsa_sign(&pub, TOMPZ(priv), NULL, rnd_nonce_func,
+ dsa_sign(&pub, TOMPZ(priv), random_ctx, random_func,
hash_len, vdata->data, &sig);
if (ret == 0 || HAVE_LIB_ERROR()) {
gnutls_assert();
@@ -871,6 +920,7 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
dsa_fail:
dsa_signature_clear(&sig);
+ mpz_clear(k);
if (ret < 0) {
gnutls_assert();