1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-11-08 21:18:51 +01:00

experiment: Try to support new 448 key and signature.

--

Keygrip computation is still wrong, need to fix soon.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2021-10-08 12:00:56 +09:00
parent e99b9890c2
commit c450eb1ccb
6 changed files with 83 additions and 11 deletions

View File

@ -27,7 +27,7 @@
#include "../common/i18n.h" #include "../common/i18n.h"
#include "cvt-openpgp.h" #include "cvt-openpgp.h"
#include "../common/host2net.h" #include "../common/host2net.h"
#include "../common/openpgpdefs.h"
/* Helper to pass data via the callback to do_unprotect. */ /* Helper to pass data via the callback to do_unprotect. */
struct try_do_unprotect_arg_s struct try_do_unprotect_arg_s
@ -153,6 +153,9 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
else else
{ {
const char *format; const char *format;
gcry_mpi_t pubkey = NULL;
gcry_mpi_t seckey = NULL;
pubkey_algo_t pkalgo = 0; /* Specify NONE */
if (!strcmp (curve, "Ed25519")) if (!strcmp (curve, "Ed25519"))
/* Do not store the OID as name but the real name and the /* Do not store the OID as name but the real name and the
@ -161,8 +164,23 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
else if (!strcmp (curve, "Curve25519")) else if (!strcmp (curve, "Curve25519"))
format = "(private-key(ecc(curve %s)(flags djb-tweak)(q%m)(d%m)))"; format = "(private-key(ecc(curve %s)(flags djb-tweak)(q%m)(d%m)))";
else else
{
if (!strcmp (curve, "Ed448"))
pkalgo = PUBKEY_ALGO_EDDSA;
else if (!strcmp (curve, "X448"))
pkalgo = PUBKEY_ALGO_ECDH;
format = "(private-key(ecc(curve %s)(q%m)(d%m)))"; format = "(private-key(ecc(curve %s)(q%m)(d%m)))";
}
if (pkalgo)
{
pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve, skey[0]);
seckey = openpgp_ecc_parse_seckey (pkalgo, curve, skey[1]);
err = gcry_sexp_build (&s_skey, NULL, format, curve, pubkey, seckey);
gcry_mpi_release (pubkey);
gcry_mpi_release (seckey);
}
else
err = gcry_sexp_build (&s_skey, NULL, format, curve, skey[0], skey[1]); err = gcry_sexp_build (&s_skey, NULL, format, curve, skey[0], skey[1]);
} }
break; break;

View File

@ -85,7 +85,7 @@ common_sources = \
localename.c \ localename.c \
session-env.c session-env.h \ session-env.c session-env.h \
userids.c userids.h \ userids.c userids.h \
openpgp-oid.c openpgp-s2k.c \ openpgp-oid.c openpgp-s2k.c openpgp-misc.c \
ssh-utils.c ssh-utils.h \ ssh-utils.c ssh-utils.h \
agent-opt.c \ agent-opt.c \
helpfile.c \ helpfile.c \

View File

@ -239,5 +239,10 @@ pubkey_algo_t map_gcry_pk_to_openpgp (enum gcry_pk_algos algo);
enum gcry_pk_algos map_openpgp_pk_to_gcry (pubkey_algo_t algo); enum gcry_pk_algos map_openpgp_pk_to_gcry (pubkey_algo_t algo);
/*-- openpgp-misc.c --*/
gcry_mpi_t openpgp_ecc_parse_pubkey (pubkey_algo_t pkalgo, const char *curve,
gcry_mpi_t pubkey);
gcry_mpi_t openpgp_ecc_parse_seckey (pubkey_algo_t pkalgo, const char *curve_oid,
gcry_mpi_t seckey);
#endif /*GNUPG_COMMON_OPENPGPDEFS_H*/ #endif /*GNUPG_COMMON_OPENPGPDEFS_H*/

View File

@ -1068,6 +1068,9 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
else else
{ {
gcry_mpi_t pubkey = openpgp_ecc_parse_pubkey (pk->pubkey_algo,
curve, pk->pkey[1]);
err = gcry_sexp_build (&s_pkey, NULL, err = gcry_sexp_build (&s_pkey, NULL,
pk->pubkey_algo == PUBKEY_ALGO_EDDSA? pk->pubkey_algo == PUBKEY_ALGO_EDDSA?
"(public-key(ecc(curve%s)(flags eddsa)(q%m)))": "(public-key(ecc(curve%s)(flags eddsa)(q%m)))":
@ -1075,8 +1078,9 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
&& openpgp_oid_is_cv25519 (pk->pkey[0]))? && openpgp_oid_is_cv25519 (pk->pkey[0]))?
"(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))": "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))":
"(public-key(ecc(curve%s)(q%m)))", "(public-key(ecc(curve%s)(q%m)))",
curve, pk->pkey[1]); curve, pubkey);
xfree (curve); xfree (curve);
gcry_mpi_release (pubkey);
} }
} }
break; break;

View File

@ -1805,10 +1805,13 @@ pubkey_nbits( int algo, gcry_mpi_t *key )
rc = gpg_error_from_syserror (); rc = gpg_error_from_syserror ();
else else
{ {
gcry_mpi_t pubkey = openpgp_ecc_parse_pubkey (algo, curve, key[1]);
rc = gcry_sexp_build (&sexp, NULL, rc = gcry_sexp_build (&sexp, NULL,
"(public-key(ecc(curve%s)(q%m)))", "(public-key(ecc(curve%s)(q%m)))",
curve, key[1]); curve, key[1]);
xfree (curve); xfree (curve);
gcry_mpi_release (pubkey);
} }
} }
else else

