summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2021-06-17 11:08:23 +0200
committerWerner Koch <wk@gnupg.org>2021-08-22 14:58:44 +0200
commit64e4a6a2a43698a604e3933ce261ff77063d64e8 (patch)
treef57ef8c8fe348437e971eba7c973f7a2e9a1367d
parent84ad6ac02c45a00daad87c614daf278c76ef9a9d (diff)
downloadlibgcrypt-64e4a6a2a43698a604e3933ce261ff77063d64e8.tar.gz
ecc: Fix bug in gcry_pk_get_param for Curve25519.
* cipher/ecc-curves.c (_gcry_ecc_get_param_sexp): Simplify. * cipher/pubkey.c (map_algo): Also map EDDSA to ECC. * tests/curves.c (check_get_params): Add simple param lookup tests by for all curves. -- There is no actual need to compute affine ccordinates given that we already got them in the curve parameter table. Thus most code could be removed and thus won't run into the problem getting an Y coordinate for a Montgomery curve. EDDSA was not mapped to ECC: The map function was written a year before EDDSA and I obviously forgot to add it. GnuPG-bug-id: 5490 Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--cipher/ecc-curves.c26
-rw-r--r--cipher/pubkey.c1
-rw-r--r--tests/curves.c146
3 files changed, 151 insertions, 22 deletions
diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index 900b668a..d1a1c329 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
@@ -1379,45 +1379,27 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
gcry_sexp_t
_gcry_ecc_get_param_sexp (const char *name)
{
- unsigned int nbits;
elliptic_curve_t E;
- mpi_ec_t ctx;
- gcry_mpi_t g_x, g_y;
gcry_mpi_t pkey[5];
gcry_sexp_t result;
- int i;
memset (&E, 0, sizeof E);
- if (_gcry_ecc_fill_in_curve (0, name, &E, &nbits))
+ if (_gcry_ecc_fill_in_curve (0, name, &E, NULL))
return NULL;
- g_x = mpi_new (0);
- g_y = mpi_new (0);
- ctx = _gcry_mpi_ec_p_internal_new (E.model,
- E.dialect,
- 0,
- E.p, E.a, E.b);
- if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
- log_fatal ("ecc get param: Failed to get affine coordinates\n");
- _gcry_mpi_ec_free (ctx);
- _gcry_mpi_point_free_parts (&E.G);
-
pkey[0] = E.p;
pkey[1] = E.a;
pkey[2] = E.b;
- pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p);
+ pkey[3] = _gcry_ecc_ec2os (E.G.x, E.G.y, E.p);
pkey[4] = E.n;
- mpi_free (g_x);
- mpi_free (g_y);
-
if (sexp_build (&result, NULL,
"(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)))",
pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], E.h))
result = NULL;
- for (i=0; i < DIM (pkey); i++)
- _gcry_mpi_release (pkey[i]);
+ _gcry_ecc_curve_free (&E);
+ _gcry_mpi_release (pkey[3]);
return result;
}
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 4c07e33b..3ca09932 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -61,6 +61,7 @@ map_algo (int algo)
case GCRY_PK_RSA_S: return GCRY_PK_RSA;
case GCRY_PK_ELG_E: return GCRY_PK_ELG;
case GCRY_PK_ECDSA: return GCRY_PK_ECC;
+ case GCRY_PK_EDDSA: return GCRY_PK_ECC;
case GCRY_PK_ECDH: return GCRY_PK_ECC;
default: return algo;
}
diff --git a/tests/curves.c b/tests/curves.c
index 55ba7422..e5186dbf 100644
--- a/tests/curves.c
+++ b/tests/curves.c
@@ -132,6 +132,134 @@ check_matching (void)
static void
check_get_params (void)
{
+ static struct {
+ int algo;
+ const char *name;
+ int error_expected;
+ } tv[] =
+ {
+ { GCRY_PK_ECC, "Ed25519" },
+ { GCRY_PK_ECC, "1.3.6.1.4.1.11591.15.1" },
+ { GCRY_PK_ECC, "1.3.101.112" },
+
+ { GCRY_PK_ECC, "Curve25519" },
+ { GCRY_PK_ECC, "1.3.6.1.4.1.3029.1.5.1" },
+ { GCRY_PK_ECC, "1.3.101.110" },
+ { GCRY_PK_ECC, "X25519" },
+
+ { GCRY_PK_ECC, "Ed448" },
+ { GCRY_PK_ECC, "X448" },
+ { GCRY_PK_ECC, "1.3.101.113" },
+ { GCRY_PK_ECC, "1.3.101.111" },
+
+ { GCRY_PK_ECC, "NIST P-192" },
+ { GCRY_PK_ECC, "1.2.840.10045.3.1.1" },
+ { GCRY_PK_ECC, "prime192v1" },
+ { GCRY_PK_ECC, "secp192r1" },
+ { GCRY_PK_ECC, "nistp192" },
+
+ { GCRY_PK_ECC, "NIST P-224" },
+ { GCRY_PK_ECC, "secp224r1" },
+ { GCRY_PK_ECC, "1.3.132.0.33" },
+ { GCRY_PK_ECC, "nistp224" },
+
+ { GCRY_PK_ECC, "NIST P-256" },
+ { GCRY_PK_ECC, "1.2.840.10045.3.1.7" },
+ { GCRY_PK_ECC, "prime256v1" },
+ { GCRY_PK_ECC, "secp256r1" },
+ { GCRY_PK_ECC, "nistp256" },
+
+ { GCRY_PK_ECC, "NIST P-384" },
+ { GCRY_PK_ECC, "secp384r1" },
+ { GCRY_PK_ECC, "1.3.132.0.34" },
+ { GCRY_PK_ECC, "nistp384" },
+
+ { GCRY_PK_ECC, "NIST P-521" },
+ { GCRY_PK_ECC, "secp521r1" },
+ { GCRY_PK_ECC, "1.3.132.0.35" },
+ { GCRY_PK_ECC, "nistp521" },
+
+ { GCRY_PK_ECC, "brainpoolP160r1" },
+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1" },
+ { GCRY_PK_ECC, "brainpoolP192r1" },
+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3" },
+ { GCRY_PK_ECC, "brainpoolP224r1" },
+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5" },
+ { GCRY_PK_ECC, "brainpoolP256r1" },
+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7" },
+ { GCRY_PK_ECC, "brainpoolP320r1" },
+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9" },
+ { GCRY_PK_ECC, "brainpoolP384r1" },
+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11"},
+ { GCRY_PK_ECC, "brainpoolP512r1" },
+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13"},
+
+ { GCRY_PK_ECC, "GOST2001-test" },
+ { GCRY_PK_ECC, "1.2.643.2.2.35.0" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-A" },
+ { GCRY_PK_ECC, "1.2.643.2.2.35.1" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-B" },
+ { GCRY_PK_ECC, "1.2.643.2.2.35.2" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-C" },
+ { GCRY_PK_ECC, "1.2.643.2.2.35.3" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-A" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-XchA" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-C" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-XchB" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-A" },
+ { GCRY_PK_ECC, "1.2.643.2.2.36.0" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-C" },
+ { GCRY_PK_ECC, "1.2.643.2.2.36.1" },
+
+ /* Noet that GOST2012-256-tc26-A" is only in the curve alias
+ * list but has no parameter entry. */
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-A" },
+ { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.2" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-A" },
+ { GCRY_PK_ECC, "GOST2012-256-tc26-B" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-B" },
+ { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.3" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-B" },
+ { GCRY_PK_ECC, "GOST2012-256-tc26-C" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-C" },
+ { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.4" },
+ { GCRY_PK_ECC, "GOST2001-CryptoPro-C" },
+ { GCRY_PK_ECC, "GOST2012-256-tc26-D" },
+
+ { GCRY_PK_ECC, "GOST2012-512-test" },
+ { GCRY_PK_ECC, "GOST2012-test" },
+ { GCRY_PK_ECC, "GOST2012-512-test" },
+ { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.0" },
+ { GCRY_PK_ECC, "GOST2012-512-tc26-A" },
+ { GCRY_PK_ECC, "GOST2012-tc26-A" },
+ { GCRY_PK_ECC, "GOST2012-512-tc26-B" },
+ { GCRY_PK_ECC, "GOST2012-tc26-B" },
+ { GCRY_PK_ECC, "GOST2012-512-tc26-A" },
+ { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.1" },
+ { GCRY_PK_ECC, "GOST2012-512-tc26-B" },
+ { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.2" },
+ { GCRY_PK_ECC, "GOST2012-512-tc26-C" },
+ { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.3" },
+
+ { GCRY_PK_ECC, "secp256k1" },
+ { GCRY_PK_ECC, "1.3.132.0.10" },
+
+ { GCRY_PK_ECC, "sm2p256v1" },
+ { GCRY_PK_ECC, "1.2.156.10197.1.301" },
+
+ /* Check also the ECC algo mapping. */
+ { GCRY_PK_ECDSA, "Ed25519" },
+ { GCRY_PK_EDDSA, "Ed25519" },
+ { GCRY_PK_ECDH, "Ed25519" },
+ { GCRY_PK_ECDSA, "Curve25519" },
+ { GCRY_PK_EDDSA, "Curve25519" },
+ { GCRY_PK_ECDH, "Curve25519" },
+ { GCRY_PK_ECC, "NoSuchCurve", 1 },
+ { GCRY_PK_RSA, "rsa", 1 },
+ { GCRY_PK_ELG, "elg", 1 },
+ { GCRY_PK_DSA, "dsa", 1 }
+ };
+ int idx;
gcry_sexp_t param;
const char *name;
@@ -164,6 +292,24 @@ check_get_params (void)
sample_key_2_curve, name);
gcry_sexp_release (param);
+
+ /* Some simple tests */
+ for (idx=0; idx < DIM (tv); idx++)
+ {
+ param = gcry_pk_get_param (tv[idx].algo, tv[idx].name);
+ if (!param)
+ {
+ if (!tv[idx].error_expected)
+ fail ("get_param: test %d (%s) failed\n", idx, tv[idx].name);
+ }
+ else
+ {
+ if (tv[idx].error_expected)
+ fail ("get_param: test %d (%s) failed (error expected)\n",
+ idx, tv[idx].name);
+ }
+ gcry_sexp_release (param);
+ }
}