mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
gpg: Initial support for generating Kyber subkeys.
* common/openpgpdefs.h (PUBKEY_ALGO_KY768_25519): Remove. (PUBKEY_ALGO_KY1024_448): Remove. (PUBKEY_ALGO_KYBER): New. Use them everywhere instead of the removed. * g10/build-packet.c (gpg_mpi_write_nohdr): Rename to (gpg_mpi_write_opaque_nohdr): this. Change callers. (gpg_mpi_write_opaque_32): New. (do_key): Support Kyber keys using the revised format. * g10/gpg.h (MAX_EXTERN_KEYPARM_BITS): New. * g10/parse-packet.c (read_octet_string): Add arg nbytes so support reading with a length prefix. Adjust callers. (parse_key): Parse Kyber public keys. * g10/misc.c (pubkey_get_npkey): Support Kyber. (pubkey_get_nskey): Ditto. * g10/keyid.c (pubkey_string): Support dual algorithms. (do_hash_public_key): Support Kyber. (nbits_from_pk): Ditto. (keygrip_from_pk): Return the Kyber part for the ECC+Kyber dual algo. * g10/keygen.c (struct common_gen_cb_parm_s): Add genkey_result2. Note that this callback is not yet used. (ecckey_from_sexp): Add optional arg sexp2 and use it for Kyber. Change callers. (ecckey_from_sexp): Do not leak LIST in case of an error. (common_gen): Add arg keyparms2, change callers, and support Kyber. (gen_kyber): New. (get_keysize_range): Support Kyber. (fixup_keysize): Simplify and support Kyber. (do_create): Handle Kyber. (parse_key_parameter_part): Remove algo strings "ky768" and "ky1024" and add a generic "kyber" with default parameters. -- This uses a revised format which is more aligned with the usual OpenPGP structure. A lot of things are still missing. For example support for handling two keygrips and checking both of them in a -K listing. There is also only ky768_bp384 as fixed algorithm for now. No passphrase for the Kyber part of the dual algorithm is on purpose. A test was done using gpg --quick-gen-key pqc1 nistp256 and then running gpg -v --quick-add-key <fingerprint> kyber which creates a v5 subkey on a v4 primary key. A second test using gpg --quick-gen-key pqc2 Ed448 followed by a --quick-add-key created a v5 key with a v5 subkey. GnuPG-bug-id: 6815
This commit is contained in:
parent
6c1dd3afd1
commit
97f5159495
9 changed files with 461 additions and 110 deletions
91
g10/keyid.c
91
g10/keyid.c
|
@ -74,12 +74,18 @@ pubkey_letter( int algo )
|
|||
is copied to the supplied buffer up a length of BUFSIZE-1.
|
||||
Examples for the output are:
|
||||
|
||||
"rsa3072" - RSA with 3072 bit
|
||||
"elg1024" - Elgamal with 1024 bit
|
||||
"ed25519" - ECC using the curve Ed25519.
|
||||
"E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4".
|
||||
"rsa3072" - RSA with 3072 bit
|
||||
"elg1024" - Elgamal with 1024 bit
|
||||
"ed25519" - EdDSA using the curve Ed25519.
|
||||
"cv25519" - ECDH using the curve X25519.
|
||||
"ky768_cv448 - Kyber-768 with X448 as second algo.
|
||||
"ky1025_bp512 - Kyber-1024 with BrainpoolP256r1 as second algo.
|
||||
"E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4".
|
||||
"unknown_N" - Unknown OpenPGP algorithm N.
|
||||
"E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID.
|
||||
"unknown_N" - Unknown OpenPGP algorithm N.
|
||||
|
||||
Note that with Kyber we use "bp" as abbreviation for BrainpoolP and
|
||||
ignore the final r1 part.
|
||||
|
||||
If the option --legacy-list-mode is active, the output use the
|
||||
legacy format:
|
||||
|
@ -97,6 +103,9 @@ char *
|
|||
pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
|
||||
{
|
||||
const char *prefix = NULL;
|
||||
int dual = 0;
|
||||
char *curve;
|
||||
const char *name;
|
||||
|
||||
if (opt.legacy_list_mode)
|
||||
{
|
||||
|
@ -116,19 +125,34 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
|
|||
case PUBKEY_ALGO_ECDH:
|
||||
case PUBKEY_ALGO_ECDSA:
|
||||
case PUBKEY_ALGO_EDDSA: prefix = ""; break;
|
||||
case PUBKEY_ALGO_KY768_25519: prefix = "ky768"; break;
|
||||
case PUBKEY_ALGO_KY1024_448: prefix = "ky1024"; break;
|
||||
case PUBKEY_ALGO_KYBER: prefix = "ky"; dual = 1; break;
|
||||
case PUBKEY_ALGO_DIL3_25519: prefix = "dil3"; break;
|
||||
case PUBKEY_ALGO_DIL5_448: prefix = "dil5"; break;
|
||||
case PUBKEY_ALGO_SPHINX_SHA2: prefix = "sphinx_sha2"; break;
|
||||
}
|
||||
|
||||
|
||||
if (prefix && *prefix)
|
||||
snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
|
||||
{
|
||||
if (dual)
|
||||
{
|
||||
curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
/* Note that we prefer the abbreviated name of the curve. */
|
||||
name = openpgp_oid_to_curve (curve, 2);
|
||||
if (!name)
|
||||
name = "unknown";
|
||||
|
||||
snprintf (buffer, bufsize, "%s%u_%s",
|
||||
prefix, nbits_from_pk (pk), name);
|
||||
xfree (curve);
|
||||
}
|
||||
else
|
||||
snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
|
||||
}
|
||||
else if (prefix)
|
||||
{
|
||||
char *curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
const char *name = openpgp_oid_to_curve (curve, 0);
|
||||
curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
name = openpgp_oid_to_curve (curve, 0);
|
||||
|
||||
if (name)
|
||||
snprintf (buffer, bufsize, "%s", name);
|
||||
|
@ -308,6 +332,23 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5)
|
|||
pp[i] = NULL;
|
||||
nn[i] = 0;
|
||||
}
|
||||
else if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2)
|
||||
{
|
||||
/* Ugly: We need to re-construct the wire format of the
|
||||
* key parameter. It would be easier to use a second
|
||||
* second index for pp and nn which could bump
|
||||
* independet of i. */
|
||||
const char *p;
|
||||
|
||||
p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
|
||||
pp[i] = xmalloc ((nbits+7)/8 + 1);
|
||||
if (p)
|
||||
memcpy (pp[i], p, (nbits+7)/8);
|
||||
else
|
||||
pp[i] = NULL;
|
||||
nn[i] = (nbits+7)/8;
|
||||
n += nn[i];
|
||||
}
|
||||
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
|
||||
{
|
||||
const char *p;
|
||||
|
@ -805,11 +846,28 @@ namehash_from_uid (PKT_user_id *uid)
|
|||
|
||||
|
||||
/*
|
||||
* Return the number of bits used in PK.
|
||||
* Return the number of bits used in PK. For Kyber we return the
|
||||
* octet count of the Kyber part and not of the ECC (thus likely
|
||||
* values are 768 or 1024).
|
||||
*/
|
||||
unsigned int
|
||||
nbits_from_pk (PKT_public_key *pk)
|
||||
{
|
||||
if (pk->pubkey_algo == PUBKEY_ALGO_KYBER)
|
||||
{
|
||||
unsigned int nbits;
|
||||
if (!gcry_mpi_get_opaque (pk->pkey[2], &nbits))
|
||||
return 0;
|
||||
switch (nbits/8)
|
||||
{
|
||||
case 800: nbits = 512; break;
|
||||
case 1184: nbits = 768; break;
|
||||
case 1568: nbits = 1024; break;
|
||||
default: nbits = 0; break; /* Unkown version. */
|
||||
}
|
||||
return nbits;
|
||||
}
|
||||
else
|
||||
return pubkey_nbits (pk->pubkey_algo, pk->pkey);
|
||||
}
|
||||
|
||||
|
@ -1292,6 +1350,17 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
|
|||
}
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_KYBER:
|
||||
{
|
||||
char tmpname[15];
|
||||
|
||||
snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk));
|
||||
err = gcry_sexp_build (&s_pkey, NULL,
|
||||
"(public-key(%s(p%m)))",
|
||||
tmpname, pk->pkey[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue