Return used curve name with ECC key generation
authorWerner Koch <wk@gnupg.org>
Mon, 31 Jan 2011 08:29:20 +0000 (09:29 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 31 Jan 2011 08:29:20 +0000 (09:29 +0100)
cipher/ChangeLog
cipher/ecc.c
cipher/pubkey.c

index 64ddb13..36773ab 100644 (file)
@@ -1,3 +1,7 @@
+2011-01-28  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_genkey): Hack to insert the used curve name.
+
 2011-01-27  Werner Koch  <wk@g10code.com>
 
        * ecc.c (fill_in_curve): Remove.
        readability.  Use ECC_public_key instead of ECC_secret_key.
        Require a caller to pass a complete pkey array.
        (ecc_decrypt_raw): Require a caller to pass a complete skey array.
+       (elliptic_curve_t): Add field NAME.
+       (fill_in_curve): Set field.
+       (generate_key): Add arg R_USED_CURVE.
+       (ecc_generate_ext): Return used curve name.
 
 2011-01-26  Werner Koch  <wk@g10code.com>
 
index ae55f8c..4561749 100644 (file)
@@ -68,6 +68,7 @@ typedef struct
   gcry_mpi_t b;   /* Second coefficient of the Weierstrass equation.  */
   mpi_point_t G;  /* Base point (generator).  */
   gcry_mpi_t n;   /* Order of G.  */
+  const char *name;  /* Name of curve or NULL.  */
 } elliptic_curve_t;
 
 
@@ -465,13 +466,17 @@ fill_in_curve (unsigned int nbits, const char *name,
                elliptic_curve_t *curve, unsigned int *r_nbits)
 {
   int idx, aliasno;
+  const char *resname = NULL; /* Set to a found curve name.  */
 
   if (name)
     {
-      /* First check nor native curves.  */
+      /* First check our native curves.  */
       for (idx = 0; domain_parms[idx].desc; idx++)
         if (!strcmp (name, domain_parms[idx].desc))
-          break;
+          {
+            resname = domain_parms[idx].desc;
+            break;
+          }
       /* If not found consult the alias table.  */
       if (!domain_parms[idx].desc)
         {
@@ -483,7 +488,10 @@ fill_in_curve (unsigned int nbits, const char *name,
               for (idx = 0; domain_parms[idx].desc; idx++)
                 if (!strcmp (curve_aliases[aliasno].name,
                              domain_parms[idx].desc))
-                  break;
+                  {
+                    resname = domain_parms[idx].desc;
+                    break;
+                  }
             }
         }
     }
@@ -510,6 +518,7 @@ fill_in_curve (unsigned int nbits, const char *name,
   curve->G.x = scanval (domain_parms[idx].g_x);
   curve->G.y = scanval (domain_parms[idx].g_y);
   curve->G.z = mpi_alloc_set_ui (1);
+  curve->name = resname;
 
   return 0;
 }
@@ -523,7 +532,8 @@ static gpg_err_code_t
 generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
               int transient_key,
               gcry_mpi_t g_x, gcry_mpi_t g_y,
-              gcry_mpi_t q_x, gcry_mpi_t q_y)
+              gcry_mpi_t q_x, gcry_mpi_t q_y,
+              const char **r_usedcurve)
 {
   gpg_err_code_t err;
   elliptic_curve_t E;
@@ -532,6 +542,8 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
   mpi_ec_t ctx;
   gcry_random_level_t random_level;
 
+  *r_usedcurve = NULL;
+
   err = fill_in_curve (nbits, name, &E, &nbits);
   if (err)
     return err;
@@ -544,7 +556,9 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
       log_mpidump ("ecgen curve  n", E.n);
       log_mpidump ("ecgen curve Gx", E.G.x);
       log_mpidump ("ecgen curve Gy", E.G.y);
-      log_mpidump ("ecgen cyrve Gz", E.G.z);
+      log_mpidump ("ecgen curve Gz", E.G.z);
+      if (E.name)
+        log_debug   ("ecgen curve used: %s\n", E.name);
     }
 
   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
@@ -584,6 +598,8 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
 
   point_free (&Q);
   mpi_free (d);
