mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Prepare Kyber encryption code for more variants.
* common/openpgp-oid.c (oidtable): Add field kem_algo. (openpgp_oid_to_kem_algo): New. * g10/pkglue.c (do_encrypt_kem): Add support for Kyber1024. -- GnuPG-bug-id: 6815
This commit is contained in:
parent
7d6ad28667
commit
ba3c873934
@ -45,14 +45,15 @@ static struct {
|
||||
const char *alias; /* NULL or alternative name of the curve. */
|
||||
const char *abbr; /* NULL or abbreviated name of the curve. */
|
||||
int pubkey_algo; /* Required OpenPGP algo or 0 for ECDSA/ECDH. */
|
||||
enum gcry_kem_algos kem_algo; /* 0 or the KEM algorithm for PQC. */
|
||||
} oidtable[] = {
|
||||
|
||||
{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", NULL,
|
||||
PUBKEY_ALGO_ECDH },
|
||||
PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X25519 /* only during development */},
|
||||
{ "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", NULL,
|
||||
PUBKEY_ALGO_EDDSA },
|
||||
{ "Curve25519", "1.3.101.110", 255, "cv25519", NULL,
|
||||
PUBKEY_ALGO_ECDH },
|
||||
PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X25519 },
|
||||
{ "Ed25519", "1.3.101.112", 255, "ed25519", NULL,
|
||||
PUBKEY_ALGO_EDDSA },
|
||||
{ "X448", "1.3.101.111", 448, "cv448", NULL,
|
||||
@ -542,6 +543,29 @@ openpgp_oid_or_name_to_curve (const char *oidname, int canon)
|
||||
}
|
||||
|
||||
|
||||
/* Return the KEM algorithm id for the curve with OIDNAME. */
|
||||
enum gcry_kem_algos
|
||||
openpgp_oid_to_kem_algo (const char *oidname)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!oidname)
|
||||
return 0;
|
||||
|
||||
for (i=0; oidtable[i].name; i++)
|
||||
if (!strcmp (oidtable[i].oidstr, oidname))
|
||||
return oidtable[i].kem_algo;
|
||||
|
||||
for (i=0; oidtable[i].name; i++)
|
||||
if (!ascii_strcasecmp (oidtable[i].name, oidname)
|
||||
|| (oidtable[i].alias
|
||||
&& !ascii_strcasecmp (oidtable[i].alias, oidname)))
|
||||
return oidtable[i].kem_algo;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if the curve with NAME is supported. */
|
||||
static int
|
||||
curve_supported_p (const char *name)
|
||||
|
@ -227,6 +227,7 @@ int openpgp_oidbuf_is_cv25519 (const void *buf, size_t len);
|
||||
int openpgp_oid_is_cv25519 (gcry_mpi_t a);
|
||||
int openpgp_oid_is_cv448 (gcry_mpi_t a);
|
||||
int openpgp_oid_is_ed448 (gcry_mpi_t a);
|
||||
enum gcry_kem_algos openpgp_oid_to_kem_algo (const char *oidname);
|
||||
const char *openpgp_curve_to_oid (const char *name,
|
||||
unsigned int *r_nbits, int *r_algo);
|
||||
const char *openpgp_oid_to_curve (const char *oid, int mode);
|
||||
|
72
g10/pkglue.c
72
g10/pkglue.c
@ -417,6 +417,11 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
|
||||
}
|
||||
|
||||
|
||||
#if GCRY_KEM_MLKEM1024_ENCAPS_LEN < GCRY_KEM_MLKEM768_ENCAPS_LEN \
|
||||
|| GCRY_KEM_MLKEM1024_SHARED_LEN < GCRY_KEM_MLKEM768_SHARED_LEN
|
||||
# error Bad Kyber constants in Libgcrypt
|
||||
#endif
|
||||
|
||||
/* Core of the encryption for KEM algorithms. See pk_decrypt for a
|
||||
* description of the arguments. */
|
||||
static gpg_error_t
|
||||
@ -428,6 +433,8 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
unsigned int nbits, n;
|
||||
gcry_sexp_t s_data = NULL;
|
||||
gcry_cipher_hd_t hd = NULL;
|
||||
char *ecc_oid = NULL;
|
||||
enum gcry_kem_algos kyber_algo, ecc_algo;
|
||||
|
||||
const unsigned char *ecc_pubkey;
|
||||
size_t ecc_pubkey_len;
|
||||
@ -445,10 +452,9 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
unsigned char ecc_ss[GCRY_KEM_RAW_X25519_SHARED_LEN];
|
||||
size_t ecc_ss_len = GCRY_KEM_RAW_X25519_SHARED_LEN;
|
||||
|
||||
unsigned char kyber_ct[GCRY_KEM_MLKEM768_ENCAPS_LEN];
|
||||
size_t kyber_ct_len = GCRY_KEM_MLKEM768_ENCAPS_LEN;
|
||||
unsigned char kyber_ss[GCRY_KEM_MLKEM768_SHARED_LEN];
|
||||
size_t kyber_ss_len = GCRY_KEM_MLKEM768_SHARED_LEN;
|
||||
unsigned char kyber_ct[GCRY_KEM_MLKEM1024_ENCAPS_LEN];
|
||||
unsigned char kyber_ss[GCRY_KEM_MLKEM1024_SHARED_LEN];
|
||||
size_t kyber_ct_len, kyber_ss_len;
|
||||
|
||||
char fixedinfo[1+MAX_FINGERPRINT_LEN];
|
||||
int fixedlen;
|
||||
@ -463,7 +469,19 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
* second public key is expected. Right now we take the keys
|
||||
* directly from the PK->data elements. */
|
||||
|
||||
/* FIXME: This is only for cv25519 */
|
||||
ecc_oid = openpgp_oid_to_str (pk->pkey[0]);
|
||||
if (!ecc_oid)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("%s: error getting OID for ECC key\n", __func__);
|
||||
goto leave;
|
||||
}
|
||||
ecc_algo = openpgp_oid_to_kem_algo (ecc_oid);
|
||||
if (ecc_algo == GCRY_KEM_RAW_X25519)
|
||||
{
|
||||
if (!strcmp (ecc_oid, "1.3.6.1.4.1.3029.1.5.1"))
|
||||
log_info ("Warning: "
|
||||
"legacy OID for cv25519 accepted during develpment\n");
|
||||
ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
|
||||
ecc_pubkey_len = (nbits+7)/8;
|
||||
if (ecc_pubkey_len != 33)
|
||||
@ -476,10 +494,23 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
}
|
||||
ecc_pubkey++; /* Remove the 0x40 prefix. */
|
||||
ecc_pubkey_len--;
|
||||
if (DBG_CRYPTO)
|
||||
log_printhex (ecc_pubkey, ecc_pubkey_len, "ECC pubkey:");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info ("%s: ECC curve %s not supported\n", __func__, ecc_oid);
|
||||
err = gpg_error (GPG_ERR_INV_DATA);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = gcry_kem_encap (GCRY_KEM_RAW_X25519,
|
||||
|
||||
if (DBG_CRYPTO)
|
||||
{
|
||||
log_debug ("ECC curve: %s\n", ecc_oid);
|
||||
log_printhex (ecc_pubkey, ecc_pubkey_len, "ECC pubkey:");
|
||||
}
|
||||
|
||||
err = gcry_kem_encap (ecc_algo,
|
||||
ecc_pubkey, ecc_pubkey_len,
|
||||
ecc_ct, ecc_ct_len,
|
||||
ecc_ecdh, ecc_ecdh_len,
|
||||
@ -487,7 +518,8 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
if (err)
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info ("%s: gcry_kem_encap for ECC failed\n", __func__);
|
||||
log_info ("%s: gcry_kem_encap for ECC (%s) failed\n",
|
||||
__func__, ecc_oid);
|
||||
goto leave;
|
||||
}
|
||||
if (DBG_CRYPTO)
|
||||
@ -509,10 +541,21 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
if (DBG_CRYPTO)
|
||||
log_printhex (ecc_ss, ecc_ss_len, "ECC shared:");
|
||||
|
||||
/* FIXME: This is only for kyber768 */
|
||||
kyber_pubkey = gcry_mpi_get_opaque (pk->pkey[2], &nbits);
|
||||
kyber_pubkey_len = (nbits+7)/8;
|
||||
if (kyber_pubkey_len != GCRY_KEM_MLKEM768_PUBKEY_LEN)
|
||||
if (kyber_pubkey_len == GCRY_KEM_MLKEM768_PUBKEY_LEN)
|
||||
{
|
||||
kyber_algo = GCRY_KEM_MLKEM768;
|
||||
kyber_ct_len = GCRY_KEM_MLKEM768_ENCAPS_LEN;
|
||||
kyber_ss_len = GCRY_KEM_MLKEM768_SHARED_LEN;
|
||||
}
|
||||
else if (kyber_pubkey_len == GCRY_KEM_MLKEM1024_PUBKEY_LEN)
|
||||
{
|
||||
kyber_algo = GCRY_KEM_MLKEM1024;
|
||||
kyber_ct_len = GCRY_KEM_MLKEM1024_ENCAPS_LEN;
|
||||
kyber_ss_len = GCRY_KEM_MLKEM1024_SHARED_LEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info ("%s: Kyber public key length invalid (%zu)\n",
|
||||
@ -523,7 +566,7 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
if (DBG_CRYPTO)
|
||||
log_printhex (kyber_pubkey, kyber_pubkey_len, "|!trunc|Kyber pubkey:");
|
||||
|
||||
err = gcry_kem_encap (GCRY_KEM_MLKEM768,
|
||||
err = gcry_kem_encap (kyber_algo,
|
||||
kyber_pubkey, kyber_pubkey_len,
|
||||
kyber_ct, kyber_ct_len,
|
||||
kyber_ss, kyber_ss_len,
|
||||
@ -625,11 +668,12 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
||||
wipememory (ecc_ct, ecc_ct_len);
|
||||
wipememory (ecc_ecdh, ecc_ecdh_len);
|
||||
wipememory (ecc_ss, ecc_ss_len);
|
||||
wipememory (kyber_ct, kyber_ct_len);
|
||||
wipememory (kyber_ss, kyber_ss_len);
|
||||
wipememory (kyber_ct, sizeof kyber_ct);
|
||||
wipememory (kyber_ss, sizeof kyber_ss);
|
||||
wipememory (kek, kek_len);
|
||||
xfree (enc_seskey);
|
||||
gcry_cipher_close (hd);
|
||||
xfree (ecc_oid);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user