diff options
author | Werner Koch <wk@gnupg.org> | 2013-12-02 16:18:25 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-12-02 16:21:45 +0100 |
commit | 14ae6224b1b17abbfc80c26ad0f4c60f1e8635e2 (patch) | |
tree | c783cf16f3a1e69943b7fa2d76e9487dbf4325b9 | |
parent | 485f35124b1a74af0bad321ed70be3a79d8d11d7 (diff) | |
download | libgcrypt-14ae6224b1b17abbfc80c26ad0f4c60f1e8635e2.tar.gz |
ecc: Make gcry_pk_testkey work for Ed25519.
* cipher/ecc-misc.c (_gcry_ecc_compute_public): Add optional args G
and d. Change all callers.
* cipher/ecc.c (gen_y_2): Remove.
(check_secret_key): Use generic public key compute function. Adjust
for use with Ed25519 and EdDSA.
(nist_generate_key): Do not use the compliant key thingy for Ed25519.
(ecc_check_secret_key): Make parameter parsing similar to the other
functions.
* cipher/ecc-curves.c (domain_parms): Zero prefix some parameters so
that _gcry_ecc_update_curve_param works correctly.
* tests/keygen.c (check_ecc_keys): Add "param" flag. Check all
Ed25519 keys.
-rw-r--r-- | cipher/ecc-common.h | 3 | ||||
-rw-r--r-- | cipher/ecc-curves.c | 14 | ||||
-rw-r--r-- | cipher/ecc-misc.c | 19 | ||||
-rw-r--r-- | cipher/ecc.c | 256 | ||||
-rw-r--r-- | tests/keygen.c | 43 |
5 files changed, 179 insertions, 156 deletions
diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h index 0cecdc34..74adaece 100644 --- a/cipher/ecc-common.h +++ b/cipher/ecc-common.h @@ -91,7 +91,8 @@ const char *_gcry_ecc_dialect2str (enum ecc_dialects dialect); gcry_mpi_t _gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p); gcry_error_t _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value); -mpi_point_t _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec); +mpi_point_t _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec, + mpi_point_t G, gcry_mpi_t d); /*-- ecc.c --*/ diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index 5815e559..f7c1c6db 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -174,10 +174,10 @@ static const ecc_domain_parms_t domain_parms[] = "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" - "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", - "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" + "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", + "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" + "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" }, { "brainpoolP160r1", 160, 0, @@ -442,7 +442,7 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, /* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, and N if they pint to NULL value. Note that G is returned + A, B, G, and N if they point to NULL value. Note that G is returned in standard uncompressed format. Also update MODEL and DIALECT if they are not NULL. */ gpg_err_code_t @@ -1030,7 +1030,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) { /* If only the private key is given, compute the public key. */ if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec); + ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL); if (!ec->Q) return NULL; @@ -1063,7 +1063,7 @@ _gcry_ecc_get_point (const char *name, mpi_ec_t ec) { /* If only the private key is given, compute the public key. */ if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec); + ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL); if (ec->Q) return point_copy (ec->Q); diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 0eb3391c..1633d32d 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -253,13 +253,20 @@ reverse_buffer (unsigned char *buffer, unsigned int length) /* Compute the public key from the the context EC. Obviously a requirement is that the secret key is available in EC. On success Q is returned; on error NULL. If Q is NULL a newly allocated point - is returned. */ + is returned. If G or D are given they override the values taken + from EC. */ mpi_point_t -_gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec) +_gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec, + mpi_point_t G, gcry_mpi_t d) { int rc; - if (!ec->d || !ec->G || !ec->p || !ec->a) + if (!G) + G = ec->G; + if (!d) + d = ec->d; + + if (!d || !G || !ec->p || !ec->a) return NULL; if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b) return NULL; @@ -280,7 +287,7 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec) return NULL; memset (hvec, 0, sizeof hvec); - rawmpi = _gcry_mpi_get_buffer (ec->d, 0, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer (d, 0, &rawmpilen, NULL); if (!rawmpi) return NULL; memset (digest, 0, b); @@ -311,7 +318,7 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec) if (!Q) Q = gcry_mpi_point_new (0); if (Q) - _gcry_mpi_ec_mul_point (Q, a, ec->G, ec); + _gcry_mpi_ec_mul_point (Q, a, G, ec); mpi_free (a); } else @@ -319,7 +326,7 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec) if (!Q) Q = gcry_mpi_point_new (0); if (Q) - _gcry_mpi_ec_mul_point (Q, ec->d, ec->G, ec); + _gcry_mpi_ec_mul_point (Q, d, G, ec); } return Q; diff --git a/cipher/ecc.c b/cipher/ecc.c index 72ca726d..bda2a86e 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -84,8 +84,6 @@ static void *progress_cb_data; /* Local prototypes. */ static void test_keys (ECC_secret_key * sk, unsigned int nbits); -static int check_secret_key (ECC_secret_key * sk); -static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base); static unsigned int ecc_get_nbits (gcry_sexp_t parms); @@ -109,32 +107,6 @@ _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *, - -/* - * Solve the right side of the Weierstrass equation. - */ -static gcry_mpi_t -gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base) -{ - gcry_mpi_t three, x_3, axb, y; - - three = mpi_alloc_set_ui (3); - x_3 = mpi_new (0); - axb = mpi_new (0); - y = mpi_new (0); - - mpi_powm (x_3, x, three, base->p); - mpi_mulm (axb, base->a, x, base->p); - mpi_addm (axb, axb, base->b, base->p); - mpi_addm (y, x_3, axb, base->p); - - mpi_free (x_3); - mpi_free (axb); - mpi_free (three); - return y; /* The quadratic value of the coordinate if it exist. */ -} - - /* Standard version of the key generation. */ static gpg_err_code_t nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, @@ -181,55 +153,62 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, * end up with the min(y,p-y) as the y coordinate. Such a public * key allows the most efficient compression: y can simply be * dropped because we know that it's a minimum of the two - * possibilities without any loss of security. */ - { - gcry_mpi_t x, y, negative; - const unsigned int pbits = mpi_get_nbits (E->p); + * possibilities without any loss of security. Note that we don't + * do that for Ed25519 so that we do not violate the special + * construction of the secret key. */ + if (E->dialect == ECC_DIALECT_ED25519) + point_set (&sk->Q, &Q); + else + { + gcry_mpi_t x, y, negative; + const unsigned int pbits = mpi_get_nbits (E->p); - x = mpi_new (pbits); - y = mpi_new (pbits); - negative = mpi_new (pbits); + x = mpi_new (pbits); + y = mpi_new (pbits); + negative = mpi_new (pbits); - if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx)) - log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q"); + if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx)) + log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q"); - if (E->model == MPI_EC_WEIERSTRASS) - mpi_sub (negative, E->p, y); /* negative = p - y */ - else - mpi_sub (negative, E->p, x); /* negative = p - x */ + if (E->model == MPI_EC_WEIERSTRASS) + mpi_sub (negative, E->p, y); /* negative = p - y */ + else + mpi_sub (negative, E->p, x); /* negative = p - x */ - if (mpi_cmp (negative, y) < 0) /* p - y < p */ - { - /* We need to end up with -Q; this assures that new Q's y is - the smallest one */ - mpi_sub (sk->d, E->n, sk->d); /* d = order - d */ - if (E->model == MPI_EC_WEIERSTRASS) - gcry_mpi_point_snatch_set (&sk->Q, x, negative, mpi_alloc_set_ui (1)); - else - gcry_mpi_point_snatch_set (&sk->Q, negative, y, mpi_alloc_set_ui (1)); - - if (DBG_CIPHER) - log_debug ("ecgen converted Q to a compliant point\n"); - } - else /* p - y >= p */ - { - /* No change is needed exactly 50% of the time: just copy. */ - point_set (&sk->Q, &Q); - if (DBG_CIPHER) - log_debug ("ecgen didn't need to convert Q to a compliant point\n"); - - mpi_free (negative); - if (E->model == MPI_EC_WEIERSTRASS) - mpi_free (x); - else - mpi_free (y); - } + if (mpi_cmp (negative, y) < 0) /* p - y < p */ + { + /* We need to end up with -Q; this assures that new Q's y is + the smallest one */ + mpi_sub (sk->d, E->n, sk->d); /* d = order - d */ + if (E->model == MPI_EC_WEIERSTRASS) + gcry_mpi_point_snatch_set (&sk->Q, x, negative, + mpi_alloc_set_ui (1)); + else + gcry_mpi_point_snatch_set (&sk->Q, negative, y, + mpi_alloc_set_ui (1)); - if (E->model == MPI_EC_WEIERSTRASS) - mpi_free (y); - else - mpi_free (x); - } + if (DBG_CIPHER) + log_debug ("ecgen converted Q to a compliant point\n"); + } + else /* p - y >= p */ + { + /* No change is needed exactly 50% of the time: just copy. */ + point_set (&sk->Q, &Q); + if (DBG_CIPHER) + log_debug ("ecgen didn't need to convert Q to a compliant point\n"); + + mpi_free (negative); + if (E->model == MPI_EC_WEIERSTRASS) + mpi_free (x); + else + mpi_free (y); + } + + if (E->model == MPI_EC_WEIERSTRASS) + mpi_free (y); + else + mpi_free (x); + } point_free (&Q); /* Now we can test our keys (this should never fail!). */ @@ -295,30 +274,26 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) * between the public value and the secret one. */ static int -check_secret_key (ECC_secret_key * sk) +check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags) { int rc = 1; mpi_point_struct Q; - gcry_mpi_t y_2, y2; - gcry_mpi_t x1, x2; - mpi_ec_t ctx = NULL; + gcry_mpi_t x1, y1; + gcry_mpi_t x2 = NULL; + gcry_mpi_t y2 = NULL; point_init (&Q); + x1 = mpi_new (0); + y1 = mpi_new (0); - /* ?primarity test of 'p' */ - /* (...) //!! */ /* G in E(F_p) */ - y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */ - y2 = mpi_alloc (0); - x1 = mpi_alloc (0); - x2 = mpi_alloc (0); - mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */ - if (mpi_cmp (y_2, y2)) + if (!_gcry_mpi_ec_curve_point (&sk->E.G, ec)) { if (DBG_CIPHER) log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n"); goto leave; } + /* G != PaI */ if (!mpi_cmp_ui (sk->E.G.z, 0)) { @@ -327,37 +302,46 @@ check_secret_key (ECC_secret_key * sk) goto leave; } - ctx = _gcry_mpi_ec_p_internal_new (sk->E.model, sk->E.dialect, 0, - sk->E.p, sk->E.a, sk->E.b); - - _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx); - if (mpi_cmp_ui (Q.z, 0)) + /* Check order of curve. */ + if (sk->E.dialect != ECC_DIALECT_ED25519) { - if (DBG_CIPHER) - log_debug ("check_secret_key: E is not a curve of order n\n"); - goto leave; + _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ec); + if (mpi_cmp_ui (Q.z, 0)) + { + if (DBG_CIPHER) + log_debug ("check_secret_key: E is not a curve of order n\n"); + goto leave; + } } - /* pubkey cannot be PaI */ + + /* Pubkey cannot be PaI */ if (!mpi_cmp_ui (sk->Q.z, 0)) { if (DBG_CIPHER) log_debug ("Bad check: Q can not be a Point at Infinity!\n"); goto leave; } - /* pubkey = [d]G over E */ - _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx); - if (_gcry_mpi_ec_get_affine (x1, y_2, &Q, ctx)) + /* pubkey = [d]G over E */ + if (!_gcry_ecc_compute_public (&Q, ec, &sk->E.G, sk->d)) + { + if (DBG_CIPHER) + log_debug ("Bad check: computation of dG failed\n"); + goto leave; + } + if (_gcry_mpi_ec_get_affine (x1, y1, &Q, ec)) { if (DBG_CIPHER) log_debug ("Bad check: Q can not be a Point at Infinity!\n"); goto leave; } - /* Fast path for loaded secret keys - Q is already in affine coordinates */ - if (!mpi_cmp_ui (sk->Q.z, 1)) + if ((flags & PUBKEY_FLAG_EDDSA)) + ; /* Fixme: EdDSA is special. */ + else if (!mpi_cmp_ui (sk->Q.z, 1)) { - if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y_2, sk->Q.y)) + /* Fast path if Q is already in affine coordinates. */ + if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y1, sk->Q.y)) { if (DBG_CIPHER) log_debug @@ -367,14 +351,16 @@ check_secret_key (ECC_secret_key * sk) } else { - if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ctx)) + x2 = mpi_new (0); + y2 = mpi_new (0); + if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ec)) { if (DBG_CIPHER) log_debug ("Bad check: Q can not be a Point at Infinity!\n"); goto leave; } - if (mpi_cmp (x1, x2) || mpi_cmp (y_2, y2)) + if (mpi_cmp (x1, x2) || mpi_cmp (y1, y2)) { if (DBG_CIPHER) log_debug @@ -385,11 +371,10 @@ check_secret_key (ECC_secret_key * sk) rc = 0; /* Okay. */ leave: - _gcry_mpi_ec_free (ctx); mpi_free (x2); mpi_free (x1); + mpi_free (y1); mpi_free (y2); - mpi_free (y_2); point_free (&Q); return rc; } @@ -601,28 +586,35 @@ ecc_check_secret_key (gcry_sexp_t keyparms) { gcry_err_code_t rc; gcry_sexp_t l1 = NULL; + int flags = 0; char *curvename = NULL; gcry_mpi_t mpi_g = NULL; gcry_mpi_t mpi_q = NULL; ECC_secret_key sk; + mpi_ec_t ec = NULL; memset (&sk, 0, sizeof sk); - /* - * Extract the key. - */ - rc = _gcry_sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d", - &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, - &mpi_q, &sk.d, NULL); - if (rc) - goto leave; - if (mpi_g) + /* Look for flags. */ + l1 = gcry_sexp_find_token (keyparms, "flags", 0); + if (l1) { - point_init (&sk.E.G); - rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g); + rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL); if (rc) goto leave; } + + /* Extract the parameters. */ + if ((flags & PUBKEY_FLAG_PARAM)) + rc = _gcry_sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d", + &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, + &mpi_q, &sk.d, NULL); + else + rc = _gcry_sexp_extract_param (keyparms, NULL, "/q?+d", + &mpi_q, &sk.d, NULL); + if (rc) + goto leave; + /* Add missing parameters using the optional curve parameter. */ gcry_sexp_release (l1); l1 = gcry_sexp_find_token (keyparms, "curve", 5); @@ -631,17 +623,32 @@ ecc_check_secret_key (gcry_sexp_t keyparms) curvename = gcry_sexp_nth_string (l1, 1); if (curvename) { - rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL); + rc = _gcry_ecc_update_curve_param (curvename, + &sk.E.model, &sk.E.dialect, + &sk.E.p, &sk.E.a, &sk.E.b, + &mpi_g, &sk.E.n); if (rc) return rc; } } + if (mpi_g) + { + point_init (&sk.E.G); + rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g); + if (rc) + goto leave; + } + /* Guess required fields if a curve parameter has not been given. FIXME: This is a crude hacks. We need to fix that. */ if (!curvename) { - sk.E.model = MPI_EC_WEIERSTRASS; - sk.E.dialect = ECC_DIALECT_STANDARD; + sk.E.model = ((flags & PUBKEY_FLAG_EDDSA) + ? MPI_EC_TWISTEDEDWARDS + : MPI_EC_WEIERSTRASS); + sk.E.dialect = ((flags & PUBKEY_FLAG_EDDSA) + ? ECC_DIALECT_ED25519 + : ECC_DIALECT_STANDARD); } if (DBG_CIPHER) { @@ -665,24 +672,31 @@ ecc_check_secret_key (gcry_sexp_t keyparms) goto leave; } + ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0, + sk.E.p, sk.E.a, sk.E.b); + if (mpi_q) { point_init (&sk.Q); - rc = _gcry_ecc_os2ec (&sk.Q, mpi_q); + if (ec->dialect == ECC_DIALECT_ED25519) + rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &sk.Q, NULL, NULL); + else + rc = _gcry_ecc_os2ec (&sk.Q, mpi_q); if (rc) goto leave; } else { - /* The current test requires Q. */ + /* The secret key test requires Q. */ rc = GPG_ERR_NO_OBJ; goto leave; } - if (check_secret_key (&sk)) + if (check_secret_key (&sk, ec, flags)) rc = GPG_ERR_BAD_SECKEY; leave: + _gcry_mpi_ec_free (ec); gcry_mpi_release (sk.E.p); gcry_mpi_release (sk.E.a); gcry_mpi_release (sk.E.b); @@ -1623,7 +1637,7 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec) /* Compute the public point if it is missing. */ if (!ec->Q && ec->d) - ec->Q = _gcry_ecc_compute_public (NULL, ec); + ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL); /* Encode G and Q. */ mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec); diff --git a/tests/keygen.c b/tests/keygen.c index 48663d45..e8cf7c5b 100644 --- a/tests/keygen.c +++ b/tests/keygen.c @@ -90,21 +90,21 @@ show (const char *format, ...) } -static void -show_note (const char *format, ...) -{ - va_list arg_ptr; - - if (!verbose && getenv ("srcdir")) - fputs (" ", stderr); /* To align above "PASS: ". */ - else - fprintf (stderr, "%s: ", PGM); - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - if (*format && format[strlen(format)-1] != '\n') - putc ('\n', stderr); - va_end (arg_ptr); -} +/* static void */ +/* show_note (const char *format, ...) */ +/* { */ +/* va_list arg_ptr; */ + +/* if (!verbose && getenv ("srcdir")) */ +/* fputs (" ", stderr); /\* To align above "PASS: ". *\/ */ +/* else */ +/* fprintf (stderr, "%s: ", PGM); */ +/* va_start (arg_ptr, format); */ +/* vfprintf (stderr, format, arg_ptr); */ +/* if (*format && format[strlen(format)-1] != '\n') */ +/* putc ('\n', stderr); */ +/* va_end (arg_ptr); */ +/* } */ static void @@ -376,11 +376,11 @@ check_ecc_keys (void) show ("creating ECC key using curve %s\n", curves[testno]); if (!strcmp (curves[testno], "Ed25519")) rc = gcry_sexp_build (&keyparm, NULL, - "(genkey(ecc(curve %s)(flags eddsa)))", + "(genkey(ecc(curve %s)(flags param eddsa)))", curves[testno]); else rc = gcry_sexp_build (&keyparm, NULL, - "(genkey(ecc(curve %s)(flags )))", + "(genkey(ecc(curve %s)(flags param)))", curves[testno]); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); @@ -393,10 +393,7 @@ check_ecc_keys (void) if (verbose > 1) show_sexp ("ECC key:\n", key); - if (!strcmp (curves[testno], "Ed25519")) - show_note ("note: gcry_pk_testkey does not yet work for Ed25519\n"); - else - check_generated_ecc_key (key); + check_generated_ecc_key (key); gcry_sexp_release (key); } @@ -415,6 +412,8 @@ check_ecc_keys (void) if (verbose > 1) show_sexp ("ECC key:\n", key); + check_generated_ecc_key (key); + if (verbose) show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n"); rc = gcry_sexp_build (&keyparm, NULL, @@ -431,6 +430,8 @@ check_ecc_keys (void) if (verbose > 1) show_sexp ("ECC key:\n", key); + check_generated_ecc_key (key); + gcry_sexp_release (key); } |