Пример #1
0
void
gcry_mpi_ec_mul (gcry_mpi_point_t w, gcry_mpi_t n, gcry_mpi_point_t u,
                 gcry_ctx_t ctx)
{
  _gcry_mpi_ec_mul_point (w, n, u,
                          _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
}
Пример #2
0
void
gcry_mpi_ec_add (gcry_mpi_point_t w,
                 gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx)
{
  _gcry_mpi_ec_add_points (w, u, v,
                           _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
}
Пример #3
0
int
gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
                        gcry_ctx_t ctx)
{
  return _gcry_mpi_ec_get_affine (x, y, point,
                                  _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
}
Пример #4
0
void
gcry_log_debugpnt (const char *text, mpi_point_t point, gcry_ctx_t ctx)
{
  mpi_ec_t ec = ctx? _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC) : NULL;

  _gcry_mpi_point_log (text, point, ec);
}
Пример #5
0
gcry_mpi_t
_gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
{
  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);

  if (!strcmp (name, "p") && ec->p)
    return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
  if (!strcmp (name, "a") && ec->a)
    return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
  if (!strcmp (name, "b") && ec->b)
    return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b);
  if (!strcmp (name, "n") && ec->n)
    return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n);
  if (!strcmp (name, "d") && ec->d)
    return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);

  /* Return a requested point coordinate.  */
  if (!strcmp (name, "g.x") && ec->G && ec->G->x)
    return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
  if (!strcmp (name, "g.y") && ec->G && ec->G->y)
    return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
  if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
    return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
  if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
    return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);

  /* If a point has been requested, return it in standard encoding.  */
  if (!strcmp (name, "g") && ec->G)
    return _gcry_mpi_ec_ec2os (ec->G, ec);
  if (!strcmp (name, "q"))
    {
      /* If only the private key is given, compute the public key.  */
      if (!ec->Q && ec->d && ec->G && ec->p && ec->a)
        {
          ec->Q = gcry_mpi_point_new (0);
          _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
        }

      if (ec->Q)
        return _gcry_mpi_ec_ec2os (ec->Q, ec);
    }

  return NULL;
}
Пример #6
0
/* This function returns a new context for elliptic curve operations
   based on the field GF(p).  P is the prime specifying this field, A
   is the first coefficient.  On success the new context is stored at
   R_CTX and 0 is returned; on error NULL is stored at R_CTX and an
   error code is returned.  The context needs to be released using
   gcry_ctx_release.  This is an internal fucntions.  */