View File

@ -121,6 +121,26 @@ get_data_from_sexp (gcry_sexp_t sexp, const char *item, size_t *r_size)
} }
static void
openpgp_ecc_parse_signature (pubkey_algo_t pkalgo, gcry_mpi_t sig_data,
gcry_mpi_t *r, gcry_mpi_t *s)
{
unsigned int nbits = 0;
unsigned char *buf;
if (pkalgo != PUBKEY_ALGO_EDDSA)
return;
buf = gcry_mpi_get_opaque (sig_data, &nbits);
if ((nbits+7)/8 != (8 /*prefix*/ + 448 + 8 /*r*/ + 448 + 8 /*s*/)/8)
return;
/* Ed448 signature with the prefix. */
*r = gcry_mpi_set_opaque_copy (NULL, buf+1, 8 + 448);
*s = gcry_mpi_set_opaque_copy (NULL, buf+1+57, 8 + 448);
}
/**************** /****************
* Emulate our old PK interface here - sometime in the future we might * Emulate our old PK interface here - sometime in the future we might
* change the internal design to directly fit to libgcrypt. * change the internal design to directly fit to libgcrypt.
@ -171,14 +191,17 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
else else
{ {
const char *fmt; const char *fmt;
gcry_mpi_t pubkey;
pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve, pkey[1]);
if (openpgp_oid_is_ed25519 (pkey[0])) if (openpgp_oid_is_ed25519 (pkey[0]))
fmt = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))"; fmt = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))";
else else
fmt = "(public-key(ecc(curve %s)(q%m)))"; fmt = "(public-key(ecc(curve %s)(q%m)))";
rc = gcry_sexp_build (&s_pkey, NULL, fmt, curve, pkey[1]); rc = gcry_sexp_build (&s_pkey, NULL, fmt, curve, pubkey);
xfree (curve); xfree (curve);
gcry_mpi_release (pubkey);
} }
} }
else else
@ -298,6 +321,9 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
} }
} }
} }
else if (!gcry_mpi_cmp_ui (s, 0))
/* When data[1] == MPI(0), parse the signature into R and S parts. */
openpgp_ecc_parse_signature (pkalgo, r, &r, &s);
else else
rc = 0; rc = 0;
@ -388,14 +414,17 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
else else
{ {
int with_djb_tweak_flag = openpgp_oid_is_cv25519 (pkey[0]); int with_djb_tweak_flag = openpgp_oid_is_cv25519 (pkey[0]);
gcry_mpi_t pubkey;
pubkey = openpgp_ecc_parse_pubkey (algo, curve, pkey[1]);
/* Now use the ephemeral secret to compute the shared point. */ /* Now use the ephemeral secret to compute the shared point. */
rc = gcry_sexp_build (&s_pkey, NULL, rc = gcry_sexp_build (&s_pkey, NULL,
with_djb_tweak_flag ? with_djb_tweak_flag ?
"(public-key(ecdh(curve%s)(flags djb-tweak)(q%m)))" "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))"
: "(public-key(ecdh(curve%s)(q%m)))", : "(public-key(ecc(curve%s)(q%m)))",
curve, pkey[1]); curve, pubkey);
xfree (curve); xfree (curve);
gcry_mpi_release (pubkey);
/* Put K into a simplified S-expression. */ /* Put K into a simplified S-expression. */
if (!rc) if (!rc)
rc = gcry_sexp_build (&s_data, NULL, "%m", k); rc = gcry_sexp_build (&s_data, NULL, "%m", k);
@ -508,10 +537,17 @@ pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey)
rc = gpg_error_from_syserror (); rc = gpg_error_from_syserror ();
else else
{ {
gcry_mpi_t pubkey;
gcry_mpi_t seckey;
pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve, skey[1]);
seckey = openpgp_ecc_parse_seckey (pkalgo, curve, skey[2]);
rc = gcry_sexp_build (&s_skey, NULL, rc = gcry_sexp_build (&s_skey, NULL,
"(private-key(ecc(curve%s)(q%m)(d%m)))", "(private-key(ecc(curve%s)(q%m)(d%m)))",
curve, skey[1], skey[2]); curve, pubkey, seckey);
xfree (curve); xfree (curve);
gcry_mpi_release (pubkey);
gcry_mpi_release (seckey);
} }
} }
else if (pkalgo == PUBKEY_ALGO_EDDSA) else if (pkalgo == PUBKEY_ALGO_EDDSA)
@ -522,14 +558,20 @@ pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey)
else else
{ {
const char *fmt; const char *fmt;
gcry_mpi_t pubkey;
gcry_mpi_t seckey;
pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve, skey[1]);
seckey = openpgp_ecc_parse_seckey (pkalgo, curve, skey[2]);
if (openpgp_oid_is_ed25519 (skey[0])) if (openpgp_oid_is_ed25519 (skey[0]))
fmt = "(private-key(ecc(curve %s)(flags eddsa)(q%m)(d%m)))"; fmt = "(private-key(ecc(curve %s)(flags eddsa)(q%m)(d%m)))";
else else
fmt = "(private-key(ecc(curve %s)(q%m)(d%m)))"; fmt = "(private-key(ecc(curve %s)(q%m)(d%m)))";
rc = gcry_sexp_build (&s_skey, NULL, fmt, curve, skey[1], skey[2]); rc = gcry_sexp_build (&s_skey, NULL, fmt, curve, pubkey, seckey);
xfree (curve); xfree (curve);
gcry_mpi_release (pubkey);
gcry_mpi_release (seckey);
} }
} }
else else