Add crypto hash SM3.
[libgcrypt.git] / cipher / ecc-ecdsa.c
index 7663623..1484830 100644 (file)
@@ -42,7 +42,7 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
                       gcry_mpi_t r, gcry_mpi_t s,
                       int flags, int hashalgo)
 {
-  gpg_err_code_t err = 0;
+  gpg_err_code_t rc = 0;
   int extraloops = 0;
   gcry_mpi_t k, dr, sum, k_1, x;
   mpi_point_struct I;
@@ -57,19 +57,9 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
   qbits = mpi_get_nbits (skey->E.n);
 
   /* Convert the INPUT into an MPI if needed.  */
-  if (mpi_is_opaque (input))
-    {
-      abuf = gcry_mpi_get_opaque (input, &abits);
-      err = gpg_err_code (gcry_mpi_scan (&hash, GCRYMPI_FMT_USG,
-                                         abuf, (abits+7)/8, NULL));
-      if (err)
-        return err;
-      if (abits > qbits)
-        gcry_mpi_rshift (hash, hash, abits - qbits);
-    }
-  else
-    hash = input;
-
+  rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+  if (rc)
+    return rc;
 
   k = NULL;
   dr = mpi_alloc (0);
@@ -98,15 +88,15 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
                  used as h1 from 3.2.a.  */
               if (!mpi_is_opaque (input))
                 {
-                  err = GPG_ERR_CONFLICT;
+                  rc = GPG_ERR_CONFLICT;
                   goto leave;
                 }
 
-              abuf = gcry_mpi_get_opaque (input, &abits);
-              err = _gcry_dsa_gen_rfc6979_k (&k, skey->E.n, skey->d,
-                                             abuf, (abits+7)/8,
-                                             hashalgo, extraloops);
-              if (err)
+              abuf = mpi_get_opaque (input, &abits);
+              rc = _gcry_dsa_gen_rfc6979_k (&k, skey->E.n, skey->d,
+                                            abuf, (abits+7)/8,
+                                            hashalgo, extraloops);
+              if (rc)
                 goto leave;
               extraloops++;
             }
@@ -118,7 +108,7 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
             {
               if (DBG_CIPHER)
                 log_debug ("ecc sign: Failed to get affine coordinates\n");
-              err = GPG_ERR_BAD_SIGNATURE;
+              rc = GPG_ERR_BAD_SIGNATURE;
               goto leave;
             }
           mpi_mod (r, x, skey->E.n);  /* r = x mod n */
@@ -150,7 +140,7 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
   if (hash != input)
     mpi_free (hash);
 
-  return err;
+  return rc;
 }
 
 
@@ -162,15 +152,21 @@ _gcry_ecc_ecdsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
                         gcry_mpi_t r, gcry_mpi_t s)
 {
   gpg_err_code_t err = 0;
-  gcry_mpi_t h, h1, h2, x;
+  gcry_mpi_t hash, h, h1, h2, x;
   mpi_point_struct Q, Q1, Q2;
   mpi_ec_t ctx;
+  unsigned int nbits;
 
   if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
     return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n  failed.  */
   if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
     return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n  failed.  */
 
+  nbits = mpi_get_nbits (pkey->E.n);
+  err = _gcry_dsa_normalize_hash (input, &hash, nbits);
+  if (err)
+    return err;
+
   h  = mpi_alloc (0);
   h1 = mpi_alloc (0);
   h2 = mpi_alloc (0);
@@ -185,7 +181,7 @@ _gcry_ecc_ecdsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
   /* h  = s^(-1) (mod n) */
   mpi_invm (h, s, pkey->E.n);
   /* h1 = hash * s^(-1) (mod n) */
-  mpi_mulm (h1, input, h, pkey->E.n);
+  mpi_mulm (h1, hash, h, pkey->E.n);
   /* Q1 = [ hash * s^(-1) ]G  */
   _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
   /* h2 = r * s^(-1) (mod n) */
@@ -231,5 +227,8 @@ _gcry_ecc_ecdsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
   mpi_free (h2);
   mpi_free (h1);
   mpi_free (h);
+  if (hash != input)
+    mpi_free (hash);
+
   return err;
 }