diff options
author | Werner Koch <wk@gnupg.org> | 2013-09-30 20:17:05 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-09-30 20:44:50 +0200 |
commit | c325adb8f5092b80a626bd3bb5e49cf7f3a29fc8 (patch) | |
tree | 256b90ac9ca14a4c6838ac4d361a1da0742dac75 /cipher/ecc.c | |
parent | d69a13d3d1c14ad6a6aa7cd349d6d2dfb152d422 (diff) | |
download | libgcrypt-c325adb8f5092b80a626bd3bb5e49cf7f3a29fc8.tar.gz |
ecc: Fix recomputing of Q for Ed25519.
* cipher/ecc-misc.c (reverse_buffer): New.
(_gcry_ecc_compute_public): Add ED255519 specific code.
* cipher/ecc.c (sign_eddsa): Allocate DIGEST in secure memory. Get
rid of HASH_D.
* tests/t-mpi-point.c (context_param): Test recomputing of Q for
Ed25519.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/ecc.c')
-rw-r--r-- | cipher/ecc.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/cipher/ecc.c b/cipher/ecc.c index abd501f7..a7fb90f1 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -909,8 +909,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, mpi_ec_t ctx = NULL; int b; unsigned int tmp; - unsigned char hash_d[64]; /* Fixme: malloc in secure memory */ - unsigned char digest[64]; + unsigned char *digest; gcry_buffer_t hvec[3]; const void *mbuf; size_t mlen; @@ -938,37 +937,41 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, r = mpi_new (0); ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, skey->E.p, skey->E.a, skey->E.b); - b = ctx->nbits/8; + b = (ctx->nbits+7)/8; if (b != 256/8) return GPG_ERR_INTERNAL; /* We only support 256 bit. */ + digest = gcry_calloc_secure (2, b); + if (!digest) + { + rc = gpg_err_code_from_syserror (); + goto leave; + } - /* Hash the secret key. We clear DIGEST so we can use it to left - pad the key with zeroes for hashing. */ + /* Hash the secret key. We clear DIGEST so we can use it as input + to left pad the key with zeroes for hashing. */ rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL); if (!rawmpi) { rc = gpg_err_code_from_syserror (); goto leave; } - memset (digest, 0, b); hvec[0].data = digest; hvec[0].off = 0; hvec[0].len = b > rawmpilen? b - rawmpilen : 0; hvec[1].data = rawmpi; hvec[1].off = 0; hvec[1].len = rawmpilen; - rc = _gcry_md_hash_buffers (hashalgo, 0, hash_d, hvec, 2); + rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2); gcry_free (rawmpi); rawmpi = NULL; if (rc) goto leave; - /* Compute the A value (this modifies hash_d). */ - reverse_buffer (hash_d, 32); /* Only the first half of the hash. */ - hash_d[0] = (hash_d[0] & 0x7f) | 0x40; - hash_d[31] &= 0xf8; - _gcry_mpi_set_buffer (a, hash_d, 32, 0); - /* log_printmpi (" a", a); */ + /* Compute the A value (this modifies DIGEST). */ + reverse_buffer (digest, 32); /* Only the first half of the hash. */ + digest[0] = (digest[0] & 0x7f) | 0x40; + digest[31] &= 0xf8; + _gcry_mpi_set_buffer (a, digest, 32, 0); /* Compute the public key if it has not been supplied as optional parameter. */ @@ -1001,7 +1004,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, if (DBG_CIPHER) log_printhex (" m", mbuf, mlen); - hvec[0].data = hash_d; + hvec[0].data = digest; hvec[0].off = 32; hvec[0].len = 32; hvec[1].data = (char*)mbuf; @@ -1063,6 +1066,7 @@ sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (r); + gcry_free (digest); _gcry_mpi_ec_free (ctx); point_free (&I); point_free (&Q); |