summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2021-09-10 15:32:14 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2021-09-10 15:32:14 +0900
commitb7b0b518982280e34eaf86725daf9dd976aac0b5 (patch)
tree57d925a7b24962d56ec3fbfae68898422febea17
parent5122f548af4df146a2fb235f4fc1364c489075d5 (diff)
downloadlibgcrypt-b7b0b518982280e34eaf86725daf9dd976aac0b5.tar.gz
cipher:dsa: Support supplying K by "label".
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--cipher/dsa.c34
-rw-r--r--cipher/pubkey-util.c25
2 files changed, 52 insertions, 7 deletions
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 2cf3f0ee..f1d30ad8 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -133,7 +133,8 @@ static gpg_err_code_t generate (DSA_secret_key *sk,
int transient_key,
dsa_domain_t *domain,
gcry_mpi_t **ret_factors);
-static gpg_err_code_t sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+static gpg_err_code_t sign (gcry_mpi_t r, gcry_mpi_t s,
+ gcry_mpi_t input, gcry_mpi_t k,
DSA_secret_key *skey, int flags, int hashalgo);
static gpg_err_code_t verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
DSA_public_key *pkey, int flags, int hashalgo);
@@ -182,7 +183,7 @@ test_keys (DSA_secret_key *sk, unsigned int qbits)
_gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
/* Sign DATA using the secret key. */
- sign (sig_a, sig_b, data, sk, 0, 0);
+ sign (sig_a, sig_b, data, NULL, sk, 0, 0);
/* Verify the signature using the public key. */
if ( verify (sig_a, sig_b, data, &pk, 0, 0) )
@@ -580,13 +581,16 @@ check_secret_key( DSA_secret_key *sk )
internally converted to a plain MPI. FLAGS and HASHALGO may both
be 0 for standard operation mode.
+ The random value, K_SUPPLIED, may be supplied externally. If not,
+ it is generated internally.
+
The return value is 0 on success or an error code. Note that for
backward compatibility the function will not return any error if
FLAGS and HASHALGO are both 0 and INPUT is a plain MPI.
*/
static gpg_err_code_t
-sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey,
- int flags, int hashalgo)
+sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, gcry_mpi_t k_supplied,
+ DSA_secret_key *skey, int flags, int hashalgo)
{
gpg_err_code_t rc;
gcry_mpi_t hash;
@@ -617,8 +621,10 @@ sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey,
}
again:
+ if (k_supplied)
+ k = k_supplied;
/* Create the K value. */
- if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
+ else if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
{
/* Use Pornin's method for deterministic DSA. If this flag is
set, it is expected that HASH is an opaque MPI with the to be
@@ -657,12 +663,19 @@ sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey,
mpi_add( tmp, tmp, hash );
mpi_mulm( s , kinv, tmp, skey->q );
- mpi_free(k);
+ if (!k_supplied)
+ mpi_free(k);
mpi_free(kinv);
mpi_free(tmp);
if (!mpi_cmp_ui (r, 0))
{
+ if (k_supplied)
+ {
+ rc = GPG_ERR_INV_VALUE;
+ goto leave;
+ }
+
/* This is a highly unlikely code path. */
extraloops++;
goto again;
@@ -1049,6 +1062,7 @@ dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
gcry_err_code_t rc;
struct pk_encoding_ctx ctx;
gcry_mpi_t data = NULL;
+ gcry_mpi_t k = NULL;
DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
gcry_mpi_t sig_r = NULL;
gcry_mpi_t sig_s = NULL;
@@ -1063,6 +1077,11 @@ dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
if (DBG_CIPHER)
log_mpidump ("dsa_sign data", data);
+ if (ctx.label)
+ rc = _gcry_mpi_scan (&k, GCRYMPI_FMT_USG, ctx.label, ctx.labellen, NULL);
+ if (rc)
+ goto leave;
+
/* Extract the key. */
rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
&sk.p, &sk.q, &sk.g, &sk.y, &sk.x, NULL);
@@ -1080,7 +1099,7 @@ dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
sig_r = mpi_new (0);
sig_s = mpi_new (0);
- rc = sign (sig_r, sig_s, data, &sk, ctx.flags, ctx.hash_algo);
+ rc = sign (sig_r, sig_s, data, k, &sk, ctx.flags, ctx.hash_algo);
if (rc)
goto leave;
if (DBG_CIPHER)
@@ -1099,6 +1118,7 @@ dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
_gcry_mpi_release (sk.y);
_gcry_mpi_release (sk.x);
_gcry_mpi_release (data);
+ _gcry_mpi_release (k);
_gcry_pk_util_free_encoding_ctx (&ctx);
if (DBG_CIPHER)
log_debug ("dsa_sign => %s\n", gpg_strerror (rc));
diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c
index d377932b..7c3f8a47 100644
--- a/cipher/pubkey-util.c
+++ b/cipher/pubkey-util.c
@@ -845,6 +845,31 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
goto leave;
}
+ /* Get optional LABEL. */
+ list = sexp_find_token (ldata, "label", 0);
+ if (list)
+ {
+ s = sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = xtrymalloc (n);
+ if (!ctx->label)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ else
+ rc = GPG_ERR_INV_ARG;
+ sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
if ( !(value=sexp_nth_buffer (lvalue, 1, &valuelen)) || !valuelen )
rc = GPG_ERR_INV_OBJ;
else if ((valuelen * 8) < valuelen)