diff options
author | Werner Koch <[email protected]> | 2024-04-23 09:20:37 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2024-04-23 09:31:49 +0000 |
commit | e591fd25adc3c40561e9ebebb9d08abbaea0ad63 (patch) | |
tree | 57f2bb99656e4350ea3f749ac6dec2e7266fbfc4 /g10/pkglue.c | |
parent | Require Libgcrypt 1.11.0 (diff) | |
download | gnupg-e591fd25adc3c40561e9ebebb9d08abbaea0ad63.tar.gz gnupg-e591fd25adc3c40561e9ebebb9d08abbaea0ad63.zip |
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
Diffstat (limited to 'g10/pkglue.c')
-rw-r--r-- | g10/pkglue.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/g10/pkglue.c b/g10/pkglue.c index 2de0e80ab..fb39d5ba8 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -32,6 +32,12 @@ #include "main.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 gcrypt macros. */ 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; unsigned char *enc_seskey = NULL; size_t enc_seskey_len; + int ecc_hash_algo; - unsigned char ecc_ct[GCRY_KEM_ECC_X25519_ENCAPS_LEN]; - size_t ecc_ct_len = GCRY_KEM_ECC_X25519_ENCAPS_LEN; - unsigned char ecc_ecdh[GCRY_KEM_RAW_X25519_SHARED_LEN]; - size_t ecc_ecdh_len = GCRY_KEM_RAW_X25519_SHARED_LEN; - unsigned char ecc_ss[GCRY_KEM_RAW_X25519_SHARED_LEN]; - size_t ecc_ss_len = GCRY_KEM_RAW_X25519_SHARED_LEN; + unsigned char ecc_ct[ECC_POINT_LEN_MAX]; + unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; + unsigned char ecc_ss[ECC_HASH_LEN_MAX]; + size_t ecc_ct_len, ecc_ecdh_len, ecc_ss_len; unsigned char kyber_ct[GCRY_KEM_MLKEM1024_ENCAPS_LEN]; unsigned char kyber_ss[GCRY_KEM_MLKEM1024_SHARED_LEN]; @@ -484,7 +489,28 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, "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) + 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) + 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 = 32; + 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", @@ -492,8 +518,9 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - ecc_pubkey++; /* Remove the 0x40 prefix. */ - ecc_pubkey_len--; + ecc_ct_len = ecc_ecdh_len = 56; + ecc_ss_len = 64; + ecc_hash_algo = GCRY_MD_SHA3_512; } 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:"); } err = gnupg_ecc_kem_kdf (ecc_ss, ecc_ss_len, - GCRY_MD_SHA3_256, + ecc_hash_algo, ecc_ecdh, ecc_ecdh_len, ecc_ct, ecc_ct_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: - wipememory (ecc_ct, ecc_ct_len); - wipememory (ecc_ecdh, ecc_ecdh_len); - wipememory (ecc_ss, ecc_ss_len); + wipememory (ecc_ct, sizeof ecc_ct); + wipememory (ecc_ecdh, sizeof ecc_ecdh); + wipememory (ecc_ss, sizeof ecc_ss); wipememory (kyber_ct, sizeof kyber_ct); wipememory (kyber_ss, sizeof kyber_ss); wipememory (kek, kek_len); |