+
+  *r_usedcurve = E.name;
   curve_free (&E);
 
   /* Now we can test our keys (this should never fail!).  */
@@ -992,10 +1008,10 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
   char *curve_name = NULL;
   gcry_sexp_t l1;
   int transient_key = 0;
+  const char *usedcurve = NULL;
 
   (void)algo;
   (void)evalue;
-  (void)r_extrainfo;
 
   if (genparms)
     {
@@ -1026,10 +1042,13 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
   g_y = mpi_new (0);
   q_x = mpi_new (0);
   q_y = mpi_new (0);
-  ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y);
+  ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y,
+                     &usedcurve);
   gcry_free (curve_name);
   if (ec)
     return ec;
+  if (usedcurve)  /* Fixme: No error return checking.  */
+    gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve);
 
   skey[0] = sk.E.p;
   skey[1] = sk.E.a;
@@ -1050,7 +1069,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
   /* Make an empty list of factors.  */
   *retfactors = gcry_calloc ( 1, sizeof **retfactors );
   if (!*retfactors)
-    return gpg_err_code_from_syserror ();
+    return gpg_err_code_from_syserror ();  /* Fixme: relase mem?  */
 
   if (DBG_CIPHER)
     {
@@ -1659,7 +1678,7 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
 gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
   {
     "ECDH", ecdh_names,
-    "pabgnq", "pabgnqd", "", "rs", "pabgnq",
+    "pabgnq", "pabgnqd", "rs", "", "pabgnq",
     GCRY_PK_USAGE_ENCR,
     ecc_generate,
     ecc_check_secret_key,
index 2861d29..d540866 100644 (file)
@@ -2078,7 +2078,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   char *name = NULL;
   size_t n;
   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-  int i;
+  int i, j;
   const char *algo_name = NULL;
   int algo;
   const char *sec_elems = NULL, *pub_elems = NULL;
@@ -2196,6 +2196,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
     char *string, *p;
     size_t nelem=0, nelem_cp = 0, needed=0;
     gcry_mpi_t mpis[30];
+    int percent_s_idx = -1;
     
     /* Estimate size of format string.  */
     nelem = strlen (pub_elems) + strlen (sec_elems);
@@ -2230,6 +2231,13 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
         p = stpcpy (p, "%m)");
         mpis[nelem++] = skey[i];
       }
+    if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
+      {
+        /* Very ugly hack to insert the used curve parameter into the
+           list of public key parameters.  */
+        percent_s_idx = nelem;
+        p = stpcpy (p, "%S");
+      }
     p = stpcpy (p, "))");
     p = stpcpy (p, "(private-key(");
     p = stpcpy (p, algo_name);
@@ -2245,7 +2253,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
     /* Hack to make release_mpi_array() work.  */
     skey[i] = NULL;
 
-    if (extrainfo)
+    if (extrainfo && percent_s_idx == -1)
       {
         /* If we have extrainfo we should not have any factors.  */
         p = stpcpy (p, "%S");
@@ -2266,6 +2274,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
     while (nelem < DIM (mpis))
       mpis[nelem++] = NULL;
 
+    log_debug ("-->%s<-- %d\n", string, percent_s_idx);
     {
       int elem_n = strlen (pub_elems) + strlen (sec_elems);
       void **arg_list;
@@ -2277,16 +2286,19 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
           rc = gpg_err_code_from_errno (errno);
           goto leave;
         }
-      for (i = 0; i < elem_n; i++)
-        arg_list[i] = mpis + i;
-      if (extrainfo)
-        arg_list[i] = &extrainfo;
+      for (i = j = 0; i < elem_n; i++)
+        {
+          if (i == percent_s_idx)
+            arg_list[j++] = &extrainfo;
+          arg_list[j++] = mpis + i;
+        }
+      if (extrainfo && percent_s_idx == -1)
+        arg_list[j] = &extrainfo;
       else if (factors && factors[0])
         {
           for (; i < nelem_cp; i++)
-            arg_list[i] = factors + i - elem_n;
+            arg_list[j++] = factors + i - elem_n;
         }
-      
       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
       gcry_free (arg_list);
       if (rc)