summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cipher/ecc.c155
-rw-r--r--cipher/elgamal.c63
-rw-r--r--cipher/pubkey.c48
-rw-r--r--cipher/rsa.c61
-rw-r--r--src/cipher-proto.h8
-rw-r--r--tests/basic.c4
6 files changed, 215 insertions, 124 deletions
diff --git a/cipher/ecc.c b/cipher/ecc.c
index f98a5cc2..051308f0 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -1786,46 +1786,106 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
* result[0] : shared point (kdG)
*/
static gcry_err_code_t
-ecc_encrypt_raw (int algo, gcry_sexp_t *r_result, gcry_mpi_t k,
- gcry_mpi_t *pkey, int flags)
+ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
{
- gpg_err_code_t rc;
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ char *curvename = NULL;
+ gcry_mpi_t mpi_g = NULL;
+ gcry_mpi_t mpi_q = NULL;
+ gcry_mpi_t mpi_s = NULL;
+ gcry_mpi_t mpi_e = NULL;
+ gcry_mpi_t data = NULL;
ECC_public_key pk;
- mpi_ec_t ctx;
- gcry_mpi_t s, e;
-
- (void)algo;
- (void)flags;
+ mpi_ec_t ec = NULL;
- if (!k
- || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
- return GPG_ERR_BAD_MPI;
+ memset (&pk, 0, sizeof pk);
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+ ecc_get_nbits (keyparms));
- pk.E.model = MPI_EC_WEIERSTRASS;
- pk.E.p = pkey[0];
- pk.E.a = pkey[1];
- pk.E.b = pkey[2];
- point_init (&pk.E.G);
- rc = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
+ /*
+ * Extract the data.
+ */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("ecc_encrypt data", data);
+ if (mpi_is_opaque (data))
{
- point_free (&pk.E.G);
- return rc;
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
}
- pk.E.n = pkey[4];
- point_init (&pk.Q);
- rc = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
+
+
+ /*
+ * Extract the key.
+ */
+ rc = _gcry_pk_util_extract_mpis (keyparms, "-p?a?b?g?n?+q",
+ &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n,
+ &mpi_q, NULL);
if (rc)
+ goto leave;
+ if (mpi_g)
{
- point_free (&pk.E.G);
- point_free (&pk.Q);
- return rc;
+ point_init (&pk.E.G);
+ rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
+ if (rc)
+ goto leave;
+ }
+ /* Add missing parameters using the optional curve parameter. */
+ gcry_sexp_release (l1);
+ l1 = gcry_sexp_find_token (keyparms, "curve", 5);
+ if (l1)
+ {
+ curvename = gcry_sexp_nth_string (l1, 1);
+ if (curvename)
+ {
+ rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
+ if (rc)
+ return rc;
+ }
+ }
+ /* Guess required fields if a curve parameter has not been given. */
+ if (!curvename)
+ {
+ pk.E.model = MPI_EC_WEIERSTRASS;
+ pk.E.dialect = ECC_DIALECT_STANDARD;
}
- ctx = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
- pk.E.p, pk.E.a, pk.E.b);
- s = mpi_alloc (mpi_get_nlimbs (pk.E.p));
- e = mpi_alloc (mpi_get_nlimbs (pk.E.p));
+ if (DBG_CIPHER)
+ {
+ log_debug ("ecc_encrypt info: %s/%s\n",
+ _gcry_ecc_model2str (pk.E.model),
+ _gcry_ecc_dialect2str (pk.E.dialect));
+ if (pk.E.name)
+ log_debug ("ecc_encrypt name: %s\n", pk.E.name);
+ log_printmpi ("ecc_encrypt p", pk.E.p);
+ log_printmpi ("ecc_encrypt a", pk.E.a);
+ log_printmpi ("ecc_encrypt b", pk.E.b);
+ log_printpnt ("ecc_encrypt g", &pk.E.G, NULL);
+ log_printmpi ("ecc_encrypt n", pk.E.n);
+ log_printmpi ("ecc_encrypt q", mpi_q);
+ }
+ if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+
+ /* Convert the public key. */
+ if (mpi_q)
+ {
+ point_init (&pk.Q);
+ rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
+ if (rc)
+ goto leave;
+ }
+
+ /* Compute the encrypted value. */
+ ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
+ pk.E.p, pk.E.a, pk.E.b);
/* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
{
@@ -1838,18 +1898,18 @@ ecc_encrypt_raw (int algo, gcry_sexp_t *r_result, gcry_mpi_t k,
point_init (&R);
/* R = kQ <=> R = kdG */
- _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
+ _gcry_mpi_ec_mul_point (&R, data, &pk.Q, ec);
- if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
- s = _gcry_ecc_ec2os (x, y, pk.E.p);
+ mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
/* R = kG */
- _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
+ _gcry_mpi_ec_mul_point (&R, data, &pk.E.G, ec);
- if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
- e = _gcry_ecc_ec2os (x, y, pk.E.p);
+ mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
mpi_free (x);
mpi_free (y);
@@ -1857,17 +1917,30 @@ ecc_encrypt_raw (int algo, gcry_sexp_t *r_result, gcry_mpi_t k,
point_free (&R);
}
- _gcry_mpi_ec_free (ctx);
+ rc = gcry_sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))",
+ mpi_s, mpi_e);
+
+ leave:
+ gcry_mpi_release (pk.E.p);
+ gcry_mpi_release (pk.E.a);
+ gcry_mpi_release (pk.E.b);
+ gcry_mpi_release (mpi_g);
point_free (&pk.E.G);
+ gcry_mpi_release (pk.E.n);
+ gcry_mpi_release (mpi_q);
point_free (&pk.Q);
-
- rc = gcry_sexp_build (r_result, NULL, "(enc-val(ecdh(s%m)(e%m)))", s, e);
- mpi_free (s);
- mpi_free (e);
-
+ gcry_mpi_release (data);
+ gcry_mpi_release (mpi_s);
+ gcry_mpi_release (mpi_e);
+ gcry_free (curvename);
+ _gcry_mpi_ec_free (ec);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("ecc_encrypt => %s\n", gpg_strerror (rc));
return rc;
}
+
/* input:
* data[0] : a point kG (ephemeral public key)
* output:
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index a4f5ce3d..37182874 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -755,30 +755,57 @@ elg_check_secret_key (int algo, gcry_mpi_t *skey)
static gcry_err_code_t
-elg_encrypt (int algo, gcry_sexp_t *r_result,
- gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
+elg_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
{
gcry_err_code_t rc;
- ELG_public_key pk;
- gcry_mpi_t a, b;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t mpi_a = NULL;
+ gcry_mpi_t mpi_b = NULL;
+ gcry_mpi_t data = NULL;
+ ELG_public_key pk = { NULL, NULL, NULL };
- (void)algo;
- (void)flags;
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+ elg_get_nbits (keyparms));
- if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
- rc = GPG_ERR_BAD_MPI;
- else
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("elg_encrypt data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = _gcry_pk_util_extract_mpis (keyparms, "pgy", &pk.p, &pk.g, &pk.y, NULL);
+ if (rc)
+ return rc;
+ if (DBG_CIPHER)
{
- pk.p = pkey[0];
- pk.g = pkey[1];
- pk.y = pkey[2];
- a = mpi_alloc (mpi_get_nlimbs (pk.p));
- b = mpi_alloc (mpi_get_nlimbs (pk.p));
- do_encrypt (a, b, data, &pk);
- rc = gcry_sexp_build (r_result, NULL, "(enc-val(elg(a%m)(b%m)))", a, b);
- mpi_free (a);
- mpi_free (b);
+ log_mpidump ("elg_encrypt p", pk.p);
+ log_mpidump ("elg_encrypt g", pk.g);
+ log_mpidump ("elg_encrypt y", pk.y);
}
+
+ /* Do Elgamal computation and build result. */
+ mpi_a = gcry_mpi_new (0);
+ mpi_b = gcry_mpi_new (0);
+ do_encrypt (mpi_a, mpi_b, data, &pk);
+ rc = gcry_sexp_build (r_ciph, NULL, "(enc-val(elg(a%m)(b%m)))", mpi_a, mpi_b);
+
+ leave:
+ gcry_mpi_release (mpi_a);
+ gcry_mpi_release (mpi_b);
+ gcry_mpi_release (pk.p);
+ gcry_mpi_release (pk.g);
+ gcry_mpi_release (pk.y);
+ gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("elg_encrypt => %s\n", gpg_strerror (rc));
return rc;
}
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index c0f4ab27..8a46e4e5 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -926,60 +926,22 @@ gcry_error_t
gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
{
gcry_err_code_t rc;
- gcry_mpi_t *pkey = NULL;
- gcry_mpi_t data = NULL;
- struct pk_encoding_ctx ctx;
- gcry_pk_spec_t *spec = NULL;
- int i;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms;
*r_ciph = NULL;
- /* Get the key. */
- rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_ENCR, NULL, &pkey, &spec, NULL);
- if (rc)
- goto leave;
-
- gcry_assert (spec);
-
- /* Get the stuff we want to encrypt. */
- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
- rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
if (rc)
goto leave;
- /* In fips mode DBG_CIPHER will never evaluate to true but as an
- extra failsafe protection we explicitly test for fips mode
- here. */
- if (DBG_CIPHER && !fips_mode ())
- {
- log_debug ("pubkey_encrypt: algo=%d\n", spec->algo);
- for(i = 0; i < pubkey_get_npkey (spec->algo); i++)
- log_mpidump (" pkey", pkey[i]);
- log_mpidump (" data", data);
- }
-
if (spec->encrypt)
- rc = spec->encrypt (spec->algo, r_ciph, data, pkey, ctx.flags);
+ rc = spec->encrypt (r_ciph, s_data, keyparms);
else
rc = GPG_ERR_NOT_IMPLEMENTED;
-
- /* if (DBG_CIPHER && !fips_mode ()) */
- /* { */
- /* for (i = 0; i < pubkey_get_nenc (spec->algo); i++) */
- /* log_mpidump (" encr", ciph[i]); */
- /* } */
-
leave:
- mpi_free (data);
- if (pkey)
- {
- release_mpi_array (pkey);
- gcry_free (pkey);
- }
-
- gcry_free (ctx.label);
-
+ gcry_sexp_release (keyparms);
return gcry_error (rc);
}
diff --git a/cipher/rsa.c b/cipher/rsa.c
index db644520..51480df3 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -861,39 +861,68 @@ rsa_check_secret_key (int algo, gcry_mpi_t *skey)
static gcry_err_code_t
-rsa_encrypt (int algo, gcry_sexp_t *r_result, gcry_mpi_t data,
- gcry_mpi_t *pkey, int flags)
+rsa_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
{
- gpg_err_code_t rc;
- RSA_public_key pk;
- gcry_mpi_t result;
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t data = NULL;
+ RSA_public_key pk = {NULL, NULL};
+ gcry_mpi_t ciph = NULL;
- (void)algo;
- (void)flags;
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+ rsa_get_nbits (keyparms));
- pk.n = pkey[0];
- pk.e = pkey[1];
- result = mpi_alloc (mpi_get_nlimbs (pk.n));
- public (result, data, &pk);
- if ((flags & PUBKEY_FLAG_FIXEDLEN))
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("rsa_encrypt data", data);
+ if (mpi_is_opaque (data))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+
+ /* Extract the key. */
+ rc = _gcry_pk_util_extract_mpis (keyparms, "ne", &pk.n, &pk.e, NULL);
+ if (rc)
+ return rc;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("rsa_encrypt n", pk.n);
+ log_mpidump ("rsa_encrypt e", pk.e);
+ }
+
+ /* Do RSA computation and build result. */
+ ciph = gcry_mpi_new (0);
+ public (ciph, data, &pk);
+ if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN))
{
/* We need to make sure to return the correct length to avoid
problems with missing leading zeroes. */
unsigned char *em;
size_t emlen = (mpi_get_nbits (pk.n)+7)/8;
- rc = _gcry_mpi_to_octet_string (&em, NULL, result, emlen);
+ rc = _gcry_mpi_to_octet_string (&em, NULL, ciph, emlen);
if (!rc)
{
- rc = gcry_sexp_build (r_result, NULL,
+ rc = gcry_sexp_build (r_ciph, NULL,
"(enc-val(rsa(a%b)))", (int)emlen, em);
gcry_free (em);
}
}
else
- rc = gcry_sexp_build (r_result, NULL, "(enc-val(rsa(a%m)))", result);
+ rc = gcry_sexp_build (r_ciph, NULL, "(enc-val(rsa(a%m)))", ciph);
- mpi_free (result);
+ leave:
+ gcry_mpi_release (ciph);
+ gcry_mpi_release (pk.n);
+ gcry_mpi_release (pk.e);
+ gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("rsa_encrypt => %s\n", gpg_strerror (rc));
return rc;
}
diff --git a/src/cipher-proto.h b/src/cipher-proto.h
index 8892ddfe..c570e5ff 100644
--- a/src/cipher-proto.h
+++ b/src/cipher-proto.h
@@ -58,11 +58,9 @@ typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
gcry_mpi_t *skey);
/* Type for the pk_encrypt function. */
-typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
- gcry_sexp_t *r_result,
- gcry_mpi_t data,
- gcry_mpi_t *pkey,
- int flags);
+typedef gcry_err_code_t (*gcry_pk_encrypt_t) (gcry_sexp_t *r_ciph,
+ gcry_sexp_t s_data,
+ gcry_sexp_t keyparms);
/* Type for the pk_decrypt function. */
typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
diff --git a/tests/basic.c b/tests/basic.c
index 13a8600b..ee049006 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -3486,7 +3486,9 @@ static void
check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
{
gcry_error_t rc;
- gcry_sexp_t plain, ciph, data;
+ gcry_sexp_t plain = NULL;
+ gcry_sexp_t ciph = NULL;
+ gcry_sexp_t data = NULL;
int dataidx;
static struct
{