123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- /* dsa-common.c - Common code for DSA
- * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
- * Copyright (C) 2013 g10 Code GmbH
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
- #include <config.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "g10lib.h"
- #include "mpi.h"
- #include "cipher.h"
- #include "pubkey-internal.h"
- /*
- * Modify K, so that computation time difference can be small,
- * by making K large enough.
- *
- * Originally, (EC)DSA computation requires k where 0 < k < q. Here,
- * we add q (the order), to keep k in a range: q < k < 2*q (or,
- * addming more q, to keep k in a range: 2*q < k < 3*q), so that
- * timing difference of the EC multiply (or exponentiation) operation
- * can be small. The result of (EC)DSA computation is same.
- */
- void
- _gcry_dsa_modify_k (gcry_mpi_t k, gcry_mpi_t q, int qbits)
- {
- gcry_mpi_t k1 = mpi_new (qbits+2);
- mpi_resize (k, (qbits+2+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB);
- k->nlimbs = k->alloced;
- mpi_add (k, k, q);
- mpi_add (k1, k, q);
- mpi_set_cond (k, k1, !mpi_test_bit (k, qbits));
- mpi_free (k1);
- }
- /*
- * Generate a random secret exponent K less than Q.
- * Note that ECDSA uses this code also to generate D.
- */
- gcry_mpi_t
- _gcry_dsa_gen_k (gcry_mpi_t q, int security_level)
- {
- gcry_mpi_t k = mpi_alloc_secure (mpi_get_nlimbs (q));
- unsigned int nbits = mpi_get_nbits (q);
- unsigned int nbytes = (nbits+7)/8;
- char *rndbuf = NULL;
- /* To learn why we don't use mpi_mod to get the requested bit size,
- read the paper: "The Insecurity of the Digital Signature
- Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
- Journal of Cryptology, New York. Vol 15, nr 3 (2003) */
- if (DBG_CIPHER)
- log_debug ("choosing a random k of %u bits at seclevel %d\n",
- nbits, security_level);
- for (;;)
- {
- if ( !rndbuf || nbits < 32 )
- {
- xfree (rndbuf);
- rndbuf = _gcry_random_bytes_secure (nbytes, security_level);
- }
- else
- { /* Change only some of the higher bits. We could improve
- this by directly requesting more memory at the first call
- to get_random_bytes() and use these extra bytes here.
- However the required management code is more complex and
- thus we better use this simple method. */
- char *pp = _gcry_random_bytes_secure (4, security_level);
- memcpy (rndbuf, pp, 4);
- xfree (pp);
- }
- _gcry_mpi_set_buffer (k, rndbuf, nbytes, 0);
- /* Make sure we have the requested number of bits. This code
- looks a bit funny but it is easy to understand if you
- consider that mpi_set_highbit clears all higher bits. We
- don't have a clear_highbit, thus we first set the high bit
- and then clear it again. */
- if (mpi_test_bit (k, nbits-1))
- mpi_set_highbit (k, nbits-1);
- else
- {
- mpi_set_highbit (k, nbits-1);
- mpi_clear_bit (k, nbits-1);
- }
- if (!(mpi_cmp (k, q) < 0)) /* check: k < q */
- {
- if (DBG_CIPHER)
- log_debug ("\tk too large - again\n");
- continue; /* no */
- }
- if (!(mpi_cmp_ui (k, 0) > 0)) /* check: k > 0 */
- {
- if (DBG_CIPHER)
- log_debug ("\tk is zero - again\n");
- continue; /* no */
- }
- break; /* okay */
- }
- xfree (rndbuf);
- return k;
- }
- /* Turn VALUE into an octet string and store it in an allocated buffer
- at R_FRAME. If the resulting octet string is shorter than NBYTES
- the result will be left padded with zeroes. If VALUE does not fit
- into NBYTES an error code is returned. */
- static gpg_err_code_t
- int2octets (unsigned char **r_frame, gcry_mpi_t value, size_t nbytes)
- {
- gpg_err_code_t rc;
- size_t nframe, noff, n;
- unsigned char *frame;
- rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
- if (rc)
- return rc;
- if (nframe > nbytes)
- return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */
- noff = (nframe < nbytes)? nbytes - nframe : 0;
- n = nframe + noff;
- frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
- if (!frame)
- return gpg_err_code_from_syserror ();
- if (noff)
- memset (frame, 0, noff);
- nframe += noff;
- rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
- if (rc)
- {
- xfree (frame);
- return rc;
- }
- *r_frame = frame;
- return 0;
- }
- /* Connert the bit string BITS of length NBITS into an octet string
- with a length of (QBITS+7)/8 bytes. On success store the result at
- R_FRAME. */
- static gpg_err_code_t
- bits2octets (unsigned char **r_frame,
- const void *bits, unsigned int nbits,
- gcry_mpi_t q, unsigned int qbits)
- {
- gpg_err_code_t rc;
- gcry_mpi_t z1;
- /* z1 = bits2int (b) */
- rc = _gcry_mpi_scan (&z1, GCRYMPI_FMT_USG, bits, (nbits+7)/8, NULL);
- if (rc)
- return rc;
- if (nbits > qbits)
- mpi_rshift (z1, z1, nbits - qbits);
- /* z2 - z1 mod q */
- if (mpi_cmp (z1, q) >= 0)
- mpi_sub (z1, z1, q);
- /* Convert to an octet string. */
- rc = int2octets (r_frame, z1, (qbits+7)/8);
- mpi_free (z1);
- return rc;
- }
- /*
- * Generate a deterministic secret exponent K less than DSA_Q. H1 is
- * the to be signed digest with a length of HLEN bytes. HALGO is the
- * algorithm used to create the hash. On success the value for K is
- * stored at R_K.
- */
- gpg_err_code_t
- _gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k,
- gcry_mpi_t dsa_q, gcry_mpi_t dsa_x,
- const unsigned char *h1, unsigned int hlen,
- int halgo, unsigned int extraloops)
- {
- gpg_err_code_t rc;
- unsigned char *V = NULL;
- unsigned char *K = NULL;
- unsigned char *x_buf = NULL;
- unsigned char *h1_buf = NULL;
- gcry_md_hd_t hd = NULL;
- unsigned char *t = NULL;
- gcry_mpi_t k = NULL;
- unsigned int tbits, qbits;
- int i;
- qbits = mpi_get_nbits (dsa_q);
- if (!qbits || !h1 || !hlen)
- return GPG_ERR_EINVAL;
- if (_gcry_md_get_algo_dlen (halgo) != hlen)
- return GPG_ERR_DIGEST_ALGO;
- /* Step b: V = 0x01 0x01 0x01 ... 0x01 */
- V = xtrymalloc (hlen);
- if (!V)
- {
- rc = gpg_err_code_from_syserror ();
- goto leave;
- }
- for (i=0; i < hlen; i++)
- V[i] = 1;
- /* Step c: K = 0x00 0x00 0x00 ... 0x00 */
- K = xtrycalloc (1, hlen);
- if (!K)
- {
- rc = gpg_err_code_from_syserror ();
- goto leave;
- }
- rc = int2octets (&x_buf, dsa_x, (qbits+7)/8);
- if (rc)
- goto leave;
- rc = bits2octets (&h1_buf, h1, hlen*8, dsa_q, qbits);
- if (rc)
- goto leave;
- /* Create a handle to compute the HMACs. */
- rc = _gcry_md_open (&hd, halgo, (GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC));
- if (rc)
- goto leave;
- /* Step d: K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- _gcry_md_write (hd, "", 1);
- _gcry_md_write (hd, x_buf, (qbits+7)/8);
- _gcry_md_write (hd, h1_buf, (qbits+7)/8);
- memcpy (K, _gcry_md_read (hd, 0), hlen);
- /* Step e: V = HMAC_K(V) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- memcpy (V, _gcry_md_read (hd, 0), hlen);
- /* Step f: K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- _gcry_md_write (hd, "\x01", 1);
- _gcry_md_write (hd, x_buf, (qbits+7)/8);
- _gcry_md_write (hd, h1_buf, (qbits+7)/8);
- memcpy (K, _gcry_md_read (hd, 0), hlen);
- /* Step g: V = HMAC_K(V) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- memcpy (V, _gcry_md_read (hd, 0), hlen);
- /* Step h. */
- t = xtrymalloc_secure ((qbits+7)/8+hlen);
- if (!t)
- {
- rc = gpg_err_code_from_syserror ();
- goto leave;
- }
- again:
- for (tbits = 0; tbits < qbits;)
- {
- /* V = HMAC_K(V) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- memcpy (V, _gcry_md_read (hd, 0), hlen);
- /* T = T || V */
- memcpy (t+(tbits+7)/8, V, hlen);
- tbits += 8*hlen;
- }
- /* k = bits2int (T) */
- mpi_free (k);
- k = NULL;
- rc = _gcry_mpi_scan (&k, GCRYMPI_FMT_USG, t, (tbits+7)/8, NULL);
- if (rc)
- goto leave;
- if (tbits > qbits)
- mpi_rshift (k, k, tbits - qbits);
- /* Check: k < q and k > 1 */
- if (!(mpi_cmp (k, dsa_q) < 0 && mpi_cmp_ui (k, 0) > 0))
- {
- /* K = HMAC_K(V || 0x00) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- _gcry_md_write (hd, "", 1);
- memcpy (K, _gcry_md_read (hd, 0), hlen);
- /* V = HMAC_K(V) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- memcpy (V, _gcry_md_read (hd, 0), hlen);
- goto again;
- }
- /* The caller may have requested that we introduce some extra loops.
- This is for example useful if the caller wants another value for
- K because the last returned one yielded an R of 0. Because this
- is very unlikely we implement it in a straightforward way. */
- if (extraloops)
- {
- extraloops--;
- /* K = HMAC_K(V || 0x00) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- _gcry_md_write (hd, "", 1);
- memcpy (K, _gcry_md_read (hd, 0), hlen);
- /* V = HMAC_K(V) */
- rc = _gcry_md_setkey (hd, K, hlen);
- if (rc)
- goto leave;
- _gcry_md_write (hd, V, hlen);
- memcpy (V, _gcry_md_read (hd, 0), hlen);
- goto again;
- }
- /* log_mpidump (" k", k); */
- leave:
- xfree (t);
- _gcry_md_close (hd);
- xfree (h1_buf);
- xfree (x_buf);
- xfree (K);
- xfree (V);
- if (rc)
- mpi_free (k);
- else
- *r_k = k;
- return rc;
- }
- /*
- * For DSA/ECDSA, as prehash function, compute hash with HASHALGO for
- * INPUT. Result hash value is returned in R_HASH as an opaque MPI.
- * Returns error code.
- */
- gpg_err_code_t
- _gcry_dsa_compute_hash (gcry_mpi_t *r_hash, gcry_mpi_t input, int hashalgo)
- {
- gpg_err_code_t rc = 0;
- size_t hlen;
- void *hashbuf;
- void *abuf;
- unsigned int abits;
- unsigned int n;
- hlen = _gcry_md_get_algo_dlen (hashalgo);
- hashbuf = xtrymalloc (hlen);
- if (!hashbuf)
- {
- rc = gpg_err_code_from_syserror ();
- return rc;
- }
- if (mpi_is_opaque (input))
- {
- abuf = mpi_get_opaque (input, &abits);
- n = (abits+7)/8;
- _gcry_md_hash_buffer (hashalgo, hashbuf, abuf, n);
- }
- else
- {
- abits = mpi_get_nbits (input);
- n = (abits+7)/8;
- abuf = xtrymalloc (n);
- if (!abuf)
- {
- rc = gpg_err_code_from_syserror ();
- xfree (hashbuf);
- return rc;
- }
- _gcry_mpi_to_octet_string (NULL, abuf, input, n);
- _gcry_md_hash_buffer (hashalgo, hashbuf, abuf, n);
- xfree (abuf);
- }
- *r_hash = mpi_set_opaque (NULL, hashbuf, hlen*8);
- if (!*r_hash)
- rc = GPG_ERR_INV_OBJ;
- return rc;
- }
- /*
- * Truncate opaque hash value to qbits for DSA.
- * Non-opaque input is not truncated, in hope that user
- * knows what is passed. It is not possible to correctly
- * trucate non-opaque inputs.
- */
- gpg_err_code_t
- _gcry_dsa_normalize_hash (gcry_mpi_t input,
- gcry_mpi_t *out,
- unsigned int qbits)
- {
- gpg_err_code_t rc = 0;
- const void *abuf;
- unsigned int abits;
- gcry_mpi_t hash;
- if (mpi_is_opaque (input))
- {
- abuf = mpi_get_opaque (input, &abits);
- rc = _gcry_mpi_scan (&hash, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
- if (rc)
- return rc;
- if (abits > qbits)
- mpi_rshift (hash, hash, abits - qbits);
- }
- else
- hash = input;
- *out = hash;
- return rc;
- }
|