[git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-353-gf09ffe8

by Werner Koch cvs at cvs.gnupg.org
Tue Nov 5 17:31:45 CET 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".

The branch, master has been updated
       via  f09ffe8a4802af65a116e79eceeb1cb4ed4fa2f4 (commit)
       via  630aca794ddf057fb7265b7dc346374743036af4 (commit)
      from  d50a88d1e29124d038196fec6082fd093e922604 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f09ffe8a4802af65a116e79eceeb1cb4ed4fa2f4
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Nov 5 17:25:02 2013 +0100

    ecc: Fully implement Ed25519 compression in ECDSA mode.
    
    * src/ec-context.h (mpi_ec_ctx_s): Add field FLAGS.
    * mpi/ec.c (ec_p_init): Add arg FLAGS.  Change all callers to pass it.
    * cipher/ecc-curves.c (point_from_keyparam): Add arg EC, parse as
     opaque mpi and use eddsa decoding depending on the flag.
    (_gcry_mpi_ec_new): Rearrange to parse Q and D after knowing the
    curve.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index fb0db3b..1bd3679 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
@@ -545,28 +545,36 @@ mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name)
 /* Helper to extract a point from key parameters.  If no parameter
    with NAME is found, the functions tries to find a non-encoded point
    by appending ".x", ".y" and ".z" to NAME.  ".z" is in this case
-   optional and defaults to 1.  */
+   optional and defaults to 1.  EC is the context which at this point
+   may not be fully initialized. */
 static gpg_err_code_t
 point_from_keyparam (gcry_mpi_point_t *r_a,
-                     gcry_sexp_t keyparam, const char *name)
+                     gcry_sexp_t keyparam, const char *name, mpi_ec_t ec)
 {
-  gcry_err_code_t ec;
-  gcry_mpi_t a = NULL;
+  gcry_err_code_t rc;
+  gcry_sexp_t l1;
   gcry_mpi_point_t point;
 
-  ec = mpi_from_keyparam (&a, keyparam, name);
-  if (ec)
-    return ec;
-
-  if (a)
+  l1 = gcry_sexp_find_token (keyparam, name, 0);
+  if (l1)
     {
+      gcry_mpi_t a;
+
+      a = _gcry_sexp_nth_opaque_mpi (l1, 1);
+      gcry_sexp_release (l1);
+      if (!a)
+        return GPG_ERR_INV_OBJ;
+
       point = gcry_mpi_point_new (0);
-      ec = _gcry_ecc_os2ec (point, a);
+      if (ec && ec->dialect == ECC_DIALECT_ED25519)
+        rc = _gcry_ecc_eddsa_decodepoint (a, ec, point, NULL, NULL);
+      else
+        rc = _gcry_ecc_os2ec (point, a);
       mpi_free (a);
-      if (ec)
+      if (rc)
         {
           gcry_mpi_point_release (point);
-          return ec;
+          return rc;
         }
     }
   else
@@ -580,28 +588,28 @@ point_from_keyparam (gcry_mpi_point_t *r_a,
       if (!tmpname)
         return gpg_err_code_from_syserror ();
       strcpy (stpcpy (tmpname, name), ".x");
-      ec = mpi_from_keyparam (&x, keyparam, tmpname);
-      if (ec)
+      rc = mpi_from_keyparam (&x, keyparam, tmpname);
+      if (rc)
         {
           gcry_free (tmpname);
-          return ec;
+          return rc;
         }
       strcpy (stpcpy (tmpname, name), ".y");
-      ec = mpi_from_keyparam (&y, keyparam, tmpname);
-      if (ec)
+      rc = mpi_from_keyparam (&y, keyparam, tmpname);
+      if (rc)
         {
           mpi_free (x);
           gcry_free (tmpname);
-          return ec;
+          return rc;
         }
       strcpy (stpcpy (tmpname, name), ".z");
-      ec = mpi_from_keyparam (&z, keyparam, tmpname);
-      if (ec)
+      rc = mpi_from_keyparam (&z, keyparam, tmpname);
+      if (rc)
         {
           mpi_free (y);
           mpi_free (x);
           gcry_free (tmpname);
-          return ec;
+          return rc;
         }
       if (!z)
         z = mpi_set_ui (NULL, 1);
@@ -645,35 +653,43 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
   gcry_mpi_t n = NULL;
   gcry_mpi_point_t Q = NULL;
   gcry_mpi_t d = NULL;
+  int flags = 0;
   gcry_sexp_t l1;
 
   *r_ctx = NULL;
 
   if (keyparam)
     {
-      errc = mpi_from_keyparam (&p, keyparam, "p");
-      if (errc)
-        goto leave;
-      errc = mpi_from_keyparam (&a, keyparam, "a");
-      if (errc)
-        goto leave;
-      errc = mpi_from_keyparam (&b, keyparam, "b");
-      if (errc)
-        goto leave;
-      errc = point_from_keyparam (&G, keyparam, "g");
-      if (errc)
-        goto leave;
-      errc = mpi_from_keyparam (&n, keyparam, "n");
-      if (errc)
-        goto leave;
-      errc = point_from_keyparam (&Q, keyparam, "q");
-      if (errc)
-        goto leave;
-      errc = mpi_from_keyparam (&d, keyparam, "d");
-      if (errc)
-        goto leave;
-    }
+      /* Parse an optional flags list.  */
+      l1 = gcry_sexp_find_token (keyparam, "flags", 0);
+      if (l1)
+        {
+          errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+          gcry_sexp_release (l1);
+          l1 = NULL;
+          if (errc)
+            goto leave;
+        }
 
+      if (!(flags & PUBKEY_FLAG_NOPARAM))
+        {
+          errc = mpi_from_keyparam (&p, keyparam, "p");
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&a, keyparam, "a");
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&b, keyparam, "b");
+          if (errc)
+            goto leave;
+          errc = point_from_keyparam (&G, keyparam, "g", NULL);
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&n, keyparam, "n");
+          if (errc)
+            goto leave;
+        }
+    }
 
   /* Check whether a curve parameter is available and use that to fill
      in missing values.  If no curve parameter is available try an
@@ -751,7 +767,8 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
       gcry_free (E);
     }
 
-  errc = _gcry_mpi_ec_p_new (&ctx, model, dialect, p, a, b);
+
+  errc = _gcry_mpi_ec_p_new (&ctx, model, dialect, flags, p, a, b);
   if (!errc)
     {
       mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
@@ -771,6 +788,22 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
           ec->n = n;
           n = NULL;
         }
+
+      /* Now that we now the curve name we can look for the public key
+         Q.  point_from_keyparam needs to know the curve parameters so
+         that it is able to use the correct decompression.  Parsing
+         the private key D could have been done earlier but it is less
+         surprising if we do it here as well.  */
+      if (keyparam)
+        {
+          errc = point_from_keyparam (&Q, keyparam, "q", ec);
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&d, keyparam, "d");
+          if (errc)
+            goto leave;
+        }
+
       if (Q)
         {
           ec->Q = Q;
@@ -783,9 +816,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
         }
 
       *r_ctx = ctx;
