From 04950cb8c41603e7201be8040d397011ad64fef6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 30 Sep 2021 11:51:08 +0900 Subject: experiment: Change use of pkey_open for classic ECC. Signed-off-by: NIIBE Yutaka --- cipher/pkey-ecc-nist.c | 34 ++++++++++++++++++++++++++++++++-- cipher/pkey.c | 27 +++++++++++++++++++++++---- src/gcrypt.h.in | 7 +++++++ tests/t-ecc-cdh.c | 4 ++-- tests/t-ecdsa.c | 18 ++++++++++++++++-- 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); -- cgit v1.2.1