summaryrefslogtreecommitdiffstats
path: root/g10/pkglue.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2011-01-25 20:28:25 +0100
committerWerner Koch <wk@gnupg.org>2011-01-25 20:28:25 +0100
commitd879c287ac1da7990c97b911018d63410c60433c (patch)
tree7a213af1c1f9f801b06a46350fe9473a6893a49d /g10/pkglue.c
parentMore ECDH code cleanups (diff)
downloadgnupg2-d879c287ac1da7990c97b911018d63410c60433c.tar.xz
gnupg2-d879c287ac1da7990c97b911018d63410c60433c.zip
Started with some code cleanups in ECDH.
The goal is to have the ECDH code more uniform with the other algorithms. Also make error messages and variable names more similar to other places.
Diffstat (limited to 'g10/pkglue.c')
-rw-r--r--g10/pkglue.c70
1 files changed, 57 insertions, 13 deletions
diff --git a/g10/pkglue.c b/g10/pkglue.c
index f5c85976f..3aba4e4c1 100644
--- a/g10/pkglue.c
+++ b/g10/pkglue.c
@@ -28,6 +28,7 @@
#include "util.h"
#include "pkglue.h"
#include "main.h"
+#include "options.h"
/* FIXME: Better chnage the fucntion name because mpi_ is used by
gcrypt macros. */
@@ -156,26 +157,39 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(elg(p%m)(g%m)(y%m)))",
pkey[0], pkey[1], pkey[2]);
+ /* Put DATA into a simplified S-expression. */
+ if (rc || gcry_sexp_build (&s_data, NULL, "%m", data))
+ BUG ();
+
}
else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E)
{
rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(rsa(n%m)(e%m)))",
pkey[0], pkey[1]);
+ /* Put DATA into a simplified S-expression. */
+ if (rc || gcry_sexp_build (&s_data, NULL, "%m", data))
+ BUG ();
}
else if (algo == PUBKEY_ALGO_ECDH)
{
- return pk_ecdh_encrypt (resarr, pk_fp, data, pkey);
+ gcry_mpi_t k;
+
+ rc = pk_ecdh_generate_ephemeral_key (pkey, &k);
+ if (rc)
+ return rc;
+
+ /* Now use the ephemeral secret to compute the shared point. */
+ rc = gcry_sexp_build (&s_pkey, NULL,
+ "(public-key(ecdh(c%m)(q%m)(p%m)))",
+ pkey[0], pkey[1], pkey[2]);
+ /* Put K into a simplified S-expression. */
+ if (rc || gcry_sexp_build (&s_data, NULL, "%m", k))
+ BUG ();
}
else
- return GPG_ERR_PUBKEY_ALGO;
-
- if (rc)
- BUG ();
+ return gpg_error (GPG_ERR_PUBKEY_ALGO);
- /* Put the data into a simple list. */
- if (gcry_sexp_build (&s_data, NULL, "%m", data))
- BUG ();
/* Pass it to libgcrypt. */
rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
@@ -184,12 +198,42 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
if (rc)
;
- else
- { /* Add better error handling or make gnupg use S-Exp directly. */
+ else if (algo == PUBKEY_ALGO_ECDH)
+ {
+ gcry_mpi_t shared, public, result;
+
+ /* Get the shared point and the ephemeral public key. */
+ shared = mpi_from_sexp (s_ciph, "a");
+ public = mpi_from_sexp (s_ciph, "b");
+ gcry_sexp_release (s_ciph);
+ s_ciph = NULL;
+ if (DBG_CIPHER)
+ {
+ log_debug ("ECDH ephemeral key:");
+ gcry_mpi_dump (public);
+ log_printf ("\n");
+ }
+
+ result = NULL;
+ rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared,
+ pk_fp, data, pkey, &result);
+ gcry_mpi_release (shared);
+ if (!rc)
+ {
+ resarr[0] = public;
+ resarr[1] = result;
+ }
+ else
+ {
+ gcry_mpi_release (public);
+ gcry_mpi_release (result);
+ }
+ }
+ else /* Elgamal or RSA case. */
+ { /* Fixme: Add better error handling or make gnupg use
+ S-expressions directly. */
resarr[0] = mpi_from_sexp (s_ciph, "a");
- if (algo != GCRY_PK_RSA
- && algo != GCRY_PK_RSA_E
- && algo != PUBKEY_ALGO_ECDH)
+ if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E)
resarr[1] = mpi_from_sexp (s_ciph, "b");
}