+      ctx = NULL;
     }
 
  leave:
+  gcry_ctx_release (ctx);
   mpi_free (p);
   mpi_free (a);
   mpi_free (b);
@@ -814,7 +849,10 @@ _gcry_ecc_get_param (const char *name, gcry_mpi_t *pkey)
 
   g_x = mpi_new (0);
   g_y = mpi_new (0);
-  ctx = _gcry_mpi_ec_p_internal_new (0, ECC_DIALECT_STANDARD, E.p, E.a, NULL);
+  ctx = _gcry_mpi_ec_p_internal_new (MPI_EC_WEIERSTRASS,
+                                     ECC_DIALECT_STANDARD,
+                                     0,
+                                     E.p, E.a, NULL);
   if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
     log_fatal ("ecc get param: Failed to get affine coordinates\n");
   _gcry_mpi_ec_free (ctx);
diff --git a/cipher/ecc-ecdsa.c b/cipher/ecc-ecdsa.c
index 70dfe38..7663623 100644
--- a/cipher/ecc-ecdsa.c
+++ b/cipher/ecc-ecdsa.c
@@ -78,7 +78,7 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
   x = mpi_alloc (0);
   point_init (&I);
 
-  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
+  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, 0,
                                      skey->E.p, skey->E.a, skey->E.b);
 
   /* Two loops to avoid R or S are zero.  This is more of a joke than
@@ -179,7 +179,7 @@ _gcry_ecc_ecdsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
   point_init (&Q1);
   point_init (&Q2);
 
-  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
+  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, 0,
                                      pkey->E.p, pkey->E.a, pkey->E.b);
 
   /* h  = s^(-1) (mod n) */
diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c
index 22f2702..d83b7c6 100644
--- a/cipher/ecc-eddsa.c
+++ b/cipher/ecc-eddsa.c
@@ -441,7 +441,7 @@ _gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
   x = mpi_new (0);
   y = mpi_new (0);
   r = mpi_new (0);
-  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
+  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, 0,
                                      skey->E.p, skey->E.a, skey->E.b);
   b = (ctx->nbits+7)/8;
   if (b != 256/8)
@@ -618,7 +618,7 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
   h = mpi_new (0);
   s = mpi_new (0);
 
-  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
+  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, 0,
                                      pkey->E.p, pkey->E.a, pkey->E.b);
   b = ctx->nbits/8;
   if (b != 256/8)
diff --git a/cipher/ecc-gost.c b/cipher/ecc-gost.c
index a40459c..ce3e921 100644
--- a/cipher/ecc-gost.c
+++ b/cipher/ecc-gost.c
@@ -77,7 +77,7 @@ _gcry_ecc_gost_sign (gcry_mpi_t input, ECC_secret_key *skey,
   x = mpi_alloc (0);
   point_init (&I);
 
-  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
+  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, 0,
                                      skey->E.p, skey->E.a, skey->E.b);
 
   mpi_mod (e, input, skey->E.n); /* e = hash mod n */
@@ -164,7 +164,7 @@ _gcry_ecc_gost_verify (gcry_mpi_t input, ECC_public_key *pkey,
   point_init (&Q1);
   point_init (&Q2);
 
-  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
+  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, 0,
                                      pkey->E.p, pkey->E.a, pkey->E.b);
 
   mpi_mod (e, input, pkey->E.n); /* e = hash mod n */
diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c
index fa0bded..6c75e75 100644
--- a/cipher/ecc-misc.c
+++ b/cipher/ecc-misc.c
@@ -26,6 +26,7 @@
 
 #include "g10lib.h"
 #include "mpi.h"
+#include "cipher.h"
 #include "context.h"
 #include "ec-context.h"
 #include "ecc-common.h"
@@ -263,67 +264,62 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec)
   if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b)
     return NULL;
 
-  switch (ec->dialect)
+  if (ec->dialect == ECC_DIALECT_ED25519
+      && !(ec->flags & PUBKEY_FLAG_ECDSA))
     {
-    case ECC_DIALECT_ED25519:
-      {
-        gcry_mpi_t a;
-        unsigned char *rawmpi = NULL;
-        unsigned int rawmpilen;
-        unsigned char *digest;
-        gcry_buffer_t hvec[2];
-        int b = (ec->nbits+7)/8;
-
-        gcry_assert (b >= 32);
-        digest = gcry_calloc_secure (2, b);
-        if (!digest)
+      gcry_mpi_t a;
+      unsigned char *rawmpi = NULL;
+      unsigned int rawmpilen;
+      unsigned char *digest;
+      gcry_buffer_t hvec[2];
+      int b = (ec->nbits+7)/8;
+
+      gcry_assert (b >= 32);
+      digest = gcry_calloc_secure (2, b);
+      if (!digest)
+        return NULL;
+      memset (hvec, 0, sizeof hvec);
+
+      rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL);
+      if (!rawmpi)
+        return NULL;
+      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;
+      /* FIXME: Put and take the hash algo from the context.  */
+      rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, digest, hvec, 2);
+      gcry_free (rawmpi);
+      if (rc)
+        {
+          gcry_free (digest);
           return NULL;
-        memset (hvec, 0, sizeof hvec);
+        }
 
-        rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL);
-        if (!rawmpi)
-          return NULL;
-        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;
-        /* FIXME: Put and take the hash algo from the context.  */
-        rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, digest, hvec, 2);
-        gcry_free (rawmpi);
-        if (rc)
-          {
-            gcry_free (digest);
-            return NULL;
-          }
-
-        /* Compute the A value.  */
-        reverse_buffer (digest, 32);  /* Only the first half of the hash.  */
-        digest[0] = (digest[0] & 0x7f) | 0x40;
-        digest[31] &= 0xf8;
-        a = mpi_snew (0);
-        _gcry_mpi_set_buffer (a, digest, 32, 0);
-        gcry_free (digest);
-
-        /* And finally the public key.  */
-        if (!Q)
-          Q = gcry_mpi_point_new (0);
-        if (Q)
-          _gcry_mpi_ec_mul_point (Q, a, ec->G, ec);
-        mpi_free (a);
-      }
-      break;
-
-    default:
-      {
-        if (!Q)
-          Q = gcry_mpi_point_new (0);
-        if (Q)
-          _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
-      }
-      break;
+      /* Compute the A value.  */
+      reverse_buffer (digest, 32);  /* Only the first half of the hash.  */
+      digest[0] = (digest[0] & 0x7f) | 0x40;
+      digest[31] &= 0xf8;
+      a = mpi_snew (0);
+      _gcry_mpi_set_buffer (a, digest, 32, 0);
+      gcry_free (digest);
+
+      /* And finally the public key.  */
+      if (!Q)
+        Q = gcry_mpi_point_new (0);
+      if (Q)
+        _gcry_mpi_ec_mul_point (Q, a, ec->G, ec);
+      mpi_free (a);
+    }
+  else
+    {
+      if (!Q)
+        Q = gcry_mpi_point_new (0);
+      if (Q)
+        _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec);
     }
 
   return Q;
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 752dfc1..8bc8ea6 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -312,7 +312,7 @@ check_secret_key (ECC_secret_key * sk)
       goto leave;
     }
 
-  ctx = _gcry_mpi_ec_p_internal_new (sk->E.model, sk->E.dialect,
+  ctx = _gcry_mpi_ec_p_internal_new (sk->E.model, sk->E.dialect, 0,
                                      sk->E.p, sk->E.a, sk->E.b);
 
   _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
@@ -469,7 +469,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
   else
     random_level = GCRY_VERY_STRONG_RANDOM;
 
-  ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, E.p, E.a, E.b);
+  ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, 0, E.p, E.a, E.b);
   x = mpi_new (0);
   y = mpi_new (0);
 
@@ -984,7 +984,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
 
           /* Fixme: Factor the curve context setup out of eddsa_verify
              and ecdsa_verify. So that we don't do it twice.  */
-          ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
+          ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
                                             pk.E.p, pk.E.a, pk.E.b);
 
           rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &pk.Q, NULL, NULL);
@@ -1169,7 +1169,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
     }
 
   /* Compute the encrypted value.  */
-  ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
+  ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
                                     pk.E.p, pk.E.a, pk.E.b);
 
   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
@@ -1338,7 +1338,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
       return rc;
     }
 
-  ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect,
+  ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0,
                                     sk.E.p, sk.E.a, sk.E.b);
 
   /* R = dkG */
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 76cf0bd..9c695e0 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -2278,7 +2278,7 @@ For ECC key generation do not return the domain parameters but only
 the name of the curve.  For ECC signing and verification ignore any
 provided domain parameters of the public or private key and use only
 the curve name.  It is more secure to rely on the curve name and thus
-use the curve parameters as known by Libgcrypt.  This option shouild
+use the curve parameters as known by Libgcrypt.  This option should
 have been the default but for backward compatibility reasons this is
 not possible.  It is best to always use this flag with ECC keys.
 
diff --git a/mpi/ec.c b/mpi/ec.c
index 39ab5eb..57396ce 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -350,6 +350,7 @@ ec_get_two_inv_p (mpi_ec_t ec)
 static void
 ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
            enum ecc_dialects dialect,