gpg_err_code_t
_gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a)
{
  gcry_ctx_t ctx;
  mpi_ec_t ec;

  *r_ctx = NULL;
  if (!p || !a || !mpi_cmp_ui (a, 0))
    return GPG_ERR_EINVAL;

  ctx = _gcry_ctx_alloc (CONTEXT_TYPE_EC, sizeof *ec, ec_deinit);
  if (!ctx)
    return gpg_err_code_from_syserror ();
  ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
  ec_p_init (ec, p, a);

  *r_ctx = ctx;
  return 0;
}
Пример #7
0
gpg_err_code_t
_gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
                        gcry_ctx_t ctx)
{
  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);

  if (!strcmp (name, "g"))
    {
      gcry_mpi_point_release (ec->G);
      ec->G = point_copy (newvalue);
    }
  else if (!strcmp (name, "q"))
    {
      gcry_mpi_point_release (ec->Q);
      ec->Q = point_copy (newvalue);
    }
  else
    return GPG_ERR_UNKNOWN_NAME;

  return 0;
}
Пример #8
0
gpg_err_code_t
_gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
                      gcry_ctx_t ctx)
{
  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);

  if (!strcmp (name, "p"))
    {
      mpi_free (ec->p);
      ec->p = mpi_copy (newvalue);
      ec_get_reset (ec);
    }
  else if (!strcmp (name, "a"))
    {
      mpi_free (ec->a);
      ec->a = mpi_copy (newvalue);
      ec_get_reset (ec);
    }
  else if (!strcmp (name, "b"))
    {
      mpi_free (ec->b);
      ec->b = mpi_copy (newvalue);
    }
  else if (!strcmp (name, "n"))
    {
      mpi_free (ec->n);
      ec->n = mpi_copy (newvalue);
    }
  else if (!strcmp (name, "d"))
    {
      mpi_free (ec->d);
      ec->d = mpi_copy (newvalue);
    }
  else
    return GPG_ERR_UNKNOWN_NAME;

  return 0;
}
Пример #9
0
gcry_mpi_point_t
_gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy)
{
  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);

  (void)copy;  /* Not used.  */

  if (!strcmp (name, "g") && ec->G)
    return point_copy (ec->G);
  if (!strcmp (name, "q"))
    {
      /* If only the private key is given, compute the public key.  */
      if (!ec->Q && ec->d && ec->G && ec->p && ec->a)
        {
          ec->Q = gcry_mpi_point_new (0);
          _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
        }

      if (ec->Q)
        return point_copy (ec->Q);
    }

  return NULL;
}
Пример #10
0
int
gcry_mpi_ec_curve_point (gcry_mpi_point_t point, gcry_ctx_t ctx)
{
  return _gcry_mpi_ec_curve_point
    (point, _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
}
Пример #11
0
void
gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx)
{
  _gcry_mpi_ec_dup_point (w, u, _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
}
Пример #12
0
/* This function creates a new context for elliptic curve operations.
   Either KEYPARAM or CURVENAME must be given.  If both are given and
   KEYPARAM has no curve parameter, CURVENAME is used to add missing
   parameters.  On success 0 is returned and the new context stored at
   R_CTX.  On error NULL is stored at R_CTX and an error code is
   returned.  The context needs to be released using
   gcry_ctx_release.  */
gpg_err_code_t
_gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
                  gcry_sexp_t keyparam, const char *curvename)
{
  gpg_err_code_t errc;
  gcry_ctx_t ctx = NULL;
  enum gcry_mpi_ec_models model = MPI_EC_WEIERSTRASS;
  enum ecc_dialects dialect = ECC_DIALECT_STANDARD;
  gcry_mpi_t p = NULL;
  gcry_mpi_t a = NULL;
  gcry_mpi_t b = NULL;
  gcry_mpi_point_t G = NULL;
  gcry_mpi_t n = NULL;
  gcry_mpi_point_t Q = NULL;
  gcry_mpi_t d = NULL;
  int flags = 0;
  gcry_sexp_t l1;

  *r_ctx = NULL;

  if (keyparam)
    {
      /* Parse an optional flags list.  */
      l1 = sexp_find_token (keyparam, "flags", 0);
      if (l1)
        {
          errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
          sexp_release (l1);
          l1 = NULL;
          if (errc)
            goto leave;
        }

      /* Check whether a curve name was given.  */
      l1 = sexp_find_token (keyparam, "curve", 5);

      /* If we don't have a curve name or if override parameters have
         explicitly been requested, parse them.  */
      if (!l1 || (flags & PUBKEY_FLAG_PARAM))
        {
          errc = mpi_from_keyparam (&p, keyparam, "p");
          if (errc)
            goto leave;
          errc = mpi_from_keyparam (&a, keyparam, "a");
          if (errc)
            goto leave;
          errc = mpi_from_keyparam (&b, keyparam, "b");
          if (errc)
            goto leave;
          errc = point_from_keyparam (&G, keyparam, "g", NULL);
          if (errc)
            goto leave;
          errc = mpi_from_keyparam (&n, keyparam, "n");
          if (errc)
            goto leave;
        }
    }
  else
    l1 = NULL; /* No curvename.  */

  /* Check whether a curve parameter is available and use that to fill
     in missing values.  If no curve parameter is available try an
     optional provided curvename.  If only the curvename has been
     given use that one. */
  if (l1 || curvename)
    {
      char *name;
      elliptic_curve_t *E;

      if (l1)
        {
          name = sexp_nth_string (l1, 1);
          sexp_release (l1);
          if (!name)
            {
              errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
              goto leave;
            }
        }
      else
        name = NULL;

      E = xtrycalloc (1, sizeof *E);
      if (!E)
        {
          errc = gpg_err_code_from_syserror ();
          xfree (name);
          goto leave;
        }

      errc = _gcry_ecc_fill_in_curve (0, name? name : curvename, E, NULL);
      xfree (name);
      if (errc)
        {
          xfree (E);
          goto leave;
        }

      model = E->model;
      dialect = E->dialect;

      if (!p)
        {
          p = E->p;
          E->p = NULL;
        }
      if (!a)
        {
          a = E->a;
          E->a = NULL;
        }
      if (!b)
        {
          b = E->b;
          E->b = NULL;
        }
      if (!G)
        {
          G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z);
          E->G.x = NULL;
          E->G.y = NULL;
          E->G.z = NULL;
        }
      if (!n)
        {
          n = E->n;
          E->n = NULL;
        }
      _gcry_ecc_curve_free (E);
      xfree (E);
    }


  errc = _gcry_mpi_ec_p_new (&ctx, model, dialect, flags, p, a, b);
  if (!errc)
    {
      mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);

      if (b)
        {
          mpi_free (ec->b);
          ec->b = b;
          b = NULL;
        }
      if (G)
        {
          ec->G = G;
          G = NULL;
        }
      if (n)
        {
          ec->n = n;
          n = NULL;
        }

      /* Now that we know the curve name we can look for the public key
         Q.  point_from_keyparam needs to know the curve parameters so
         that it is able to use the correct decompression.  Parsing
         the private key D could have been done earlier but it is less
         surprising if we do it here as well.  */
      if (keyparam)
        {
          errc = point_from_keyparam (&Q, keyparam, "q", ec);
          if (errc)
            goto leave;
          errc = mpi_from_keyparam (&d, keyparam, "d");
          if (errc)
            goto leave;
        }

      if (Q)
        {
          ec->Q = Q;
          Q = NULL;
        }
      if (d)
        {
          ec->d = d;
          d = NULL;
        }

      *r_ctx = ctx;
      ctx = NULL;
    }

 leave:
  _gcry_ctx_release (ctx);
  mpi_free (p);
  mpi_free (a);
  mpi_free (b);
  _gcry_mpi_point_release (G);
  mpi_free (n);
  _gcry_mpi_point_release (Q);
  mpi_free (d);
  return errc;
}