summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2021-09-30 11:51:08 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2021-10-02 11:09:09 +0900
commit04950cb8c41603e7201be8040d397011ad64fef6 (patch)
treeef3b3d2613e54ff2b278d6a5f89a027751139736
parent2cca08573f1d23ce4522eb4987044ae0bce6a4ab (diff)
downloadlibgcrypt-04950cb8c41603e7201be8040d397011ad64fef6.tar.gz
experiment: Change use of pkey_open for classic ECC.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--cipher/pkey-ecc-nist.c34
-rw-r--r--cipher/pkey.c27
-rw-r--r--src/gcrypt.h.in7
-rw-r--r--tests/t-ecc-cdh.c4
-rw-r--r--tests/t-ecdsa.c18
5 files changed, 80 insertions, 10 deletions
diff --git a/cipher/pkey-ecc-nist.c b/cipher/pkey-ecc-nist.c
index b10bdf57..969e7643 100644
--- a/cipher/pkey-ecc-nist.c
+++ b/cipher/pkey-ecc-nist.c
@@ -56,6 +56,24 @@ get_curve_name (int curve)
}
}
+static int
+select_md_algo (int curve)
+{
+ switch (curve)
+ {
+ case GCRY_PKEY_CURVE_NIST_P224:
+ return GCRY_MD_SHA224;
+ case GCRY_PKEY_CURVE_NIST_P256:
+ return GCRY_MD_SHA256;
+ case GCRY_PKEY_CURVE_NIST_P384:
+ return GCRY_MD_SHA384;
+ case GCRY_PKEY_CURVE_NIST_P521:
+ return GCRY_MD_SHA512;
+ default:
+ return GCRY_MD_SHA512;
+ }
+}
+
gcry_error_t
_gcry_pkey_nist_sign (gcry_pkey_hd_t h,
int num_in, const unsigned char *const in[],
@@ -68,6 +86,7 @@ _gcry_pkey_nist_sign (gcry_pkey_hd_t h,
gcry_sexp_t s_sig= NULL;
gcry_sexp_t s_tmp, s_tmp2;
const char *curve;
+ int md_algo;
const char *md_name;
if (num_in != 2) /* For now, k should be specified by the caller. */
@@ -96,7 +115,12 @@ _gcry_pkey_nist_sign (gcry_pkey_hd_t h,
if (err)
return err;
- md_name = _gcry_md_algo_name (h->ecc.md_algo);
+ if (h->ecc.md_algo < 0)
+ md_algo = select_md_algo (h->ecc.curve);
+ else
+ md_algo = h->ecc.md_algo;
+
+ md_name = _gcry_md_algo_name (md_algo);
if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
@@ -210,6 +234,7 @@ _gcry_pkey_nist_verify (gcry_pkey_hd_t h,
gcry_sexp_t s_msg= NULL;
gcry_sexp_t s_sig= NULL;
const char *curve;
+ int md_algo;
const char *md_name;
if (num_in != 4) /* For now, k should be specified by the caller. */
@@ -225,7 +250,12 @@ _gcry_pkey_nist_verify (gcry_pkey_hd_t h,
if (err)
return err;
- md_name = _gcry_md_algo_name (h->ecc.md_algo);
+ if (h->ecc.md_algo < 0)
+ md_algo = select_md_algo (h->ecc.curve);
+ else
+ md_algo = h->ecc.md_algo;
+
+ md_name = _gcry_md_algo_name (md_algo);
if ((h->flags & GCRY_PKEY_FLAG_PREHASH))
err = sexp_build (&s_msg, NULL,
diff --git a/cipher/pkey.c b/cipher/pkey.c
index 55030562..273115bf 100644
--- a/cipher/pkey.c
+++ b/cipher/pkey.c
@@ -29,6 +29,10 @@
#include "gcrypt-int.h"
#include "pkey-internal.h"
+/*
+ * GCRY_PKEY_ECC, classic_curve, Qx, x_len, Qy, y_len [, sk, sk_len]
+ * GCRY_PKEY_ECC, modern_curve, pk, pk_len [, sk, sk_len]
+ */
gcry_error_t
_gcry_pkey_vopen (gcry_pkey_hd_t *h_p, int algo, unsigned int flags,
va_list arg_ptr)
@@ -56,6 +60,7 @@ _gcry_pkey_vopen (gcry_pkey_hd_t *h_p, int algo, unsigned int flags,
int curve;
unsigned char *pk;
unsigned char *sk;
+ int is_classic = 0;
curve = va_arg (arg_ptr, int);
if (curve == GCRY_PKEY_CURVE_ED25519 || curve == GCRY_PKEY_CURVE_ED448)
@@ -65,7 +70,11 @@ _gcry_pkey_vopen (gcry_pkey_hd_t *h_p, int algo, unsigned int flags,
|| curve == GCRY_PKEY_CURVE_NIST_P256
|| curve == GCRY_PKEY_CURVE_NIST_P384
|| curve == GCRY_PKEY_CURVE_NIST_P521)
- h->ecc.md_algo = va_arg (arg_ptr, int);
+ {
+ is_classic = 1;
+ h->flags |= GCRY_PKEY_FLAG_CLASSIC_CURVE;
+ h->ecc.md_algo = -1;
+ }
else
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
if (err)
@@ -76,7 +85,7 @@ _gcry_pkey_vopen (gcry_pkey_hd_t *h_p, int algo, unsigned int flags,
h->ecc.curve = curve;
- if (h->ecc.md_algo)
+ if (is_classic)
{ /* NIST curves */
unsigned char *x, *y;
size_t x_len, y_len;
@@ -355,8 +364,18 @@ _gcry_pkey_ctl (gcry_pkey_hd_t h, int cmd, void *buffer, size_t buflen)
{
gcry_error_t err = 0;
- (void)h; (void)cmd; (void)buffer; (void)buflen;
- /* FIXME: Not yet implemented anything. */
+ /* FIXME: Only implemented md_algo setting for classic ECC. */
+
+ if (h->algo == GCRY_PKEY_ECC)
+ if ((h->flags & GCRY_PKEY_FLAG_CLASSIC_CURVE))
+ if (cmd == GCRY_PKEY_CTL_DIGEST)
+ {
+ (void)buflen;
+ h->ecc.md_algo = (int)(uintptr_t)buffer;
+ return err;
+ }
+
+ err = gpg_error (GPG_ERR_INV_OP);
return err;
}
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index cf129202..a55d50e4 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -1226,9 +1226,16 @@ enum gcry_pkey_algos
GCRY_PKEY_ELG = 20
};
+enum gcry_pkey_ctl
+ {
+ GCRY_PKEY_CTL_DIGEST
+ };
+
#define GCRY_PKEY_FLAG_SECRET (1 << 0) /* It has secret part. */
#define GCRY_PKEY_FLAG_PREHASH (1 << 1)
#define GCRY_PKEY_FLAG_CONTEXT (1 << 2)
+/**/
+#define GCRY_PKEY_FLAG_CLASSIC_CURVE (1 << 31) /* Internal use. */
enum gcry_pkey_curves
{
diff --git a/tests/t-ecc-cdh.c b/tests/t-ecc-cdh.c
index b630ee03..946c9c04 100644
--- a/tests/t-ecc-cdh.c
+++ b/tests/t-ecc-cdh.c
@@ -252,7 +252,7 @@ one_test (int testno, const char *curvename,
}
flags |= GCRY_PKEY_FLAG_SECRET;
- err = gcry_pkey_open (&h0, GCRY_PKEY_ECC, flags, curve, GCRY_MD_SHA256,
+ err = gcry_pkey_open (&h0, GCRY_PKEY_ECC, flags, curve,
buffer, buflen, buffer2, buflen2, buffer3, buflen3);
if (err)
{
@@ -262,7 +262,7 @@ one_test (int testno, const char *curvename,
}
flags &= ~GCRY_PKEY_FLAG_SECRET;
- err = gcry_pkey_open (&h1, GCRY_PKEY_ECC, flags, curve, GCRY_MD_SHA256,
+ err = gcry_pkey_open (&h1, GCRY_PKEY_ECC, flags, curve,
buffer, buflen, buffer2, buflen2);
if (err)
{
diff --git a/tests/t-ecdsa.c b/tests/t-ecdsa.c
index 017a0bc6..b6c40ae2 100644
--- a/tests/t-ecdsa.c
+++ b/tests/t-ecdsa.c
@@ -285,7 +285,7 @@ one_test (const char *curvename, const char *sha_alg,
}
flags |= GCRY_PKEY_FLAG_SECRET;
- err = gcry_pkey_open (&h0, GCRY_PKEY_ECC, flags, curve, md_algo,
+ err = gcry_pkey_open (&h0, GCRY_PKEY_ECC, flags, curve,
buffer, buflen, buffer2, buflen2, buffer3, buflen3);
if (err)
{
@@ -295,7 +295,7 @@ one_test (const char *curvename, const char *sha_alg,
}
flags &= ~GCRY_PKEY_FLAG_SECRET;
- err = gcry_pkey_open (&h1, GCRY_PKEY_ECC, flags, curve, md_algo,
+ err = gcry_pkey_open (&h1, GCRY_PKEY_ECC, flags, curve,
buffer, buflen, buffer2, buflen2);
if (err)
{
@@ -304,6 +304,20 @@ one_test (const char *curvename, const char *sha_alg,
goto leave;
}
+ err = gcry_pkey_ctl (h0, GCRY_PKEY_CTL_DIGEST, (void *)md_algo, 0);
+ if (err)
+ {
+ fail ("error setting digest for PKEY: %s", gpg_strerror (err));
+ goto leave;
+ }
+
+ err = gcry_pkey_ctl (h1, GCRY_PKEY_CTL_DIGEST, (void *)md_algo, 0);
+ if (err)
+ {
+ fail ("error setting digest for PKEY: %s", gpg_strerror (err));
+ goto leave;
+ }
+
xfree (buffer);
xfree (buffer2);
xfree (buffer3);