diff options
Diffstat (limited to 'lib/nettle/pk.c')
-rw-r--r-- | lib/nettle/pk.c | 54 |
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(); |