LCOV - code coverage report
Current view: top level - cipher - ecc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1090 0.0 %
Date: 2016-12-15 12:59:22 Functions: 0 17 0.0 %

          Line data    Source code
       1             : /* ecc.c  -  Elliptic Curve Cryptography
       2             :  * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2013, 2015 g10 Code GmbH
       4             :  *
       5             :  * This file is part of Libgcrypt.
       6             :  *
       7             :  * Libgcrypt is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU Lesser General Public License as
       9             :  * published by the Free Software Foundation; either version 2.1 of
      10             :  * the License, or (at your option) any later version.
      11             :  *
      12             :  * Libgcrypt is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : /* This code is originally based on the Patch 0.1.6 for the gnupg
      22             :    1.4.x branch as retrieved on 2007-03-21 from
      23             :    http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
      24             :    The original authors are:
      25             :      Written by
      26             :       Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>,
      27             :       Ramiro Moreno Chiral <ramiro at eup.udl.es>
      28             :      Maintainers
      29             :       Sergi Blanch i Torne
      30             :       Ramiro Moreno Chiral
      31             :       Mikael Mylnikov (mmr)
      32             :   For use in Libgcrypt the code has been heavily modified and cleaned
      33             :   up. In fact there is not much left of the originally code except for
      34             :   some variable names and the text book implementaion of the sign and
      35             :   verification algorithms.  The arithmetic functions have entirely
      36             :   been rewritten and moved to mpi/ec.c.
      37             : 
      38             :   ECDH encrypt and decrypt code written by Andrey Jivsov.
      39             : */
      40             : 
      41             : 
      42             : /* TODO:
      43             : 
      44             :   - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
      45             :     special case in mpi_powm or check whether mpi_mulm is faster.
      46             : 
      47             : */
      48             : 
      49             : 
      50             : #include <config.h>
      51             : #include <stdio.h>
      52             : #include <stdlib.h>
      53             : #include <string.h>
      54             : #include <errno.h>
      55             : 
      56             : #include "g10lib.h"
      57             : #include "mpi.h"
      58             : #include "cipher.h"
      59             : #include "context.h"
      60             : #include "ec-context.h"
      61             : #include "pubkey-internal.h"
      62             : #include "ecc-common.h"
      63             : 
      64             : 
      65             : static const char *ecc_names[] =
      66             :   {
      67             :     "ecc",
      68             :     "ecdsa",
      69             :     "ecdh",
      70             :     "eddsa",
      71             :     "gost",
      72             :     NULL,
      73             :   };
      74             : 
      75             : 
      76             : /* Sample NIST P-256 key from RFC 6979 A.2.5 */
      77             : static const char sample_public_key_secp256[] =
      78             :   "(public-key"
      79             :   " (ecc"
      80             :   "  (curve secp256r1)"
      81             :   "  (q #04"
      82             :   /**/  "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
      83             :   /**/  "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
      84             : 
      85             : static const char sample_secret_key_secp256[] =
      86             :   "(private-key"
      87             :   " (ecc"
      88             :   "  (curve secp256r1)"
      89             :   "  (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)"
      90             :   "  (q #04"
      91             :   /**/  "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
      92             :   /**/  "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
      93             : 
      94             : 
      95             : /* Registered progress function and its callback value. */
      96             : static void (*progress_cb) (void *, const char*, int, int, int);
      97             : static void *progress_cb_data;
      98             : 
      99             : 
     100             : 
     101             : /* Local prototypes. */
     102             : static void test_keys (ECC_secret_key * sk, unsigned int nbits);
     103             : static void test_ecdh_only_keys (ECC_secret_key * sk, unsigned int nbits, int flags);
     104             : static unsigned int ecc_get_nbits (gcry_sexp_t parms);
     105             : 
     106             : 
     107             : 
     108             : 
     109             : void
     110           0 : _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
     111             :                                             int, int, int),
     112             :                                 void *cb_data)
     113             : {
     114           0 :   progress_cb = cb;
     115           0 :   progress_cb_data = cb_data;
     116           0 : }
     117             : 
     118             : /* static void */
     119             : /* progress (int c) */
     120             : /* { */
     121             : /*   if (progress_cb) */
     122             : /*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
     123             : /* } */
     124             : 
     125             : 
     126             : 
     127             : /**
     128             :  * nist_generate_key - Standard version of the ECC key generation.
     129             :  * @sk:  A struct to receive the secret key.
     130             :  * @E:   Parameters of the curve.
     131             :  * @ctx: Elliptic curve computation context.
     132             :  * @flags: Flags controlling aspects of the creation.
     133             :  * @nbits: Only for testing
     134             :  * @r_x: On success this receives an allocated MPI with the affine
     135             :  *       x-coordinate of the poblic key.  On error NULL is stored.
     136             :  * @r_y: Ditto for the y-coordinate.
     137             :  *
     138             :  * Return: An error code.
     139             :  *
     140             :  * The @flags bits used by this function are %PUBKEY_FLAG_TRANSIENT to
     141             :  * use a faster RNG, and %PUBKEY_FLAG_NO_KEYTEST to skip the assertion
     142             :  * that the key works as expected.
     143             :  *
     144             :  * FIXME: Check whether N is needed.
     145             :  */
     146             : static gpg_err_code_t
     147           0 : nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
     148             :                    int flags, unsigned int nbits,
     149             :                    gcry_mpi_t *r_x, gcry_mpi_t *r_y)
     150             : {
     151             :   mpi_point_struct Q;
     152             :   gcry_random_level_t random_level;
     153             :   gcry_mpi_t x, y;
     154           0 :   const unsigned int pbits = mpi_get_nbits (E->p);
     155             : 
     156           0 :   point_init (&Q);
     157             : 
     158           0 :   if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
     159           0 :     random_level = GCRY_STRONG_RANDOM;
     160             :   else
     161           0 :     random_level = GCRY_VERY_STRONG_RANDOM;
     162             : 
     163             :   /* Generate a secret.  */
     164           0 :   if (ctx->dialect == ECC_DIALECT_ED25519 || (flags & PUBKEY_FLAG_DJB_TWEAK))
     165           0 :     {
     166             :       char *rndbuf;
     167             : 
     168           0 :       sk->d = mpi_snew (256);
     169           0 :       rndbuf = _gcry_random_bytes_secure (32, random_level);
     170           0 :       rndbuf[0] &= 0x7f;  /* Clear bit 255. */
     171           0 :       rndbuf[0] |= 0x40;  /* Set bit 254.   */
     172           0 :       rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0  */
     173           0 :       _gcry_mpi_set_buffer (sk->d, rndbuf, 32, 0);
     174           0 :       xfree (rndbuf);
     175             :     }
     176             :   else
     177           0 :     sk->d = _gcry_dsa_gen_k (E->n, random_level);
     178             : 
     179             : 
     180             :   /* Compute Q.  */
     181           0 :   _gcry_mpi_ec_mul_point (&Q, sk->d, &E->G, ctx);
     182             : 
     183             :   /* Copy the stuff to the key structures. */
     184           0 :   sk->E.model = E->model;
     185           0 :   sk->E.dialect = E->dialect;
     186           0 :   sk->E.p = mpi_copy (E->p);
     187           0 :   sk->E.a = mpi_copy (E->a);
     188           0 :   sk->E.b = mpi_copy (E->b);
     189           0 :   point_init (&sk->E.G);
     190           0 :   point_set (&sk->E.G, &E->G);
     191           0 :   sk->E.n = mpi_copy (E->n);
     192           0 :   sk->E.h = mpi_copy (E->h);
     193           0 :   point_init (&sk->Q);
     194             : 
     195           0 :   x = mpi_new (pbits);
     196           0 :   if (r_y == NULL)
     197           0 :     y = NULL;
     198             :   else
     199           0 :     y = mpi_new (pbits);
     200           0 :   if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
     201           0 :     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
     202             : 
     203             :   /* We want the Q=(x,y) be a "compliant key" in terms of the
     204             :    * http://tools.ietf.org/html/draft-jivsov-ecc-compact, which simply
     205             :    * means that we choose either Q=(x,y) or -Q=(x,p-y) such that we
     206             :    * end up with the min(y,p-y) as the y coordinate.  Such a public
     207             :    * key allows the most efficient compression: y can simply be
     208             :    * dropped because we know that it's a minimum of the two
     209             :    * possibilities without any loss of security.  Note that we don't
     210             :    * do that for Ed25519 so that we do not violate the special
     211             :    * construction of the secret key.  */
     212           0 :   if (r_y == NULL || E->dialect == ECC_DIALECT_ED25519)
     213           0 :     point_set (&sk->Q, &Q);
     214             :   else
     215             :     {
     216             :       gcry_mpi_t negative;
     217             : 
     218           0 :       negative = mpi_new (pbits);
     219             : 
     220           0 :       if (E->model == MPI_EC_WEIERSTRASS)
     221           0 :         mpi_sub (negative, E->p, y);      /* negative = p - y */
     222             :       else
     223           0 :         mpi_sub (negative, E->p, x);      /* negative = p - x */
     224             : 
     225           0 :       if (mpi_cmp (negative, y) < 0)   /* p - y < p */
     226             :         {
     227             :           /* We need to end up with -Q; this assures that new Q's y is
     228             :              the smallest one */
     229           0 :           if (E->model == MPI_EC_WEIERSTRASS)
     230             :             {
     231           0 :               mpi_free (y);
     232           0 :               y = negative;
     233             :             }
     234             :           else
     235             :             {
     236           0 :               mpi_free (x);
     237           0 :               x = negative;
     238             :             }
     239           0 :           mpi_sub (sk->d, E->n, sk->d);   /* d = order - d */
     240           0 :           mpi_point_set (&sk->Q, x, y, mpi_const (MPI_C_ONE));
     241             : 
     242           0 :           if (DBG_CIPHER)
     243           0 :             log_debug ("ecgen converted Q to a compliant point\n");
     244             :         }
     245             :       else /* p - y >= p */
     246             :         {
     247             :           /* No change is needed exactly 50% of the time: just copy. */
     248           0 :           mpi_free (negative);
     249           0 :           point_set (&sk->Q, &Q);
     250           0 :           if (DBG_CIPHER)
     251           0 :             log_debug ("ecgen didn't need to convert Q to a compliant point\n");
     252             :         }
     253             :     }
     254             : 
     255           0 :   *r_x = x;
     256           0 :   if (r_y)
     257           0 :     *r_y = y;
     258             : 
     259           0 :   point_free (&Q);
     260             :   /* Now we can test our keys (this should never fail!).  */
     261           0 :   if ((flags & PUBKEY_FLAG_NO_KEYTEST))
     262             :     ; /* User requested to skip the test.  */
     263           0 :   else if (sk->E.model != MPI_EC_MONTGOMERY)
     264           0 :     test_keys (sk, nbits - 64);
     265             :   else
     266           0 :     test_ecdh_only_keys (sk, nbits - 64, flags);
     267             : 
     268           0 :   return 0;
     269             : }
     270             : 
     271             : 
     272             : /*
     273             :  * To verify correct skey it use a random information.
     274             :  * First, encrypt and decrypt this dummy value,
     275             :  * test if the information is recuperated.
     276             :  * Second, test with the sign and verify functions.
     277             :  */
     278             : static void
     279           0 : test_keys (ECC_secret_key *sk, unsigned int nbits)
     280             : {
     281             :   ECC_public_key pk;
     282           0 :   gcry_mpi_t test = mpi_new (nbits);
     283             :   mpi_point_struct R_;
     284           0 :   gcry_mpi_t c = mpi_new (nbits);
     285           0 :   gcry_mpi_t out = mpi_new (nbits);
     286           0 :   gcry_mpi_t r = mpi_new (nbits);
     287           0 :   gcry_mpi_t s = mpi_new (nbits);
     288             : 
     289           0 :   if (DBG_CIPHER)
     290           0 :     log_debug ("Testing key.\n");
     291             : 
     292           0 :   point_init (&R_);
     293             : 
     294           0 :   pk.E = _gcry_ecc_curve_copy (sk->E);
     295           0 :   point_init (&pk.Q);
     296           0 :   point_set (&pk.Q, &sk->Q);
     297             : 
     298           0 :   _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
     299             : 
     300           0 :   if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) )
     301           0 :     log_fatal ("ECDSA operation: sign failed\n");
     302             : 
     303           0 :   if (_gcry_ecc_ecdsa_verify (test, &pk, r, s))
     304             :     {
     305           0 :       log_fatal ("ECDSA operation: sign, verify failed\n");
     306             :     }
     307             : 
     308           0 :   if (DBG_CIPHER)
     309           0 :     log_debug ("ECDSA operation: sign, verify ok.\n");
     310             : 
     311           0 :   point_free (&pk.Q);
     312           0 :   _gcry_ecc_curve_free (&pk.E);
     313             : 
     314           0 :   point_free (&R_);
     315           0 :   mpi_free (s);
     316           0 :   mpi_free (r);
     317           0 :   mpi_free (out);
     318           0 :   mpi_free (c);
     319           0 :   mpi_free (test);
     320           0 : }
     321             : 
     322             : 
     323             : static void
     324           0 : test_ecdh_only_keys (ECC_secret_key *sk, unsigned int nbits, int flags)
     325             : {
     326             :   ECC_public_key pk;
     327             :   gcry_mpi_t test;
     328             :   mpi_point_struct R_;
     329             :   gcry_mpi_t x0, x1;
     330             :   mpi_ec_t ec;
     331             : 
     332           0 :   if (DBG_CIPHER)
     333           0 :     log_debug ("Testing ECDH only key.\n");
     334             : 
     335           0 :   point_init (&R_);
     336             : 
     337           0 :   pk.E = _gcry_ecc_curve_copy (sk->E);
     338           0 :   point_init (&pk.Q);
     339           0 :   point_set (&pk.Q, &sk->Q);
     340             : 
     341           0 :   if ((flags & PUBKEY_FLAG_DJB_TWEAK))
     342             :     {
     343             :       char *rndbuf;
     344             : 
     345           0 :       test = mpi_new (256);
     346           0 :       rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM);
     347           0 :       rndbuf[0] &= 0x7f;  /* Clear bit 255. */
     348           0 :       rndbuf[0] |= 0x40;  /* Set bit 254.   */
     349           0 :       rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0  */
     350           0 :       _gcry_mpi_set_buffer (test, rndbuf, 32, 0);
     351           0 :       xfree (rndbuf);
     352             :     }
     353             :   else
     354             :     {
     355           0 :       test = mpi_new (nbits);
     356           0 :       _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
     357             :     }
     358             : 
     359           0 :   ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, flags,
     360             :                                     pk.E.p, pk.E.a, pk.E.b);
     361           0 :   x0 = mpi_new (0);
     362           0 :   x1 = mpi_new (0);
     363             : 
     364             :   /* R_ = hkQ  <=>  R_ = hkdG  */
     365           0 :   _gcry_mpi_ec_mul_point (&R_, test, &pk.Q, ec);
     366           0 :   if (!(flags & PUBKEY_FLAG_DJB_TWEAK))
     367           0 :     _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
     368           0 :   if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec))
     369           0 :     log_fatal ("ecdh: Failed to get affine coordinates for hkQ\n");
     370             : 
     371           0 :   _gcry_mpi_ec_mul_point (&R_, test, &pk.E.G, ec);
     372           0 :   _gcry_mpi_ec_mul_point (&R_, sk->d, &R_, ec);
     373             :   /* R_ = hdkG */
     374           0 :   if (!(flags & PUBKEY_FLAG_DJB_TWEAK))
     375           0 :     _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
     376             : 
     377           0 :   if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec))
     378           0 :     log_fatal ("ecdh: Failed to get affine coordinates for hdkG\n");
     379             : 
     380           0 :   if (mpi_cmp (x0, x1))
     381             :     {
     382           0 :       log_fatal ("ECDH test failed.\n");
     383             :     }
     384             : 
     385           0 :   mpi_free (x0);
     386           0 :   mpi_free (x1);
     387           0 :   _gcry_mpi_ec_free (ec);
     388             : 
     389           0 :   point_free (&pk.Q);
     390           0 :   _gcry_ecc_curve_free (&pk.E);
     391             : 
     392           0 :   point_free (&R_);
     393           0 :   mpi_free (test);
     394           0 : }
     395             : 
     396             : 
     397             : /*
     398             :  * To check the validity of the value, recalculate the correspondence
     399             :  * between the public value and the secret one.
     400             :  */
     401             : static int
     402           0 : check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags)
     403             : {
     404           0 :   int rc = 1;
     405             :   mpi_point_struct Q;
     406             :   gcry_mpi_t x1, y1;
     407           0 :   gcry_mpi_t x2 = NULL;
     408           0 :   gcry_mpi_t y2 = NULL;
     409             : 
     410           0 :   point_init (&Q);
     411           0 :   x1 = mpi_new (0);
     412           0 :   if (ec->model == MPI_EC_MONTGOMERY)
     413           0 :     y1 = NULL;
     414             :   else
     415           0 :     y1 = mpi_new (0);
     416             : 
     417             :   /* G in E(F_p) */
     418           0 :   if (!_gcry_mpi_ec_curve_point (&sk->E.G, ec))
     419             :     {
     420           0 :       if (DBG_CIPHER)
     421           0 :         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
     422           0 :       goto leave;
     423             :     }
     424             : 
     425             :   /* G != PaI */
     426           0 :   if (!mpi_cmp_ui (sk->E.G.z, 0))
     427             :     {
     428           0 :       if (DBG_CIPHER)
     429           0 :         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
     430           0 :       goto leave;
     431             :     }
     432             : 
     433             :   /* Check order of curve.  */
     434           0 :   if (sk->E.dialect != ECC_DIALECT_ED25519 && !(flags & PUBKEY_FLAG_DJB_TWEAK))
     435             :     {
     436           0 :       _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ec);
     437           0 :       if (mpi_cmp_ui (Q.z, 0))
     438             :         {
     439           0 :           if (DBG_CIPHER)
     440           0 :             log_debug ("check_secret_key: E is not a curve of order n\n");
     441           0 :           goto leave;
     442             :         }
     443             :     }
     444             : 
     445             :   /* Pubkey cannot be PaI */
     446           0 :   if (!mpi_cmp_ui (sk->Q.z, 0))
     447             :     {
     448           0 :       if (DBG_CIPHER)
     449           0 :         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
     450           0 :       goto leave;
     451             :     }
     452             : 
     453             :   /* pubkey = [d]G over E */
     454           0 :   if (!_gcry_ecc_compute_public (&Q, ec, &sk->E.G, sk->d))
     455             :     {
     456           0 :       if (DBG_CIPHER)
     457           0 :         log_debug ("Bad check: computation of dG failed\n");
     458           0 :       goto leave;
     459             :     }
     460           0 :   if (_gcry_mpi_ec_get_affine (x1, y1, &Q, ec))
     461             :     {
     462           0 :       if (DBG_CIPHER)
     463           0 :         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
     464           0 :       goto leave;
     465             :     }
     466             : 
     467           0 :   if ((flags & PUBKEY_FLAG_EDDSA))
     468             :     ; /* Fixme: EdDSA is special.  */
     469           0 :   else if (!mpi_cmp_ui (sk->Q.z, 1))
     470             :     {
     471             :       /* Fast path if Q is already in affine coordinates.  */
     472           0 :       if (mpi_cmp (x1, sk->Q.x) || (y1 && mpi_cmp (y1, sk->Q.y)))
     473             :         {
     474           0 :           if (DBG_CIPHER)
     475           0 :             log_debug
     476             :               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
     477           0 :           goto leave;
     478             :         }
     479             :     }
     480             :   else
     481             :     {
     482           0 :       x2 = mpi_new (0);
     483           0 :       y2 = mpi_new (0);
     484           0 :       if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ec))
     485             :         {
     486           0 :           if (DBG_CIPHER)
     487           0 :             log_debug ("Bad check: Q can not be a Point at Infinity!\n");
     488           0 :           goto leave;
     489             :         }
     490             : 
     491           0 :       if (mpi_cmp (x1, x2) || mpi_cmp (y1, y2))
     492             :         {
     493           0 :           if (DBG_CIPHER)
     494           0 :             log_debug
     495             :               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
     496           0 :           goto leave;
     497             :         }
     498             :     }
     499           0 :   rc = 0; /* Okay.  */
     500             : 
     501             :  leave:
     502           0 :   mpi_free (x2);
     503           0 :   mpi_free (x1);
     504           0 :   mpi_free (y1);
     505           0 :   mpi_free (y2);
     506           0 :   point_free (&Q);
     507           0 :   return rc;
     508             : }
     509             : 
     510             : 
     511             : 
     512             : /*********************************************
     513             :  **************  interface  ******************
     514             :  *********************************************/
     515             : 
     516             : static gcry_err_code_t
     517           0 : ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
     518             : {
     519             :   gpg_err_code_t rc;
     520             :   unsigned int nbits;
     521             :   elliptic_curve_t E;
     522             :   ECC_secret_key sk;
     523           0 :   gcry_mpi_t Gx = NULL;
     524           0 :   gcry_mpi_t Gy = NULL;
     525           0 :   gcry_mpi_t Qx = NULL;
     526           0 :   gcry_mpi_t Qy = NULL;
     527           0 :   char *curve_name = NULL;
     528             :   gcry_sexp_t l1;
     529           0 :   mpi_ec_t ctx = NULL;
     530           0 :   gcry_sexp_t curve_info = NULL;
     531           0 :   gcry_sexp_t curve_flags = NULL;
     532           0 :   gcry_mpi_t base = NULL;
     533           0 :   gcry_mpi_t public = NULL;
     534           0 :   gcry_mpi_t secret = NULL;
     535           0 :   int flags = 0;
     536             : 
     537           0 :   memset (&E, 0, sizeof E);
     538           0 :   memset (&sk, 0, sizeof sk);
     539             : 
     540           0 :   rc = _gcry_pk_util_get_nbits (genparms, &nbits);
     541           0 :   if (rc)
     542           0 :     return rc;
     543             : 
     544             :   /* Parse the optional "curve" parameter. */
     545           0 :   l1 = sexp_find_token (genparms, "curve", 0);
     546           0 :   if (l1)
     547             :     {
     548           0 :       curve_name = _gcry_sexp_nth_string (l1, 1);
     549           0 :       sexp_release (l1);
     550           0 :       if (!curve_name)
     551           0 :         return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
     552             :     }
     553             : 
     554             :   /* Parse the optional flags list.  */
     555           0 :   l1 = sexp_find_token (genparms, "flags", 0);
     556           0 :   if (l1)
     557             :     {
     558           0 :       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
     559           0 :       sexp_release (l1);
     560           0 :       if (rc)
     561           0 :         goto leave;
     562             :     }
     563             : 
     564             :   /* Parse the deprecated optional transient-key flag.  */
     565           0 :   l1 = sexp_find_token (genparms, "transient-key", 0);
     566           0 :   if (l1)
     567             :     {
     568           0 :       flags |= PUBKEY_FLAG_TRANSIENT_KEY;
     569           0 :       sexp_release (l1);
     570             :     }
     571             : 
     572             :   /* NBITS is required if no curve name has been given.  */
     573           0 :   if (!nbits && !curve_name)
     574           0 :     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
     575             : 
     576           0 :   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
     577           0 :   if (rc)
     578           0 :     goto leave;
     579             : 
     580           0 :   if (DBG_CIPHER)
     581             :     {
     582           0 :       log_debug ("ecgen curve info: %s/%s\n",
     583             :                  _gcry_ecc_model2str (E.model),
     584             :                  _gcry_ecc_dialect2str (E.dialect));
     585           0 :       if (E.name)
     586           0 :         log_debug ("ecgen curve used: %s\n", E.name);
     587           0 :       log_printmpi ("ecgen curve   p", E.p);
     588           0 :       log_printmpi ("ecgen curve   a", E.a);
     589           0 :       log_printmpi ("ecgen curve   b", E.b);
     590           0 :       log_printmpi ("ecgen curve   n", E.n);
     591           0 :       log_printmpi ("ecgen curve   h", E.h);
     592           0 :       log_printpnt ("ecgen curve G", &E.G, NULL);
     593             :     }
     594             : 
     595           0 :   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, flags, E.p, E.a, E.b);
     596             : 
     597           0 :   if (E.model == MPI_EC_MONTGOMERY)
     598           0 :     rc = nist_generate_key (&sk, &E, ctx, flags, nbits, &Qx, NULL);
     599           0 :   else if ((flags & PUBKEY_FLAG_EDDSA))
     600           0 :     rc = _gcry_ecc_eddsa_genkey (&sk, &E, ctx, flags);
     601             :   else
     602           0 :     rc = nist_generate_key (&sk, &E, ctx, flags, nbits, &Qx, &Qy);
     603           0 :   if (rc)
     604           0 :     goto leave;
     605             : 
     606             :   /* Copy data to the result.  */
     607           0 :   Gx = mpi_new (0);
     608           0 :   Gy = mpi_new (0);
     609           0 :   if (E.model != MPI_EC_MONTGOMERY)
     610             :     {
     611           0 :       if (_gcry_mpi_ec_get_affine (Gx, Gy, &sk.E.G, ctx))
     612           0 :         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
     613           0 :       base = _gcry_ecc_ec2os (Gx, Gy, sk.E.p);
     614             :     }
     615           0 :   if ((sk.E.dialect == ECC_DIALECT_ED25519 || E.model == MPI_EC_MONTGOMERY)
     616           0 :       && !(flags & PUBKEY_FLAG_NOCOMP))
     617           0 :     {
     618             :       unsigned char *encpk;
     619             :       unsigned int encpklen;
     620             : 
     621           0 :       if (E.model != MPI_EC_MONTGOMERY)
     622             :         /* (Gx and Gy are used as scratch variables)  */
     623           0 :         rc = _gcry_ecc_eddsa_encodepoint (&sk.Q, ctx, Gx, Gy,
     624           0 :                                           !!(flags & PUBKEY_FLAG_COMP),
     625             :                                           &encpk, &encpklen);
     626             :       else
     627             :         {
     628           0 :           encpk = _gcry_mpi_get_buffer_extra (Qx, nbits/8,
     629             :                                               -1, &encpklen, NULL);
     630           0 :           if (encpk == NULL)
     631           0 :             rc = gpg_err_code_from_syserror ();
     632             :           else
     633             :             {
     634           0 :               encpk[0] = 0x40;
     635           0 :               encpklen++;
     636             :             }
     637             :         }
     638           0 :       if (rc)
     639           0 :         goto leave;
     640           0 :       public = mpi_new (0);
     641           0 :       mpi_set_opaque (public, encpk, encpklen*8);
     642             :     }
     643             :   else
     644             :     {
     645           0 :       if (!Qx)
     646             :         {
     647             :           /* This is the case for a key from _gcry_ecc_eddsa_generate
     648             :              with no compression.  */
     649           0 :           Qx = mpi_new (0);
     650           0 :           Qy = mpi_new (0);
     651           0 :           if (_gcry_mpi_ec_get_affine (Qx, Qy, &sk.Q, ctx))
     652           0 :             log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
     653             :         }
     654           0 :       public = _gcry_ecc_ec2os (Qx, Qy, sk.E.p);
     655             :     }
     656           0 :   secret = sk.d; sk.d = NULL;
     657           0 :   if (E.name)
     658             :     {
     659           0 :       rc = sexp_build (&curve_info, NULL, "(curve %s)", E.name);
     660           0 :       if (rc)
     661           0 :         goto leave;
     662             :     }
     663             : 
     664           0 :   if ((flags & PUBKEY_FLAG_PARAM) || (flags & PUBKEY_FLAG_EDDSA)
     665           0 :       || (flags & PUBKEY_FLAG_DJB_TWEAK))
     666             :     {
     667           0 :       rc = sexp_build
     668             :         (&curve_flags, NULL,
     669           0 :          ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
     670             :          "(flags param eddsa)" :
     671             :          ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
     672             :          "(flags param djb-tweak)" :
     673           0 :          ((flags & PUBKEY_FLAG_PARAM))?
     674           0 :          "(flags param)" : ((flags & PUBKEY_FLAG_EDDSA))?
     675           0 :          "(flags eddsa)" : "(flags djb-tweak)" );
     676           0 :       if (rc)
     677           0 :         goto leave;
     678             :     }
     679             : 
     680           0 :   if ((flags & PUBKEY_FLAG_PARAM) && E.name)
     681           0 :     rc = sexp_build (r_skey, NULL,
     682             :                      "(key-data"
     683             :                      " (public-key"
     684             :                      "  (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))"
     685             :                      " (private-key"
     686             :                      "  (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))"
     687             :                      " )",
     688             :                      curve_info, curve_flags,
     689             :                      sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public,
     690             :                      curve_info, curve_flags,
     691             :                      sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public,
     692             :                                                                    secret);
     693             :   else
     694           0 :     rc = sexp_build (r_skey, NULL,
     695             :                      "(key-data"
     696             :                      " (public-key"
     697             :                      "  (ecc%S%S(q%m)))"
     698             :                      " (private-key"
     699             :                      "  (ecc%S%S(q%m)(d%m)))"
     700             :                      " )",
     701             :                      curve_info, curve_flags,
     702             :                      public,
     703             :                      curve_info, curve_flags,
     704             :                      public, secret);
     705           0 :   if (rc)
     706           0 :     goto leave;
     707             : 
     708           0 :   if (DBG_CIPHER)
     709             :     {
     710           0 :       log_printmpi ("ecgen result  p", sk.E.p);
     711           0 :       log_printmpi ("ecgen result  a", sk.E.a);
     712           0 :       log_printmpi ("ecgen result  b", sk.E.b);
     713           0 :       log_printmpi ("ecgen result  G", base);
     714           0 :       log_printmpi ("ecgen result  n", sk.E.n);
     715           0 :       log_printmpi ("ecgen result  h", sk.E.h);
     716           0 :       log_printmpi ("ecgen result  Q", public);
     717           0 :       log_printmpi ("ecgen result  d", secret);
     718           0 :       if ((flags & PUBKEY_FLAG_EDDSA))
     719           0 :         log_debug ("ecgen result  using Ed25519+EdDSA\n");
     720             :     }
     721             : 
     722             :  leave:
     723           0 :   mpi_free (secret);
     724           0 :   mpi_free (public);
     725           0 :   mpi_free (base);
     726             :   {
     727           0 :     _gcry_ecc_curve_free (&sk.E);
     728           0 :     point_free (&sk.Q);
     729           0 :     mpi_free (sk.d);
     730             :   }
     731           0 :   _gcry_ecc_curve_free (&E);
     732           0 :   mpi_free (Gx);
     733           0 :   mpi_free (Gy);
     734           0 :   mpi_free (Qx);
     735           0 :   mpi_free (Qy);
     736           0 :   _gcry_mpi_ec_free (ctx);
     737           0 :   xfree (curve_name);
     738           0 :   sexp_release (curve_flags);
     739           0 :   sexp_release (curve_info);
     740           0 :   return rc;
     741             : }
     742             : 
     743             : 
     744             : static gcry_err_code_t
     745           0 : ecc_check_secret_key (gcry_sexp_t keyparms)
     746             : {
     747             :   gcry_err_code_t rc;
     748           0 :   gcry_sexp_t l1 = NULL;
     749           0 :   int flags = 0;
     750           0 :   char *curvename = NULL;
     751           0 :   gcry_mpi_t mpi_g = NULL;
     752           0 :   gcry_mpi_t mpi_q = NULL;
     753             :   ECC_secret_key sk;
     754           0 :   mpi_ec_t ec = NULL;
     755             : 
     756           0 :   memset (&sk, 0, sizeof sk);
     757             : 
     758             :   /* Look for flags. */
     759           0 :   l1 = sexp_find_token (keyparms, "flags", 0);
     760           0 :   if (l1)
     761             :     {
     762           0 :       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
     763           0 :       if (rc)
     764           0 :         goto leave;
     765             :     }
     766             : 
     767             :   /* Extract the parameters.  */
     768           0 :   if ((flags & PUBKEY_FLAG_PARAM))
     769           0 :     rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d",
     770             :                              &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
     771             :                              &sk.E.h, &mpi_q, &sk.d, NULL);
     772             :   else
     773           0 :     rc = sexp_extract_param (keyparms, NULL, "/q?+d",
     774             :                              &mpi_q, &sk.d, NULL);
     775           0 :   if (rc)
     776           0 :     goto leave;
     777             : 
     778             :   /* Add missing parameters using the optional curve parameter.  */
     779           0 :   sexp_release (l1);
     780           0 :   l1 = sexp_find_token (keyparms, "curve", 5);
     781           0 :   if (l1)
     782             :     {
     783           0 :       curvename = sexp_nth_string (l1, 1);
     784           0 :       if (curvename)
     785             :         {
     786           0 :           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
     787           0 :           if (rc)
     788           0 :             goto leave;
     789             :         }
     790             :     }
     791           0 :   if (mpi_g)
     792             :     {
     793           0 :       if (!sk.E.G.x)
     794           0 :         point_init (&sk.E.G);
     795           0 :       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
     796           0 :       if (rc)
     797           0 :         goto leave;
     798             :     }
     799             : 
     800             :   /* Guess required fields if a curve parameter has not been given.
     801             :      FIXME: This is a crude hacks.  We need to fix that.  */
     802           0 :   if (!curvename)
     803             :     {
     804           0 :       sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
     805             :                ? MPI_EC_EDWARDS
     806           0 :                : MPI_EC_WEIERSTRASS);
     807           0 :       sk.E.dialect = ((flags & PUBKEY_FLAG_EDDSA)
     808             :                       ? ECC_DIALECT_ED25519
     809           0 :                       : ECC_DIALECT_STANDARD);
     810           0 :       if (!sk.E.h)
     811           0 :         sk.E.h = mpi_const (MPI_C_ONE);
     812             :     }
     813           0 :   if (DBG_CIPHER)
     814             :     {
     815           0 :       log_debug ("ecc_testkey inf: %s/%s\n",
     816             :                  _gcry_ecc_model2str (sk.E.model),
     817             :                  _gcry_ecc_dialect2str (sk.E.dialect));
     818           0 :       if (sk.E.name)
     819           0 :         log_debug  ("ecc_testkey nam: %s\n", sk.E.name);
     820           0 :       log_printmpi ("ecc_testkey   p", sk.E.p);
     821           0 :       log_printmpi ("ecc_testkey   a", sk.E.a);
     822           0 :       log_printmpi ("ecc_testkey   b", sk.E.b);
     823           0 :       log_printpnt ("ecc_testkey g",   &sk.E.G, NULL);
     824           0 :       log_printmpi ("ecc_testkey   n", sk.E.n);
     825           0 :       log_printmpi ("ecc_testkey   h", sk.E.h);
     826           0 :       log_printmpi ("ecc_testkey   q", mpi_q);
     827           0 :       if (!fips_mode ())
     828           0 :         log_printmpi ("ecc_testkey   d", sk.d);
     829             :     }
     830           0 :   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d)
     831             :     {
     832           0 :       rc = GPG_ERR_NO_OBJ;
     833           0 :       goto leave;
     834             :     }
     835             : 
     836           0 :   ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, flags,
     837             :                                     sk.E.p, sk.E.a, sk.E.b);
     838             : 
     839           0 :   if (mpi_q)
     840             :     {
     841           0 :       point_init (&sk.Q);
     842           0 :       if (ec->dialect == ECC_DIALECT_ED25519)
     843           0 :         rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &sk.Q, NULL, NULL);
     844           0 :       else if (ec->model == MPI_EC_MONTGOMERY)
     845           0 :         rc = _gcry_ecc_mont_decodepoint (mpi_q, ec, &sk.Q);
     846             :       else
     847           0 :         rc = _gcry_ecc_os2ec (&sk.Q, mpi_q);
     848           0 :       if (rc)
     849           0 :         goto leave;
     850             :     }
     851             :   else
     852             :     {
     853             :       /* The secret key test requires Q.  */
     854           0 :       rc = GPG_ERR_NO_OBJ;
     855           0 :       goto leave;
     856             :     }
     857             : 
     858           0 :   if (check_secret_key (&sk, ec, flags))
     859           0 :     rc = GPG_ERR_BAD_SECKEY;
     860             : 
     861             :  leave:
     862           0 :   _gcry_mpi_ec_free (ec);
     863           0 :   _gcry_mpi_release (sk.E.p);
     864           0 :   _gcry_mpi_release (sk.E.a);
     865           0 :   _gcry_mpi_release (sk.E.b);
     866           0 :   _gcry_mpi_release (mpi_g);
     867           0 :   point_free (&sk.E.G);
     868           0 :   _gcry_mpi_release (sk.E.n);
     869           0 :   _gcry_mpi_release (sk.E.h);
     870           0 :   _gcry_mpi_release (mpi_q);
     871           0 :   point_free (&sk.Q);
     872           0 :   _gcry_mpi_release (sk.d);
     873           0 :   xfree (curvename);
     874           0 :   sexp_release (l1);
     875           0 :   if (DBG_CIPHER)
     876           0 :     log_debug ("ecc_testkey   => %s\n", gpg_strerror (rc));
     877           0 :   return rc;
     878             : }
     879             : 
     880             : 
     881             : static gcry_err_code_t
     882           0 : ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
     883             : {
     884             :   gcry_err_code_t rc;
     885             :   struct pk_encoding_ctx ctx;
     886           0 :   gcry_mpi_t data = NULL;
     887           0 :   gcry_sexp_t l1 = NULL;
     888           0 :   char *curvename = NULL;
     889           0 :   gcry_mpi_t mpi_g = NULL;
     890           0 :   gcry_mpi_t mpi_q = NULL;
     891             :   ECC_secret_key sk;
     892           0 :   gcry_mpi_t sig_r = NULL;
     893           0 :   gcry_mpi_t sig_s = NULL;
     894             : 
     895           0 :   memset (&sk, 0, sizeof sk);
     896             : 
     897           0 :   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, 0);
     898             : 
     899             :   /* Extract the data.  */
     900           0 :   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
     901           0 :   if (rc)
     902           0 :     goto leave;
     903           0 :   if (DBG_CIPHER)
     904           0 :     log_mpidump ("ecc_sign   data", data);
     905             : 
     906             :   /*
     907             :    * Extract the key.
     908             :    */
     909           0 :   if ((ctx.flags & PUBKEY_FLAG_PARAM))
     910           0 :     rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d",
     911             :                              &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
     912             :                              &sk.E.h, &mpi_q, &sk.d, NULL);
     913             :   else
     914           0 :     rc = sexp_extract_param (keyparms, NULL, "/q?+d",
     915             :                              &mpi_q, &sk.d, NULL);
     916           0 :   if (rc)
     917           0 :     goto leave;
     918           0 :   if (mpi_g)
     919             :     {
     920           0 :       point_init (&sk.E.G);
     921           0 :       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
     922           0 :       if (rc)
     923           0 :         goto leave;
     924             :     }
     925             :   /* Add missing parameters using the optional curve parameter.  */
     926           0 :   l1 = sexp_find_token (keyparms, "curve", 5);
     927           0 :   if (l1)
     928             :     {
     929           0 :       curvename = sexp_nth_string (l1, 1);
     930           0 :       if (curvename)
     931             :         {
     932           0 :           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
     933           0 :           if (rc)
     934           0 :             goto leave;
     935             :         }
     936             :     }
     937             :   /* Guess required fields if a curve parameter has not been given.
     938             :      FIXME: This is a crude hacks.  We need to fix that.  */
     939           0 :   if (!curvename)
     940             :     {
     941           0 :       sk.E.model = ((ctx.flags & PUBKEY_FLAG_EDDSA)
     942             :                     ? MPI_EC_EDWARDS
     943           0 :                     : MPI_EC_WEIERSTRASS);
     944           0 :       sk.E.dialect = ((ctx.flags & PUBKEY_FLAG_EDDSA)
     945             :                       ? ECC_DIALECT_ED25519
     946           0 :                       : ECC_DIALECT_STANDARD);
     947           0 :       if (!sk.E.h)
     948           0 :         sk.E.h = mpi_const (MPI_C_ONE);
     949             :     }
     950           0 :   if (DBG_CIPHER)
     951             :     {
     952           0 :       log_debug ("ecc_sign   info: %s/%s%s\n",
     953             :                  _gcry_ecc_model2str (sk.E.model),
     954             :                  _gcry_ecc_dialect2str (sk.E.dialect),
     955           0 :                  (ctx.flags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
     956           0 :       if (sk.E.name)
     957           0 :         log_debug  ("ecc_sign   name: %s\n", sk.E.name);
     958           0 :       log_printmpi ("ecc_sign      p", sk.E.p);
     959           0 :       log_printmpi ("ecc_sign      a", sk.E.a);
     960           0 :       log_printmpi ("ecc_sign      b", sk.E.b);
     961           0 :       log_printpnt ("ecc_sign    g",   &sk.E.G, NULL);
     962           0 :       log_printmpi ("ecc_sign      n", sk.E.n);
     963           0 :       log_printmpi ("ecc_sign      h", sk.E.h);
     964           0 :       log_printmpi ("ecc_sign      q", mpi_q);
     965           0 :       if (!fips_mode ())
     966           0 :         log_printmpi ("ecc_sign      d", sk.d);
     967             :     }
     968           0 :   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d)
     969             :     {
     970           0 :       rc = GPG_ERR_NO_OBJ;
     971           0 :       goto leave;
     972             :     }
     973             : 
     974             : 
     975           0 :   sig_r = mpi_new (0);
     976           0 :   sig_s = mpi_new (0);
     977           0 :   if ((ctx.flags & PUBKEY_FLAG_EDDSA))
     978             :     {
     979             :       /* EdDSA requires the public key.  */
     980           0 :       rc = _gcry_ecc_eddsa_sign (data, &sk, sig_r, sig_s, ctx.hash_algo, mpi_q);
     981           0 :       if (!rc)
     982           0 :         rc = sexp_build (r_sig, NULL,
     983             :                          "(sig-val(eddsa(r%M)(s%M)))", sig_r, sig_s);
     984             :     }
     985           0 :   else if ((ctx.flags & PUBKEY_FLAG_GOST))
     986             :     {
     987           0 :       rc = _gcry_ecc_gost_sign (data, &sk, sig_r, sig_s);
     988           0 :       if (!rc)
     989           0 :         rc = sexp_build (r_sig, NULL,
     990             :                          "(sig-val(gost(r%M)(s%M)))", sig_r, sig_s);
     991             :     }
     992             :   else
     993             :     {
     994           0 :       rc = _gcry_ecc_ecdsa_sign (data, &sk, sig_r, sig_s,
     995             :                                  ctx.flags, ctx.hash_algo);
     996           0 :       if (!rc)
     997           0 :         rc = sexp_build (r_sig, NULL,
     998             :                          "(sig-val(ecdsa(r%M)(s%M)))", sig_r, sig_s);
     999             :     }
    1000             : 
    1001             : 
    1002             :  leave:
    1003           0 :   _gcry_mpi_release (sk.E.p);
    1004           0 :   _gcry_mpi_release (sk.E.a);
    1005           0 :   _gcry_mpi_release (sk.E.b);
    1006           0 :   _gcry_mpi_release (mpi_g);
    1007           0 :   point_free (&sk.E.G);
    1008           0 :   _gcry_mpi_release (sk.E.n);
    1009           0 :   _gcry_mpi_release (sk.E.h);
    1010           0 :   _gcry_mpi_release (mpi_q);
    1011           0 :   point_free (&sk.Q);
    1012           0 :   _gcry_mpi_release (sk.d);
    1013           0 :   _gcry_mpi_release (sig_r);
    1014           0 :   _gcry_mpi_release (sig_s);
    1015           0 :   xfree (curvename);
    1016           0 :   _gcry_mpi_release (data);
    1017           0 :   sexp_release (l1);
    1018           0 :   _gcry_pk_util_free_encoding_ctx (&ctx);
    1019           0 :   if (DBG_CIPHER)
    1020           0 :     log_debug ("ecc_sign      => %s\n", gpg_strerror (rc));
    1021           0 :   return rc;
    1022             : }
    1023             : 
    1024             : 
    1025             : static gcry_err_code_t
    1026           0 : ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
    1027             : {
    1028             :   gcry_err_code_t rc;
    1029             :   struct pk_encoding_ctx ctx;
    1030           0 :   gcry_sexp_t l1 = NULL;
    1031           0 :   char *curvename = NULL;
    1032           0 :   gcry_mpi_t mpi_g = NULL;
    1033           0 :   gcry_mpi_t mpi_q = NULL;
    1034           0 :   gcry_mpi_t sig_r = NULL;
    1035           0 :   gcry_mpi_t sig_s = NULL;
    1036           0 :   gcry_mpi_t data = NULL;
    1037             :   ECC_public_key pk;
    1038             :   int sigflags;
    1039             : 
    1040           0 :   memset (&pk, 0, sizeof pk);
    1041           0 :   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
    1042             :                                    ecc_get_nbits (s_keyparms));
    1043             : 
    1044             :   /* Extract the data.  */
    1045           0 :   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
    1046           0 :   if (rc)
    1047           0 :     goto leave;
    1048           0 :   if (DBG_CIPHER)
    1049           0 :     log_mpidump ("ecc_verify data", data);
    1050             : 
    1051             :   /*
    1052             :    * Extract the signature value.
    1053             :    */
    1054           0 :   rc = _gcry_pk_util_preparse_sigval (s_sig, ecc_names, &l1, &sigflags);
    1055           0 :   if (rc)
    1056           0 :     goto leave;
    1057           0 :   rc = sexp_extract_param (l1, NULL, (sigflags & PUBKEY_FLAG_EDDSA)? "/rs":"rs",
    1058             :                            &sig_r, &sig_s, NULL);
    1059           0 :   if (rc)
    1060           0 :     goto leave;
    1061           0 :   if (DBG_CIPHER)
    1062             :     {
    1063           0 :       log_mpidump ("ecc_verify  s_r", sig_r);
    1064           0 :       log_mpidump ("ecc_verify  s_s", sig_s);
    1065             :     }
    1066           0 :   if ((ctx.flags & PUBKEY_FLAG_EDDSA) ^ (sigflags & PUBKEY_FLAG_EDDSA))
    1067             :     {
    1068           0 :       rc = GPG_ERR_CONFLICT; /* Inconsistent use of flag/algoname.  */
    1069           0 :       goto leave;
    1070             :     }
    1071             : 
    1072             : 
    1073             :   /*
    1074             :    * Extract the key.
    1075             :    */
    1076           0 :   if ((ctx.flags & PUBKEY_FLAG_PARAM))
    1077           0 :     rc = sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?h?/q",
    1078             :                              &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n,
    1079             :                              &pk.E.h, &mpi_q, NULL);
    1080             :   else
    1081           0 :     rc = sexp_extract_param (s_keyparms, NULL, "/q",
    1082             :                              &mpi_q, NULL);
    1083           0 :   if (rc)
    1084           0 :     goto leave;
    1085           0 :   if (mpi_g)
    1086             :     {
    1087           0 :       point_init (&pk.E.G);
    1088           0 :       rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
    1089           0 :       if (rc)
    1090           0 :         goto leave;
    1091             :     }
    1092             :   /* Add missing parameters using the optional curve parameter.  */
    1093           0 :   sexp_release (l1);
    1094           0 :   l1 = sexp_find_token (s_keyparms, "curve", 5);
    1095           0 :   if (l1)
    1096             :     {
    1097           0 :       curvename = sexp_nth_string (l1, 1);
    1098           0 :       if (curvename)
    1099             :         {
    1100           0 :           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
    1101           0 :           if (rc)
    1102           0 :             goto leave;
    1103             :         }
    1104             :     }
    1105             :   /* Guess required fields if a curve parameter has not been given.
    1106             :      FIXME: This is a crude hacks.  We need to fix that.  */
    1107           0 :   if (!curvename)
    1108             :     {
    1109           0 :       pk.E.model = ((sigflags & PUBKEY_FLAG_EDDSA)
    1110             :                     ? MPI_EC_EDWARDS
    1111           0 :                     : MPI_EC_WEIERSTRASS);
    1112           0 :       pk.E.dialect = ((sigflags & PUBKEY_FLAG_EDDSA)
    1113             :                       ? ECC_DIALECT_ED25519
    1114           0 :                       : ECC_DIALECT_STANDARD);
    1115           0 :       if (!pk.E.h)
    1116           0 :         pk.E.h = mpi_const (MPI_C_ONE);
    1117             :     }
    1118             : 
    1119           0 :   if (DBG_CIPHER)
    1120             :     {
    1121           0 :       log_debug ("ecc_verify info: %s/%s%s\n",
    1122             :                  _gcry_ecc_model2str (pk.E.model),
    1123             :                  _gcry_ecc_dialect2str (pk.E.dialect),
    1124           0 :                  (sigflags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
    1125           0 :       if (pk.E.name)
    1126           0 :         log_debug  ("ecc_verify name: %s\n", pk.E.name);
    1127           0 :       log_printmpi ("ecc_verify    p", pk.E.p);
    1128           0 :       log_printmpi ("ecc_verify    a", pk.E.a);
    1129           0 :       log_printmpi ("ecc_verify    b", pk.E.b);
    1130           0 :       log_printpnt ("ecc_verify  g",   &pk.E.G, NULL);
    1131           0 :       log_printmpi ("ecc_verify    n", pk.E.n);
    1132           0 :       log_printmpi ("ecc_verify    h", pk.E.h);
    1133           0 :       log_printmpi ("ecc_verify    q", mpi_q);
    1134             :     }
    1135           0 :   if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q)
    1136             :     {
    1137           0 :       rc = GPG_ERR_NO_OBJ;
    1138           0 :       goto leave;
    1139             :     }
    1140             : 
    1141             : 
    1142             :   /*
    1143             :    * Verify the signature.
    1144             :    */
    1145           0 :   if ((sigflags & PUBKEY_FLAG_EDDSA))
    1146             :     {
    1147           0 :       rc = _gcry_ecc_eddsa_verify (data, &pk, sig_r, sig_s,
    1148             :                                    ctx.hash_algo, mpi_q);
    1149             :     }
    1150           0 :   else if ((sigflags & PUBKEY_FLAG_GOST))
    1151             :     {
    1152           0 :       point_init (&pk.Q);
    1153           0 :       rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
    1154           0 :       if (rc)
    1155           0 :         goto leave;
    1156             : 
    1157           0 :       rc = _gcry_ecc_gost_verify (data, &pk, sig_r, sig_s);
    1158             :     }
    1159             :   else
    1160             :     {
    1161           0 :       point_init (&pk.Q);
    1162           0 :       if (pk.E.dialect == ECC_DIALECT_ED25519)
    1163             :         {
    1164             :           mpi_ec_t ec;
    1165             : 
    1166             :           /* Fixme: Factor the curve context setup out of eddsa_verify
    1167             :              and ecdsa_verify. So that we don't do it twice.  */
    1168           0 :           ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
    1169             :                                             pk.E.p, pk.E.a, pk.E.b);
    1170             : 
    1171           0 :           rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &pk.Q, NULL, NULL);
    1172           0 :           _gcry_mpi_ec_free (ec);
    1173             :         }
    1174             :       else
    1175             :         {
    1176           0 :           rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
    1177             :         }
    1178           0 :       if (rc)
    1179           0 :         goto leave;
    1180             : 
    1181           0 :       if (mpi_is_opaque (data))
    1182           0 :         {
    1183             :           const void *abuf;
    1184             :           unsigned int abits, qbits;
    1185             :           gcry_mpi_t a;
    1186             : 
    1187           0 :           qbits = mpi_get_nbits (pk.E.n);
    1188             : 
    1189           0 :           abuf = mpi_get_opaque (data, &abits);
    1190           0 :           rc = _gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
    1191           0 :           if (!rc)
    1192             :             {
    1193           0 :               if (abits > qbits)
    1194           0 :                 mpi_rshift (a, a, abits - qbits);
    1195             : 
    1196           0 :               rc = _gcry_ecc_ecdsa_verify (a, &pk, sig_r, sig_s);
    1197           0 :               _gcry_mpi_release (a);
    1198             :             }
    1199             :         }
    1200             :       else
    1201           0 :         rc = _gcry_ecc_ecdsa_verify (data, &pk, sig_r, sig_s);
    1202             :     }
    1203             : 
    1204             :  leave:
    1205           0 :   _gcry_mpi_release (pk.E.p);
    1206           0 :   _gcry_mpi_release (pk.E.a);
    1207           0 :   _gcry_mpi_release (pk.E.b);
    1208           0 :   _gcry_mpi_release (mpi_g);
    1209           0 :   point_free (&pk.E.G);
    1210           0 :   _gcry_mpi_release (pk.E.n);
    1211           0 :   _gcry_mpi_release (pk.E.h);
    1212           0 :   _gcry_mpi_release (mpi_q);
    1213           0 :   point_free (&pk.Q);
    1214           0 :   _gcry_mpi_release (data);
    1215           0 :   _gcry_mpi_release (sig_r);
    1216           0 :   _gcry_mpi_release (sig_s);
    1217           0 :   xfree (curvename);
    1218           0 :   sexp_release (l1);
    1219           0 :   _gcry_pk_util_free_encoding_ctx (&ctx);
    1220           0 :   if (DBG_CIPHER)
    1221           0 :     log_debug ("ecc_verify    => %s\n", rc?gpg_strerror (rc):"Good");
    1222           0 :   return rc;
    1223             : }
    1224             : 
    1225             : 
    1226             : /* ecdh raw is classic 2-round DH protocol published in 1976.
    1227             :  *
    1228             :  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
    1229             :  *
    1230             :  * As with any PK operation, encrypt version uses a public key and
    1231             :  * decrypt -- private.
    1232             :  *
    1233             :  * Symbols used below:
    1234             :  *     G - field generator point
    1235             :  *     d - private long-term scalar
    1236             :  *    dG - public long-term key
    1237             :  *     k - ephemeral scalar
    1238             :  *    kG - ephemeral public key
    1239             :  *   dkG - shared secret
    1240             :  *
    1241             :  * ecc_encrypt_raw description:
    1242             :  *   input:
    1243             :  *     data[0] : private scalar (k)
    1244             :  *   output: A new S-expression with the parameters:
    1245             :  *     s : shared point (kdG)
    1246             :  *     e : generated ephemeral public key (kG)
    1247             :  *
    1248             :  * ecc_decrypt_raw description:
    1249             :  *   input:
    1250             :  *     data[0] : a point kG (ephemeral public key)
    1251             :  *   output:
    1252             :  *     result[0] : shared point (kdG)
    1253             :  */
    1254             : static gcry_err_code_t
    1255           0 : ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
    1256             : {
    1257             :   unsigned int nbits;
    1258             :   gcry_err_code_t rc;
    1259             :   struct pk_encoding_ctx ctx;
    1260           0 :   gcry_sexp_t l1 = NULL;
    1261           0 :   char *curvename = NULL;
    1262           0 :   gcry_mpi_t mpi_g = NULL;
    1263           0 :   gcry_mpi_t mpi_q = NULL;
    1264           0 :   gcry_mpi_t mpi_s = NULL;
    1265           0 :   gcry_mpi_t mpi_e = NULL;
    1266           0 :   gcry_mpi_t data = NULL;
    1267             :   ECC_public_key pk;
    1268           0 :   mpi_ec_t ec = NULL;
    1269           0 :   int flags = 0;
    1270             : 
    1271           0 :   memset (&pk, 0, sizeof pk);
    1272           0 :   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
    1273             :                                    (nbits = ecc_get_nbits (keyparms)));
    1274             : 
    1275             :   /* Look for flags. */
    1276           0 :   l1 = sexp_find_token (keyparms, "flags", 0);
    1277           0 :   if (l1)
    1278             :     {
    1279           0 :       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
    1280           0 :       if (rc)
    1281           0 :         goto leave;
    1282             :     }
    1283           0 :   sexp_release (l1);
    1284           0 :   l1 = NULL;
    1285             : 
    1286             :   /*
    1287             :    * Extract the data.
    1288             :    */
    1289           0 :   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
    1290           0 :   if (rc)
    1291           0 :     goto leave;
    1292           0 :   if (mpi_is_opaque (data))
    1293             :     {
    1294           0 :       rc = GPG_ERR_INV_DATA;
    1295           0 :       goto leave;
    1296             :     }
    1297             : 
    1298             :   /*
    1299             :    * Extract the key.
    1300             :    */
    1301           0 :   rc = sexp_extract_param (keyparms, NULL,
    1302           0 :                            (flags & PUBKEY_FLAG_DJB_TWEAK)?
    1303             :                            "-p?a?b?g?n?h?/q" : "-p?a?b?g?n?h?+q",
    1304             :                            &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, &pk.E.h,
    1305             :                            &mpi_q, NULL);
    1306           0 :   if (rc)
    1307           0 :     goto leave;
    1308           0 :   if (mpi_g)
    1309             :     {
    1310           0 :       point_init (&pk.E.G);
    1311           0 :       rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
    1312           0 :       if (rc)
    1313           0 :         goto leave;
    1314             :     }
    1315             :   /* Add missing parameters using the optional curve parameter.  */
    1316           0 :   l1 = sexp_find_token (keyparms, "curve", 5);
    1317           0 :   if (l1)
    1318             :     {
    1319           0 :       curvename = sexp_nth_string (l1, 1);
    1320           0 :       if (curvename)
    1321             :         {
    1322           0 :           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
    1323           0 :           if (rc)
    1324           0 :             goto leave;
    1325             :         }
    1326             :     }
    1327             :   /* Guess required fields if a curve parameter has not been given.  */
    1328           0 :   if (!curvename)
    1329             :     {
    1330           0 :       pk.E.model = MPI_EC_WEIERSTRASS;
    1331           0 :       pk.E.dialect = ECC_DIALECT_STANDARD;
    1332           0 :       if (!pk.E.h)
    1333           0 :         pk.E.h = mpi_const (MPI_C_ONE);
    1334             :     }
    1335             : 
    1336             :   /*
    1337             :    * Tweak the scalar bits by cofactor and number of bits of the field.
    1338             :    * It assumes the cofactor is a power of 2.
    1339             :    */
    1340           0 :   if ((flags & PUBKEY_FLAG_DJB_TWEAK))
    1341             :     {
    1342             :       int i;
    1343             : 
    1344           0 :       for (i = 0; i < mpi_get_nbits (pk.E.h) - 1; i++)
    1345           0 :         mpi_clear_bit (data, i);
    1346           0 :       mpi_set_highbit (data, mpi_get_nbits (pk.E.p) - 1);
    1347             :     }
    1348           0 :   if (DBG_CIPHER)
    1349           0 :     log_mpidump ("ecc_encrypt data", data);
    1350             : 
    1351           0 :   if (DBG_CIPHER)
    1352             :     {
    1353           0 :       log_debug ("ecc_encrypt info: %s/%s\n",
    1354             :                  _gcry_ecc_model2str (pk.E.model),
    1355             :                  _gcry_ecc_dialect2str (pk.E.dialect));
    1356           0 :       if (pk.E.name)
    1357           0 :         log_debug  ("ecc_encrypt name: %s\n", pk.E.name);
    1358           0 :       log_printmpi ("ecc_encrypt    p", pk.E.p);
    1359           0 :       log_printmpi ("ecc_encrypt    a", pk.E.a);
    1360           0 :       log_printmpi ("ecc_encrypt    b", pk.E.b);
    1361           0 :       log_printpnt ("ecc_encrypt  g",   &pk.E.G, NULL);
    1362           0 :       log_printmpi ("ecc_encrypt    n", pk.E.n);
    1363           0 :       log_printmpi ("ecc_encrypt    h", pk.E.h);
    1364           0 :       log_printmpi ("ecc_encrypt    q", mpi_q);
    1365             :     }
    1366           0 :   if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q)
    1367             :     {
    1368           0 :       rc = GPG_ERR_NO_OBJ;
    1369           0 :       goto leave;
    1370             :     }
    1371             : 
    1372             :   /* Compute the encrypted value.  */
    1373           0 :   ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, flags,
    1374             :                                     pk.E.p, pk.E.a, pk.E.b);
    1375             : 
    1376             :   /* Convert the public key.  */
    1377           0 :   if (mpi_q)
    1378             :     {
    1379           0 :       point_init (&pk.Q);
    1380           0 :       if (ec->model == MPI_EC_MONTGOMERY)
    1381           0 :         rc = _gcry_ecc_mont_decodepoint (mpi_q, ec, &pk.Q);
    1382             :       else
    1383           0 :         rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
    1384           0 :       if (rc)
    1385           0 :         goto leave;
    1386             :     }
    1387             : 
    1388             :   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
    1389             :   {
    1390             :     mpi_point_struct R;  /* Result that we return.  */
    1391             :     gcry_mpi_t x, y;
    1392             :     unsigned char *rawmpi;
    1393             :     unsigned int rawmpilen;
    1394             : 
    1395           0 :     x = mpi_new (0);
    1396           0 :     if (ec->model == MPI_EC_MONTGOMERY)
    1397           0 :       y = NULL;
    1398             :     else
    1399           0 :       y = mpi_new (0);
    1400             : 
    1401           0 :     point_init (&R);
    1402             : 
    1403             :     /* R = kQ  <=>  R = kdG  */
    1404           0 :     _gcry_mpi_ec_mul_point (&R, data, &pk.Q, ec);
    1405             : 
    1406           0 :     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
    1407             :       {
    1408             :         /*
    1409             :          * Here, X is 0.  In the X25519 computation on Curve25519, X0
    1410             :          * function maps infinity to zero.  So, when PUBKEY_FLAG_DJB_TWEAK
    1411             :          * is enabled, return the result of 0 not raising an error.
    1412             :          *
    1413             :          * This is a corner case.  It never occurs with properly
    1414             :          * generated public keys, but it might happen with blindly
    1415             :          * imported public key which might not follow the key
    1416             :          * generation procedure.
    1417             :          */
    1418           0 :         if (!(flags & PUBKEY_FLAG_DJB_TWEAK))
    1419             :           { /* It's not for X25519, then, the input data was simply wrong.  */
    1420           0 :             rc = GPG_ERR_INV_DATA;
    1421           0 :             goto leave;
    1422             :           }
    1423             :       }
    1424           0 :     if (y)
    1425           0 :       mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
    1426             :     else
    1427             :       {
    1428           0 :         rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
    1429           0 :         if (!rawmpi)
    1430           0 :           rc = gpg_err_code_from_syserror ();
    1431             :         else
    1432             :           {
    1433           0 :             rawmpi[0] = 0x40;
    1434           0 :             rawmpilen++;
    1435           0 :             mpi_s = mpi_new (0);
    1436           0 :             mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8);
    1437             :           }
    1438             :       }
    1439             : 
    1440             :     /* R = kG */
    1441           0 :     _gcry_mpi_ec_mul_point (&R, data, &pk.E.G, ec);
    1442             : 
    1443           0 :     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
    1444             :       {
    1445           0 :         rc = GPG_ERR_INV_DATA;
    1446           0 :         goto leave;
    1447             :       }
    1448           0 :     if (y)
    1449           0 :       mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
    1450             :     else
    1451             :       {
    1452           0 :         rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
    1453           0 :         if (!rawmpi)
    1454           0 :           rc = gpg_err_code_from_syserror ();
    1455             :         else
    1456             :           {
    1457           0 :             rawmpi[0] = 0x40;
    1458           0 :             rawmpilen++;
    1459           0 :             mpi_e = mpi_new (0);
    1460           0 :             mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8);
    1461             :           }
    1462             :       }
    1463             : 
    1464             : 
    1465           0 :     mpi_free (x);
    1466           0 :     mpi_free (y);
    1467             : 
    1468           0 :     point_free (&R);
    1469             :   }
    1470             : 
    1471           0 :   if (!rc)
    1472           0 :     rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
    1473             : 
    1474             :  leave:
    1475           0 :   _gcry_mpi_release (pk.E.p);
    1476           0 :   _gcry_mpi_release (pk.E.a);
    1477           0 :   _gcry_mpi_release (pk.E.b);
    1478           0 :   _gcry_mpi_release (mpi_g);
    1479           0 :   point_free (&pk.E.G);
    1480           0 :   _gcry_mpi_release (pk.E.n);
    1481           0 :   _gcry_mpi_release (pk.E.h);
    1482           0 :   _gcry_mpi_release (mpi_q);
    1483           0 :   point_free (&pk.Q);
    1484           0 :   _gcry_mpi_release (data);
    1485           0 :   _gcry_mpi_release (mpi_s);
    1486           0 :   _gcry_mpi_release (mpi_e);
    1487           0 :   xfree (curvename);
    1488           0 :   sexp_release (l1);
    1489           0 :   _gcry_mpi_ec_free (ec);
    1490           0 :   _gcry_pk_util_free_encoding_ctx (&ctx);
    1491           0 :   if (DBG_CIPHER)
    1492           0 :     log_debug ("ecc_encrypt    => %s\n", gpg_strerror (rc));
    1493           0 :   return rc;
    1494             : }
    1495             : 
    1496             : 
    1497             : /*  input:
    1498             :  *     data[0] : a point kG (ephemeral public key)
    1499             :  *   output:
    1500             :  *     resaddr[0] : shared point kdG
    1501             :  *
    1502             :  *  see ecc_encrypt_raw for details.
    1503             :  */
    1504             : static gcry_err_code_t
    1505           0 : ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
    1506             : {
    1507             :   unsigned int nbits;
    1508             :   gpg_err_code_t rc;
    1509             :   struct pk_encoding_ctx ctx;
    1510           0 :   gcry_sexp_t l1 = NULL;
    1511           0 :   gcry_mpi_t data_e = NULL;
    1512             :   ECC_secret_key sk;
    1513           0 :   gcry_mpi_t mpi_g = NULL;
    1514           0 :   char *curvename = NULL;
    1515           0 :   mpi_ec_t ec = NULL;
    1516             :   mpi_point_struct kG;
    1517             :   mpi_point_struct R;
    1518           0 :   gcry_mpi_t r = NULL;
    1519           0 :   int flags = 0;
    1520             : 
    1521           0 :   memset (&sk, 0, sizeof sk);
    1522           0 :   point_init (&kG);
    1523           0 :   point_init (&R);
    1524             : 
    1525           0 :   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
    1526             :                                    (nbits = ecc_get_nbits (keyparms)));
    1527             : 
    1528             :   /* Look for flags. */
    1529           0 :   l1 = sexp_find_token (keyparms, "flags", 0);
    1530           0 :   if (l1)
    1531             :     {
    1532           0 :       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
    1533           0 :       if (rc)
    1534           0 :         goto leave;
    1535             :     }
    1536           0 :   sexp_release (l1);
    1537           0 :   l1 = NULL;
    1538             : 
    1539             :   /*
    1540             :    * Extract the data.
    1541             :    */
    1542           0 :   rc = _gcry_pk_util_preparse_encval (s_data, ecc_names, &l1, &ctx);
    1543           0 :   if (rc)
    1544           0 :     goto leave;
    1545           0 :   rc = sexp_extract_param (l1, NULL, "e", &data_e, NULL);
    1546           0 :   if (rc)
    1547           0 :     goto leave;
    1548           0 :   if (DBG_CIPHER)
    1549           0 :     log_printmpi ("ecc_decrypt  d_e", data_e);
    1550           0 :   if (mpi_is_opaque (data_e))
    1551             :     {
    1552           0 :       rc = GPG_ERR_INV_DATA;
    1553           0 :       goto leave;
    1554             :     }
    1555             : 
    1556             :   /*
    1557             :    * Extract the key.
    1558             :    */
    1559           0 :   rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?+d",
    1560             :                            &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
    1561             :                            &sk.E.h, &sk.d, NULL);
    1562           0 :   if (rc)
    1563           0 :     goto leave;
    1564           0 :   if (mpi_g)
    1565             :     {
    1566           0 :       point_init (&sk.E.G);
    1567           0 :       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
    1568           0 :       if (rc)
    1569           0 :         goto leave;
    1570             :     }
    1571             :   /* Add missing parameters using the optional curve parameter.  */
    1572           0 :   sexp_release (l1);
    1573           0 :   l1 = sexp_find_token (keyparms, "curve", 5);
    1574           0 :   if (l1)
    1575             :     {
    1576           0 :       curvename = sexp_nth_string (l1, 1);
    1577           0 :       if (curvename)
    1578             :         {
    1579           0 :           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
    1580           0 :           if (rc)
    1581           0 :             goto leave;
    1582             :         }
    1583             :     }
    1584             :   /* Guess required fields if a curve parameter has not been given.  */
    1585           0 :   if (!curvename)
    1586             :     {
    1587           0 :       sk.E.model = MPI_EC_WEIERSTRASS;
    1588           0 :       sk.E.dialect = ECC_DIALECT_STANDARD;
    1589           0 :       if (!sk.E.h)
    1590           0 :         sk.E.h = mpi_const (MPI_C_ONE);
    1591             :     }
    1592           0 :   if (DBG_CIPHER)
    1593             :     {
    1594           0 :       log_debug ("ecc_decrypt info: %s/%s\n",
    1595             :                  _gcry_ecc_model2str (sk.E.model),
    1596             :                  _gcry_ecc_dialect2str (sk.E.dialect));
    1597           0 :       if (sk.E.name)
    1598           0 :         log_debug  ("ecc_decrypt name: %s\n", sk.E.name);
    1599           0 :       log_printmpi ("ecc_decrypt    p", sk.E.p);
    1600           0 :       log_printmpi ("ecc_decrypt    a", sk.E.a);
    1601           0 :       log_printmpi ("ecc_decrypt    b", sk.E.b);
    1602           0 :       log_printpnt ("ecc_decrypt  g",   &sk.E.G, NULL);
    1603           0 :       log_printmpi ("ecc_decrypt    n", sk.E.n);
    1604           0 :       log_printmpi ("ecc_decrypt    h", sk.E.h);
    1605           0 :       if (!fips_mode ())
    1606           0 :         log_printmpi ("ecc_decrypt    d", sk.d);
    1607             :     }
    1608           0 :   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d)
    1609             :     {
    1610           0 :       rc = GPG_ERR_NO_OBJ;
    1611           0 :       goto leave;
    1612             :     }
    1613             : 
    1614             : 
    1615           0 :   ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, flags,
    1616             :                                     sk.E.p, sk.E.a, sk.E.b);
    1617             : 
    1618             :   /*
    1619             :    * Compute the plaintext.
    1620             :    */
    1621           0 :   if (ec->model == MPI_EC_MONTGOMERY)
    1622           0 :     rc = _gcry_ecc_mont_decodepoint (data_e, ec, &kG);
    1623             :   else
    1624           0 :     rc = _gcry_ecc_os2ec (&kG, data_e);
    1625           0 :   if (rc)
    1626           0 :     goto leave;
    1627             : 
    1628           0 :   if (DBG_CIPHER)
    1629           0 :     log_printpnt ("ecc_decrypt    kG", &kG, NULL);
    1630             : 
    1631           0 :   if (!(flags & PUBKEY_FLAG_DJB_TWEAK)
    1632             :       /* For X25519, by its definition, validation should not be done.  */
    1633           0 :       && !_gcry_mpi_ec_curve_point (&kG, ec))
    1634             :     {
    1635           0 :       rc = GPG_ERR_INV_DATA;
    1636           0 :       goto leave;
    1637             :     }
    1638             : 
    1639             :   /* R = dkG */
    1640           0 :   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec);
    1641             : 
    1642             :   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
    1643             :   {
    1644             :     gcry_mpi_t x, y;
    1645             : 
    1646           0 :     x = mpi_new (0);
    1647           0 :     if (ec->model == MPI_EC_MONTGOMERY)
    1648           0 :       y = NULL;
    1649             :     else
    1650           0 :       y = mpi_new (0);
    1651             : 
    1652           0 :     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
    1653             :       {
    1654           0 :         rc = GPG_ERR_INV_DATA;
    1655           0 :         goto leave;
    1656             :         /*
    1657             :          * Note for X25519.
    1658             :          *
    1659             :          * By the definition of X25519, this is the case where X25519
    1660             :          * returns 0, mapping infinity to zero.  However, we
    1661             :          * deliberately let it return an error.
    1662             :          *
    1663             :          * For X25519 ECDH, comming here means that it might be
    1664             :          * decrypted by anyone with the shared secret of 0 (the result
    1665             :          * of this function could be always 0 by other scalar values,
    1666             :          * other than the private key of SK.D).
    1667             :          *
    1668             :          * So, it looks like an encrypted message but it can be
    1669             :          * decrypted by anyone, or at least something wrong
    1670             :          * happens.  Recipient should not proceed as if it were
    1671             :          * properly encrypted message.
    1672             :          *
    1673             :          * This handling is needed for our major usage of GnuPG,
    1674             :          * where it does the One-Pass Diffie-Hellman method,
    1675             :          * C(1, 1, ECC CDH), with an ephemeral key.
    1676             :          */
    1677             :       }
    1678             : 
    1679           0 :     if (y)
    1680           0 :       r = _gcry_ecc_ec2os (x, y, sk.E.p);
    1681             :     else
    1682             :       {
    1683             :         unsigned char *rawmpi;
    1684             :         unsigned int rawmpilen;
    1685             : 
    1686           0 :         rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1,
    1687             :                                              &rawmpilen, NULL);
    1688           0 :         if (!rawmpi)
    1689             :           {
    1690           0 :             rc = gpg_err_code_from_syserror ();
    1691           0 :             goto leave;
    1692             :           }
    1693             :         else
    1694             :           {
    1695           0 :             rawmpi[0] = 0x40;
    1696           0 :             rawmpilen++;
    1697           0 :             r = mpi_new (0);
    1698           0 :             mpi_set_opaque (r, rawmpi, rawmpilen*8);
    1699             :           }
    1700             :       }
    1701           0 :     if (!r)
    1702           0 :       rc = gpg_err_code_from_syserror ();
    1703             :     else
    1704           0 :       rc = 0;
    1705           0 :     mpi_free (x);
    1706           0 :     mpi_free (y);
    1707             :   }
    1708           0 :   if (DBG_CIPHER)
    1709           0 :     log_printmpi ("ecc_decrypt  res", r);
    1710             : 
    1711           0 :   if (!rc)
    1712           0 :     rc = sexp_build (r_plain, NULL, "(value %m)", r);
    1713             : 
    1714             :  leave:
    1715           0 :   point_free (&R);
    1716           0 :   point_free (&kG);
    1717           0 :   _gcry_mpi_release (r);
    1718           0 :   _gcry_mpi_release (sk.E.p);
    1719           0 :   _gcry_mpi_release (sk.E.a);
    1720           0 :   _gcry_mpi_release (sk.E.b);
    1721           0 :   _gcry_mpi_release (mpi_g);
    1722           0 :   point_free (&sk.E.G);
    1723           0 :   _gcry_mpi_release (sk.E.n);
    1724           0 :   _gcry_mpi_release (sk.E.h);
    1725           0 :   _gcry_mpi_release (sk.d);
    1726           0 :   _gcry_mpi_release (data_e);
    1727           0 :   xfree (curvename);
    1728           0 :   sexp_release (l1);
    1729           0 :   _gcry_mpi_ec_free (ec);
    1730           0 :   _gcry_pk_util_free_encoding_ctx (&ctx);
    1731           0 :   if (DBG_CIPHER)
    1732           0 :     log_debug ("ecc_decrypt    => %s\n", gpg_strerror (rc));
    1733           0 :   return rc;
    1734             : }
    1735             : 
    1736             : 
    1737             : /* Return the number of bits for the key described by PARMS.  On error
    1738             :  * 0 is returned.  The format of PARMS starts with the algorithm name;
    1739             :  * for example:
    1740             :  *
    1741             :  *   (ecc
    1742             :  *     (curve <name>)
    1743             :  *     (p <mpi>)
    1744             :  *     (a <mpi>)
    1745             :  *     (b <mpi>)
    1746             :  *     (g <mpi>)
    1747             :  *     (n <mpi>)
    1748             :  *     (q <mpi>))
    1749             :  *
    1750             :  * More parameters may be given. Either P or CURVE is needed.
    1751             :  */
    1752             : static unsigned int
    1753           0 : ecc_get_nbits (gcry_sexp_t parms)
    1754             : {
    1755             :   gcry_sexp_t l1;
    1756             :   gcry_mpi_t p;
    1757           0 :   unsigned int nbits = 0;
    1758             :   char *curve;
    1759             : 
    1760           0 :   l1 = sexp_find_token (parms, "p", 1);
    1761           0 :   if (!l1)
    1762             :     { /* Parameter P not found - check whether we have "curve".  */
    1763           0 :       l1 = sexp_find_token (parms, "curve", 5);
    1764           0 :       if (!l1)
    1765           0 :         return 0; /* Neither P nor CURVE found.  */
    1766             : 
    1767           0 :       curve = sexp_nth_string (l1, 1);
    1768           0 :       sexp_release (l1);
    1769           0 :       if (!curve)
    1770           0 :         return 0;  /* No curve name given (or out of core). */
    1771             : 
    1772           0 :       if (_gcry_ecc_fill_in_curve (0, curve, NULL, &nbits))
    1773           0 :         nbits = 0;
    1774           0 :       xfree (curve);
    1775             :     }
    1776             :   else
    1777             :     {
    1778           0 :       p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
    1779           0 :       sexp_release (l1);
    1780           0 :       if (p)
    1781             :         {
    1782           0 :           nbits = mpi_get_nbits (p);
    1783           0 :           _gcry_mpi_release (p);
    1784             :         }
    1785             :     }
    1786           0 :   return nbits;
    1787             : }
    1788             : 
    1789             : 
    1790             : /* See rsa.c for a description of this function.  */
    1791             : static gpg_err_code_t
    1792           0 : compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
    1793             : {
    1794             : #define N_COMPONENTS 7
    1795             :   static const char names[N_COMPONENTS] = "pabgnhq";
    1796             :   gpg_err_code_t rc;
    1797             :   gcry_sexp_t l1;
    1798             :   gcry_mpi_t values[N_COMPONENTS];
    1799             :   int idx;
    1800           0 :   char *curvename = NULL;
    1801           0 :   int flags = 0;
    1802           0 :   enum gcry_mpi_ec_models model = 0;
    1803           0 :   enum ecc_dialects dialect = 0;
    1804             : 
    1805             :   /* Clear the values first.  */
    1806           0 :   for (idx=0; idx < N_COMPONENTS; idx++)
    1807           0 :     values[idx] = NULL;
    1808             : 
    1809             : 
    1810             :   /* Look for flags. */
    1811           0 :   l1 = sexp_find_token (keyparms, "flags", 0);
    1812           0 :   if (l1)
    1813             :     {
    1814           0 :       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
    1815           0 :       if (rc)
    1816           0 :         goto leave;
    1817             :     }
    1818             : 
    1819             :   /* Extract the parameters.  */
    1820           0 :   if ((flags & PUBKEY_FLAG_PARAM))
    1821             :     {
    1822           0 :       if ((flags & PUBKEY_FLAG_DJB_TWEAK))
    1823           0 :         rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?/q",
    1824             :                                  &values[0], &values[1], &values[2],
    1825             :                                  &values[3], &values[4], &values[5],
    1826             :                                  &values[6], NULL);
    1827             :       else
    1828           0 :         rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?q",
    1829             :                                  &values[0], &values[1], &values[2],
    1830             :                                  &values[3], &values[4], &values[5],
    1831             :                                  &values[6], NULL);
    1832             :     }
    1833             :   else
    1834             :     {
    1835           0 :       if ((flags & PUBKEY_FLAG_DJB_TWEAK))
    1836           0 :         rc = sexp_extract_param (keyparms, NULL, "/q",
    1837             :                                  &values[6], NULL);
    1838             :       else
    1839           0 :         rc = sexp_extract_param (keyparms, NULL, "q",
    1840             :                                  &values[6], NULL);
    1841             :     }
    1842           0 :   if (rc)
    1843           0 :     goto leave;
    1844             : 
    1845             :   /* Check whether a curve parameter is available and use that to fill
    1846             :      in missing values.  */
    1847           0 :   sexp_release (l1);
    1848           0 :   l1 = sexp_find_token (keyparms, "curve", 5);
    1849           0 :   if (l1)
    1850             :     {
    1851           0 :       curvename = sexp_nth_string (l1, 1);
    1852           0 :       if (curvename)
    1853             :         {
    1854           0 :           rc = _gcry_ecc_update_curve_param (curvename,
    1855             :                                              &model, &dialect,
    1856             :                                              &values[0], &values[1], &values[2],
    1857             :                                              &values[3], &values[4], &values[5]);
    1858           0 :           if (rc)
    1859           0 :             goto leave;
    1860             :         }
    1861             :     }
    1862             : 
    1863             :   /* Guess required fields if a curve parameter has not been given.
    1864             :      FIXME: This is a crude hacks.  We need to fix that.  */
    1865           0 :   if (!curvename)
    1866             :     {
    1867           0 :       model = ((flags & PUBKEY_FLAG_EDDSA)
    1868             :                ? MPI_EC_EDWARDS
    1869           0 :                : MPI_EC_WEIERSTRASS);
    1870           0 :       dialect = ((flags & PUBKEY_FLAG_EDDSA)
    1871             :                  ? ECC_DIALECT_ED25519
    1872           0 :                  : ECC_DIALECT_STANDARD);
    1873           0 :       if (!values[5])
    1874           0 :         values[5] = mpi_const (MPI_C_ONE);
    1875             :     }
    1876             : 
    1877             :   /* Check that all parameters are known and normalize all MPIs (that
    1878             :      should not be required but we use an internal function later and
    1879             :      thus we better make 100% sure that they are normalized). */
    1880           0 :   for (idx = 0; idx < N_COMPONENTS; idx++)
    1881           0 :     if (!values[idx])
    1882             :       {
    1883           0 :         rc = GPG_ERR_NO_OBJ;
    1884           0 :         goto leave;
    1885             :       }
    1886             :     else
    1887           0 :       _gcry_mpi_normalize (values[idx]);
    1888             : 
    1889             :   /* Uncompress the public key with the exception of EdDSA where
    1890             :      compression is the default and we thus compute the keygrip using
    1891             :      the compressed version.  Because we don't support any non-eddsa
    1892             :      compression, the only thing we need to do is to compress
    1893             :      EdDSA.  */
    1894           0 :   if ((flags & PUBKEY_FLAG_DJB_TWEAK))
    1895             :     {
    1896           0 :       rc = _gcry_ecc_eddsa_ensure_compact (values[6], 256);
    1897           0 :       if (rc)
    1898           0 :         goto leave;
    1899             :     }
    1900             : 
    1901             :   /* Hash them all.  */
    1902           0 :   for (idx = 0; idx < N_COMPONENTS; idx++)
    1903             :     {
    1904             :       char buf[30];
    1905             : 
    1906           0 :       if (idx == 5)
    1907           0 :         continue;               /* Skip cofactor. */
    1908             : 
    1909           0 :       if (mpi_is_opaque (values[idx]))
    1910           0 :         {
    1911             :           const unsigned char *raw;
    1912             :           unsigned int n;
    1913             : 
    1914           0 :           raw = mpi_get_opaque (values[idx], &n);
    1915           0 :           n = (n + 7)/8;
    1916           0 :           snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], n);
    1917           0 :           _gcry_md_write (md, buf, strlen (buf));
    1918           0 :           _gcry_md_write (md, raw, n);
    1919           0 :           _gcry_md_write (md, ")", 1);
    1920             :         }
    1921             :       else
    1922             :         {
    1923             :           unsigned char *rawmpi;
    1924             :           unsigned int rawmpilen;
    1925             : 
    1926           0 :           rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
    1927           0 :           if (!rawmpi)
    1928             :             {
    1929           0 :               rc = gpg_err_code_from_syserror ();
    1930           0 :               goto leave;
    1931             :             }
    1932           0 :           snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
    1933           0 :           _gcry_md_write (md, buf, strlen (buf));
    1934           0 :           _gcry_md_write (md, rawmpi, rawmpilen);
    1935           0 :           _gcry_md_write (md, ")", 1);
    1936           0 :           xfree (rawmpi);
    1937             :         }
    1938             :     }
    1939             : 
    1940             :  leave:
    1941           0 :   xfree (curvename);
    1942           0 :   sexp_release (l1);
    1943           0 :   for (idx = 0; idx < N_COMPONENTS; idx++)
    1944           0 :     _gcry_mpi_release (values[idx]);
    1945             : 
    1946           0 :   return rc;
    1947             : #undef N_COMPONENTS
    1948             : }
    1949             : 
    1950             : 
    1951             : 
    1952             : /*
    1953             :    Low-level API helper functions.
    1954             :  */
    1955             : 
    1956             : /* This is the worker function for gcry_pubkey_get_sexp for ECC
    1957             :    algorithms.  Note that the caller has already stored NULL at
    1958             :    R_SEXP.  */
    1959             : gpg_err_code_t
    1960           0 : _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
    1961             : {
    1962             :   gpg_err_code_t rc;
    1963           0 :   gcry_mpi_t mpi_G = NULL;
    1964           0 :   gcry_mpi_t mpi_Q = NULL;
    1965             : 
    1966           0 :   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->h)
    1967           0 :     return GPG_ERR_BAD_CRYPT_CTX;
    1968             : 
    1969           0 :   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
    1970           0 :     return GPG_ERR_NO_SECKEY;
    1971             : 
    1972             :   /* Compute the public point if it is missing.  */
    1973           0 :   if (!ec->Q && ec->d)
    1974           0 :     ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL);
    1975             : 
    1976             :   /* Encode G and Q.  */
    1977           0 :   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
    1978           0 :   if (!mpi_G)
    1979             :     {
    1980           0 :       rc = GPG_ERR_BROKEN_PUBKEY;
    1981           0 :       goto leave;
    1982             :     }
    1983           0 :   if (!ec->Q)
    1984             :     {
    1985           0 :       rc = GPG_ERR_BAD_CRYPT_CTX;
    1986           0 :       goto leave;
    1987             :     }
    1988             : 
    1989           0 :   if (ec->dialect == ECC_DIALECT_ED25519)
    1990             :     {
    1991             :       unsigned char *encpk;
    1992             :       unsigned int encpklen;
    1993             : 
    1994           0 :       rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0,
    1995             :                                         &encpk, &encpklen);
    1996           0 :       if (rc)
    1997           0 :         goto leave;
    1998           0 :       mpi_Q = mpi_set_opaque (NULL, encpk, encpklen*8);
    1999           0 :       encpk = NULL;
    2000             :     }
    2001             :   else
    2002             :     {
    2003           0 :       mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
    2004             :     }
    2005           0 :   if (!mpi_Q)
    2006             :     {
    2007           0 :       rc = GPG_ERR_BROKEN_PUBKEY;
    2008           0 :       goto leave;
    2009             :     }
    2010             : 
    2011             :   /* Fixme: We should return a curve name instead of the parameters if
    2012             :      if know that they match a curve.  */
    2013             : 
    2014           0 :   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
    2015             :     {
    2016             :       /* Let's return a private key. */
    2017           0 :       rc = sexp_build (r_sexp, NULL,
    2018             :                        "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))",
    2019             :                        ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q, ec->d);
    2020             :     }
    2021           0 :   else if (ec->Q)
    2022             :     {
    2023             :       /* Let's return a public key.  */
    2024           0 :       rc = sexp_build (r_sexp, NULL,
    2025             :                        "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))",
    2026             :                        ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q);
    2027             :     }
    2028             :   else
    2029           0 :     rc = GPG_ERR_BAD_CRYPT_CTX;
    2030             : 
    2031             :  leave:
    2032           0 :   mpi_free (mpi_Q);
    2033           0 :   mpi_free (mpi_G);
    2034           0 :   return rc;
    2035             : }
    2036             : 
    2037             : 
    2038             : 
    2039             : /*
    2040             :      Self-test section.
    2041             :  */
    2042             : 
    2043             : static const char *
    2044           0 : selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
    2045             : {
    2046             :   /* Sample data from RFC 6979 section A.2.5, hash is of message "sample" */
    2047             :   static const char sample_data[] =
    2048             :     "(data (flags rfc6979)"
    2049             :     " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
    2050             :     /**/           "62113d8a62add1bf#))";
    2051             :   static const char sample_data_bad[] =
    2052             :     "(data (flags rfc6979)"
    2053             :     " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
    2054             :     /**/           "62113d8a62add1bf#))";
    2055             :   static const char signature_r[] =
    2056             :     "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716";
    2057             :   static const char signature_s[] =
    2058             :     "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8";
    2059             : 
    2060           0 :   const char *errtxt = NULL;
    2061             :   gcry_error_t err;
    2062           0 :   gcry_sexp_t data = NULL;
    2063           0 :   gcry_sexp_t data_bad = NULL;
    2064           0 :   gcry_sexp_t sig = NULL;
    2065           0 :   gcry_sexp_t l1 = NULL;
    2066           0 :   gcry_sexp_t l2 = NULL;
    2067           0 :   gcry_mpi_t r = NULL;
    2068           0 :   gcry_mpi_t s = NULL;
    2069           0 :   gcry_mpi_t calculated_r = NULL;
    2070           0 :   gcry_mpi_t calculated_s = NULL;
    2071             :   int cmp;
    2072             : 
    2073           0 :   err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
    2074           0 :   if (!err)
    2075           0 :     err = sexp_sscan (&data_bad, NULL,
    2076             :                       sample_data_bad, strlen (sample_data_bad));
    2077           0 :   if (!err)
    2078           0 :     err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
    2079           0 :   if (!err)
    2080           0 :     err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
    2081             : 
    2082           0 :   if (err)
    2083             :     {
    2084           0 :       errtxt = "converting data failed";
    2085           0 :       goto leave;
    2086             :     }
    2087             : 
    2088           0 :   err = _gcry_pk_sign (&sig, data, skey);
    2089           0 :   if (err)
    2090             :     {
    2091           0 :       errtxt = "signing failed";
    2092           0 :       goto leave;
    2093             :     }
    2094             : 
    2095             :   /* check against known signature */
    2096           0 :   errtxt = "signature validity failed";
    2097           0 :   l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
    2098           0 :   if (!l1)
    2099           0 :     goto leave;
    2100           0 :   l2 = _gcry_sexp_find_token (l1, "ecdsa", 0);
    2101           0 :   if (!l2)
    2102           0 :     goto leave;
    2103             : 
    2104           0 :   sexp_release (l1);
    2105           0 :   l1 = l2;
    2106             : 
    2107           0 :   l2 = _gcry_sexp_find_token (l1, "r", 0);
    2108           0 :   if (!l2)
    2109           0 :     goto leave;
    2110           0 :   calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
    2111           0 :   if (!calculated_r)
    2112           0 :     goto leave;
    2113             : 
    2114           0 :   sexp_release (l2);
    2115           0 :   l2 = _gcry_sexp_find_token (l1, "s", 0);
    2116           0 :   if (!l2)
    2117           0 :     goto leave;
    2118           0 :   calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
    2119           0 :   if (!calculated_s)
    2120           0 :     goto leave;
    2121             : 
    2122           0 :   errtxt = "known sig check failed";
    2123             : 
    2124           0 :   cmp = _gcry_mpi_cmp (r, calculated_r);
    2125           0 :   if (cmp)
    2126           0 :     goto leave;
    2127           0 :   cmp = _gcry_mpi_cmp (s, calculated_s);
    2128           0 :   if (cmp)
    2129           0 :     goto leave;
    2130             : 
    2131           0 :   errtxt = NULL;
    2132             : 
    2133             :   /* verify generated signature */
    2134           0 :   err = _gcry_pk_verify (sig, data, pkey);
    2135           0 :   if (err)
    2136             :     {
    2137           0 :       errtxt = "verify failed";
    2138           0 :       goto leave;
    2139             :     }
    2140           0 :   err = _gcry_pk_verify (sig, data_bad, pkey);
    2141           0 :   if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
    2142             :     {
    2143           0 :       errtxt = "bad signature not detected";
    2144           0 :       goto leave;
    2145             :     }
    2146             : 
    2147             : 
    2148             :  leave:
    2149           0 :   sexp_release (sig);
    2150           0 :   sexp_release (data_bad);
    2151           0 :   sexp_release (data);
    2152           0 :   sexp_release (l1);
    2153           0 :   sexp_release (l2);
    2154           0 :   mpi_release (r);
    2155           0 :   mpi_release (s);
    2156           0 :   mpi_release (calculated_r);
    2157           0 :   mpi_release (calculated_s);
    2158           0 :   return errtxt;
    2159             : }
    2160             : 
    2161             : 
    2162             : static gpg_err_code_t
    2163           0 : selftests_ecdsa (selftest_report_func_t report)
    2164             : {
    2165             :   const char *what;
    2166             :   const char *errtxt;
    2167             :   gcry_error_t err;
    2168           0 :   gcry_sexp_t skey = NULL;
    2169           0 :   gcry_sexp_t pkey = NULL;
    2170             : 
    2171           0 :   what = "convert";
    2172           0 :   err = sexp_sscan (&skey, NULL, sample_secret_key_secp256,
    2173             :                     strlen (sample_secret_key_secp256));
    2174           0 :   if (!err)
    2175           0 :     err = sexp_sscan (&pkey, NULL, sample_public_key_secp256,
    2176             :                       strlen (sample_public_key_secp256));
    2177           0 :   if (err)
    2178             :     {
    2179           0 :       errtxt = _gcry_strerror (err);
    2180           0 :       goto failed;
    2181             :     }
    2182             : 
    2183           0 :   what = "key consistency";
    2184           0 :   err = ecc_check_secret_key(skey);
    2185           0 :   if (err)
    2186             :     {
    2187           0 :       errtxt = _gcry_strerror (err);
    2188           0 :       goto failed;
    2189             :     }
    2190             : 
    2191           0 :   what = "sign";
    2192           0 :   errtxt = selftest_sign (pkey, skey);
    2193           0 :   if (errtxt)
    2194           0 :     goto failed;
    2195             : 
    2196           0 :   sexp_release(pkey);
    2197           0 :   sexp_release(skey);
    2198           0 :   return 0; /* Succeeded. */
    2199             : 
    2200             :  failed:
    2201           0 :   sexp_release(pkey);
    2202           0 :   sexp_release(skey);
    2203           0 :   if (report)
    2204           0 :     report ("pubkey", GCRY_PK_ECC, what, errtxt);
    2205           0 :   return GPG_ERR_SELFTEST_FAILED;
    2206             : }
    2207             : 
    2208             : 
    2209             : /* Run a full self-test for ALGO and return 0 on success.  */
    2210             : static gpg_err_code_t
    2211           0 : run_selftests (int algo, int extended, selftest_report_func_t report)
    2212             : {
    2213             :   (void)extended;
    2214             : 
    2215           0 :   if (algo != GCRY_PK_ECC)
    2216           0 :     return GPG_ERR_PUBKEY_ALGO;
    2217             : 
    2218           0 :   return selftests_ecdsa (report);
    2219             : }
    2220             : 
    2221             : 
    2222             : 
    2223             : 
    2224             : gcry_pk_spec_t _gcry_pubkey_spec_ecc =
    2225             :   {
    2226             :     GCRY_PK_ECC, { 0, 1 },
    2227             :     (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
    2228             :     "ECC", ecc_names,
    2229             :     "pabgnhq", "pabgnhqd", "sw", "rs", "pabgnhq",
    2230             :     ecc_generate,
    2231             :     ecc_check_secret_key,
    2232             :     ecc_encrypt_raw,
    2233             :     ecc_decrypt_raw,
    2234             :     ecc_sign,
    2235             :     ecc_verify,
    2236             :     ecc_get_nbits,
    2237             :     run_selftests,
    2238             :     compute_keygrip,
    2239             :     _gcry_ecc_get_curve,
    2240             :     _gcry_ecc_get_param_sexp
    2241             :   };

Generated by: LCOV version 1.12