+           int flags,
            gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
 {
   int i;
@@ -367,6 +368,7 @@ ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
 
   ctx->model = model;
   ctx->dialect = dialect;
+  ctx->flags = flags;
   if (dialect == ECC_DIALECT_ED25519)
     ctx->nbits = 256;
   else
@@ -454,12 +456,13 @@ ec_deinit (void *opaque)
 mpi_ec_t
 _gcry_mpi_ec_p_internal_new (enum gcry_mpi_ec_models model,
                              enum ecc_dialects dialect,
+                             int flags,
                              gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
 {
   mpi_ec_t ctx;
 
   ctx = gcry_xcalloc (1, sizeof *ctx);
-  ec_p_init (ctx, model, dialect, p, a, b);
+  ec_p_init (ctx, model, dialect, flags, p, a, b);
 
   return ctx;
 }
@@ -476,6 +479,7 @@ gpg_err_code_t
 _gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
                     enum gcry_mpi_ec_models model,
                     enum ecc_dialects dialect,
+                    int flags,
                     gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
 {
   gcry_ctx_t ctx;
@@ -489,7 +493,7 @@ _gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
   if (!ctx)
     return gpg_err_code_from_syserror ();
   ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
-  ec_p_init (ec, model, dialect, p, a, b);
+  ec_p_init (ec, model, dialect, flags, p, a, b);
 
   *r_ctx = ctx;
   return 0;
diff --git a/src/ec-context.h b/src/ec-context.h
index a118608..60ca759 100644
--- a/src/ec-context.h
+++ b/src/ec-context.h
@@ -27,6 +27,8 @@ struct mpi_ec_ctx_s
 
   enum ecc_dialects dialect;     /* The ECC dialect used with the curve.  */
 
+  int flags;                     /* Public key flags (not always used).  */
+
   unsigned int nbits;            /* Number of bits.  */
 
   /* Domain parameters.  Note that they may not all be set and if set
diff --git a/src/mpi.h b/src/mpi.h
index 15fb542..a5d805e 100644
--- a/src/mpi.h
+++ b/src/mpi.h
@@ -312,10 +312,12 @@ void _gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx);
 
 mpi_ec_t _gcry_mpi_ec_p_internal_new (enum gcry_mpi_ec_models model,
                                       enum ecc_dialects dialect,
+                                      int flags,
                                       gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b);
 gpg_err_code_t _gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
                                    enum gcry_mpi_ec_models model,
                                    enum ecc_dialects dialect,
+                                   int flags,
                                    gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b);
 void _gcry_mpi_ec_free (mpi_ec_t ctx);
 

commit 630aca794ddf057fb7265b7dc346374743036af4
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Nov 4 16:47:13 2013 +0100

    mpi: Add function gcry_mpi_set_opaque_copy.
    
    * src/gcrypt.h.in (gcry_mpi_set_opaque_copy): New.
    * src/visibility.c (gcry_mpi_set_opaque_copy): New.
    * src/visibility.h (gcry_mpi_set_opaque_copy): Mark visible.
    * src/libgcrypt.def, src/libgcrypt.vers: Add new API.
    * tests/mpitests.c (test_opaque): Add test.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index d60e067..8010c37 100644
--- a/NEWS
+++ b/NEWS
@@ -75,6 +75,7 @@ Noteworthy changes in version 1.6.0 (unreleased)
  gcry_mpi_neg                    NEW.
  gcry_mpi_abs                    NEW.
  gcry_mpi_snatch                 NEW.
+ gcry_mpi_set_opaque_copy        NEW.
  gcry_mpi_point_t                NEW.
  gcry_mpi_point_new              NEW.
  gcry_mpi_point_release          NEW.
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 4a202dd..76cf0bd 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -4467,6 +4467,13 @@ valid functions are gcry_mpi_get_opaque and gcry_mpi_release.  Use
 gcry_mpi_scan to convert a string of arbitrary bytes into an MPI.
 @end deftypefun
 
+ at deftypefun gcry_mpi_t gcry_mpi_set_opaque_copy (@w{gcry_mpi_t @var{a}}, @w{const void *@var{p}}, @w{unsigned int @var{nbits}})
+
+Same as @code{gcry_mpi_set_opaque} but ownership of @var{p} is not
+taken instead a copy of @var{p} is used.
+ at end deftypefun
+
+
 @deftypefun {void *} gcry_mpi_get_opaque (@w{gcry_mpi_t @var{a}}, @w{unsigned int *@var{nbits}})
 
 Return a pointer to an opaque value stored in @var{a} and return its
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 2742556..234e8a4 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -726,10 +726,18 @@ void     gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
 void     gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
 
 /* Store NBITS of the value P points to in A and mark A as an opaque
-   value.  WARNING: Never use an opaque MPI for anything thing else than
+   value.  On success A received the the ownership of the value P.
+   WARNING: Never use an opaque MPI for anything thing else than
    gcry_mpi_release, gcry_mpi_get_opaque. */
 gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
 
+/* Store NBITS of the value P points to in A and mark A as an opaque
+   value.  The function takes a copy of the provided value P.
+   WARNING: Never use an opaque MPI for anything thing else than
+   gcry_mpi_release, gcry_mpi_get_opaque. */
+gcry_mpi_t gcry_mpi_set_opaque_copy (gcry_mpi_t a,
+                                     const void *p, unsigned int nbits);
+
 /* Return a pointer to an opaque value stored in A and return its size
    in NBITS.  Note that the returned pointer is still owned by A and
    that the function should never be used for an non-opaque MPI. */
diff --git a/src/libgcrypt.def b/src/libgcrypt.def
index 64ba370..e2aba2b 100644
--- a/src/libgcrypt.def
+++ b/src/libgcrypt.def
@@ -259,5 +259,7 @@ EXPORTS
       gcry_cipher_gettag        @227
       gcry_cipher_checktag      @228
 
+      gcry_mpi_set_opaque_copy  @229
+
 
 ;; end of file with public symbols for Windows.
diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers
index 93eaa93..c3a09b8 100644
--- a/src/libgcrypt.vers
+++ b/src/libgcrypt.vers
@@ -88,7 +88,8 @@ GCRYPT_1.6 {
     gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new;
     gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release;
     gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit;
-    gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque;
+    gcry_mpi_set_flag; gcry_mpi_set_highbit;
+    gcry_mpi_set_opaque; gcry_mpi_set_opaque_copy;
     gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui;
     gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit;
     gcry_mpi_lshift; gcry_mpi_snatch;
diff --git a/src/visibility.c b/src/visibility.c
index 1f7bb3a..852bdf9 100644
--- a/src/visibility.c
+++ b/src/visibility.c
@@ -629,6 +629,12 @@ gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
   return _gcry_mpi_set_opaque (a, p, nbits);
 }
 
+gcry_mpi_t
+gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
+{
+  return _gcry_mpi_set_opaque_copy (a, p, nbits);
+}
+
 void *
 gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
 {
diff --git a/src/visibility.h b/src/visibility.h
index b2fa4c0..438db5b 100644
--- a/src/visibility.h
+++ b/src/visibility.h
@@ -603,6 +603,7 @@ MARK_VISIBLE (gcry_mpi_set_bit)
 MARK_VISIBLE (gcry_mpi_set_flag)
 MARK_VISIBLE (gcry_mpi_set_highbit)
 MARK_VISIBLE (gcry_mpi_set_opaque)
+MARK_VISIBLEX(gcry_mpi_set_opaque_copy)
 MARK_VISIBLE (gcry_mpi_set_ui)
 MARK_VISIBLE (gcry_mpi_snew)
 MARK_VISIBLE (gcry_mpi_sub)
@@ -632,8 +633,8 @@ MARK_VISIBLEX(_gcry_mpi_get_const)
    between a public and an internal version is that the internal
    version use gpg_err_code_t and the public version gpg_error_t.  */
 
-#define gcry_sexp_extract_param _gcry_USE_THE_UNDERSCORED_FUNCTION
-
+#define gcry_sexp_extract_param   _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_opaque_copy  _gcry_USE_THE_UNDERSCORED_FUNCTION
 
 #endif /*!_GCRY_INCLUDED_BY_VISIBILITY_C*/
 
diff --git a/tests/mpitests.c b/tests/mpitests.c
index c5c60d7..1c4edb6 100644
--- a/tests/mpitests.c
+++ b/tests/mpitests.c
@@ -213,6 +213,24 @@ test_opaque (void)
   if (debug)
     gcry_log_debugmpi ("mpi", a);
 
+  p = gcry_xstrdup ("This is a test buffer");
+  a = gcry_mpi_set_opaque_copy (NULL, p, 21*8+1);
+  gcry_free (p);
+
+  if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    die ("opaque flag not set\n");
+
+  p = gcry_mpi_get_opaque (a, &nbits);
+  if (!p)
+    die ("gcry_mpi_get_opaque returned NULL\n");
+  if (nbits != 21*8+1)
+    die ("gcry_mpi_get_opaque returned a changed bit size\n");
+  if (strcmp (p, "This is a test buffer"))
+    die ("gcry_mpi_get_opaque returned a changed buffer\n");
+
+  if (debug)
+    gcry_log_debugmpi ("mpi", a);
+
   gcry_mpi_release (a);
 }
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS                |    1 +
 cipher/ecc-curves.c |  128 +++++++++++++++++++++++++++++++++------------------
 cipher/ecc-ecdsa.c  |    4 +-
 cipher/ecc-eddsa.c  |    4 +-
 cipher/ecc-gost.c   |    4 +-
 cipher/ecc-misc.c   |  112 ++++++++++++++++++++++----------------------
 cipher/ecc.c        |   10 ++--
 doc/gcrypt.texi     |    9 +++-
 mpi/ec.c            |    8 +++-
 src/ec-context.h    |    2 +
 src/gcrypt.h.in     |   10 +++-
 src/libgcrypt.def   |    2 +
 src/libgcrypt.vers  |    3 +-
 src/mpi.h           |    2 +
 src/visibility.c    |    6 +++
 src/visibility.h    |    5 +-
 tests/mpitests.c    |   18 ++++++++
 17 files changed, 207 insertions(+), 121 deletions(-)


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org




More information about the Gnupg-commits mailing list