mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Support encryption with kyber_cv448.
* g10/pkglue.c (do_encrypt_kem): Support cv25519 w/o 0x40 prefix. Support X448. (ECC_POINT_LEN_MAX): New. (ECC_HASH_LEN_MAX): New. * common/openpgp-oid.c (oidtable): Support X448 KEM. -- This needs more work. For example we should use a parameter table like what we do in agent/pkdecrypt.c. GnuPG-bug-id: 6815
This commit is contained in:
parent
f305e703d5
commit
e591fd25ad
@ -57,7 +57,7 @@ static struct {
|
|||||||
{ "Ed25519", "1.3.101.112", 255, "ed25519", NULL,
|
{ "Ed25519", "1.3.101.112", 255, "ed25519", NULL,
|
||||||
PUBKEY_ALGO_EDDSA },
|
PUBKEY_ALGO_EDDSA },
|
||||||
{ "X448", "1.3.101.111", 448, "cv448", NULL,
|
{ "X448", "1.3.101.111", 448, "cv448", NULL,
|
||||||
PUBKEY_ALGO_ECDH },
|
PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X448 },
|
||||||
{ "Ed448", "1.3.101.113", 456, "ed448", NULL,
|
{ "Ed448", "1.3.101.113", 456, "ed448", NULL,
|
||||||
PUBKEY_ALGO_EDDSA },
|
PUBKEY_ALGO_EDDSA },
|
||||||
|
|
||||||
|
53
g10/pkglue.c
53
g10/pkglue.c
@ -32,6 +32,12 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Maximum buffer sizes required for ECC KEM. */
|
||||||
|
#define ECC_POINT_LEN_MAX (1+2*64)
|
||||||
|
#define ECC_HASH_LEN_MAX 64
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: Better change the function name because mpi_ is used by
|
/* FIXME: Better change the function name because mpi_ is used by
|
||||||
gcrypt macros. */
|
gcrypt macros. */
|
||||||
gcry_mpi_t
|
gcry_mpi_t
|
||||||
@ -444,13 +450,12 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
|||||||
size_t seskey_len;
|
size_t seskey_len;
|
||||||
unsigned char *enc_seskey = NULL;
|
unsigned char *enc_seskey = NULL;
|
||||||
size_t enc_seskey_len;
|
size_t enc_seskey_len;
|
||||||
|
int ecc_hash_algo;
|
||||||
|
|
||||||
unsigned char ecc_ct[GCRY_KEM_ECC_X25519_ENCAPS_LEN];
|
unsigned char ecc_ct[ECC_POINT_LEN_MAX];
|
||||||
size_t ecc_ct_len = GCRY_KEM_ECC_X25519_ENCAPS_LEN;
|
unsigned char ecc_ecdh[ECC_POINT_LEN_MAX];
|
||||||
unsigned char ecc_ecdh[GCRY_KEM_RAW_X25519_SHARED_LEN];
|
unsigned char ecc_ss[ECC_HASH_LEN_MAX];
|
||||||
size_t ecc_ecdh_len = GCRY_KEM_RAW_X25519_SHARED_LEN;
|
size_t ecc_ct_len, ecc_ecdh_len, ecc_ss_len;
|
||||||
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_MLKEM1024_ENCAPS_LEN];
|
unsigned char kyber_ct[GCRY_KEM_MLKEM1024_ENCAPS_LEN];
|
||||||
unsigned char kyber_ss[GCRY_KEM_MLKEM1024_SHARED_LEN];
|
unsigned char kyber_ss[GCRY_KEM_MLKEM1024_SHARED_LEN];
|
||||||
@ -484,7 +489,12 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
|||||||
"legacy OID for cv25519 accepted during develpment\n");
|
"legacy OID for cv25519 accepted during develpment\n");
|
||||||
ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
|
ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
|
||||||
ecc_pubkey_len = (nbits+7)/8;
|
ecc_pubkey_len = (nbits+7)/8;
|
||||||
if (ecc_pubkey_len != 33)
|
if (ecc_pubkey_len == 33 && *ecc_pubkey == 0x40)
|
||||||
|
{
|
||||||
|
ecc_pubkey++; /* Remove the 0x40 prefix. */
|
||||||
|
ecc_pubkey_len--;
|
||||||
|
}
|
||||||
|
if (ecc_pubkey_len != 32)
|
||||||
{
|
{
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info ("%s: ECC public key length invalid (%zu)\n",
|
log_info ("%s: ECC public key length invalid (%zu)\n",
|
||||||
@ -492,8 +502,25 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
|||||||
err = gpg_error (GPG_ERR_INV_DATA);
|
err = gpg_error (GPG_ERR_INV_DATA);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
ecc_pubkey++; /* Remove the 0x40 prefix. */
|
ecc_ct_len = ecc_ecdh_len = 32;
|
||||||
ecc_pubkey_len--;
|
ecc_ss_len = 32;
|
||||||
|
ecc_hash_algo = GCRY_MD_SHA3_256;
|
||||||
|
}
|
||||||
|
else if (ecc_algo == GCRY_KEM_RAW_X448)
|
||||||
|
{
|
||||||
|
ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
|
||||||
|
ecc_pubkey_len = (nbits+7)/8;
|
||||||
|
if (ecc_pubkey_len != 56)
|
||||||
|
{
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info ("%s: ECC public key length invalid (%zu)\n",
|
||||||
|
__func__, ecc_pubkey_len);
|
||||||
|
err = gpg_error (GPG_ERR_INV_DATA);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
ecc_ct_len = ecc_ecdh_len = 56;
|
||||||
|
ecc_ss_len = 64;
|
||||||
|
ecc_hash_algo = GCRY_MD_SHA3_512;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -528,7 +555,7 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
|||||||
log_printhex (ecc_ecdh, ecc_ecdh_len, "ECC ecdh:");
|
log_printhex (ecc_ecdh, ecc_ecdh_len, "ECC ecdh:");
|
||||||
}
|
}
|
||||||
err = gnupg_ecc_kem_kdf (ecc_ss, ecc_ss_len,
|
err = gnupg_ecc_kem_kdf (ecc_ss, ecc_ss_len,
|
||||||
GCRY_MD_SHA3_256,
|
ecc_hash_algo,
|
||||||
ecc_ecdh, ecc_ecdh_len,
|
ecc_ecdh, ecc_ecdh_len,
|
||||||
ecc_ct, ecc_ct_len,
|
ecc_ct, ecc_ct_len,
|
||||||
ecc_pubkey, ecc_pubkey_len);
|
ecc_pubkey, ecc_pubkey_len);
|
||||||
@ -665,9 +692,9 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
wipememory (ecc_ct, ecc_ct_len);
|
wipememory (ecc_ct, sizeof ecc_ct);
|
||||||
wipememory (ecc_ecdh, ecc_ecdh_len);
|
wipememory (ecc_ecdh, sizeof ecc_ecdh);
|
||||||
wipememory (ecc_ss, ecc_ss_len);
|
wipememory (ecc_ss, sizeof ecc_ss);
|
||||||
wipememory (kyber_ct, sizeof kyber_ct);
|
wipememory (kyber_ct, sizeof kyber_ct);
|
||||||
wipememory (kyber_ss, sizeof kyber_ss);
|
wipememory (kyber_ss, sizeof kyber_ss);
|
||||||
wipememory (kek, kek_len);
|
wipememory (kek, kek_len);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user