aboutsummaryrefslogtreecommitdiffstats
path: root/g10/pkglue.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-04-23 09:20:37 +0000
committerWerner Koch <[email protected]>2024-04-23 09:31:49 +0000
commite591fd25adc3c40561e9ebebb9d08abbaea0ad63 (patch)
tree57f2bb99656e4350ea3f749ac6dec2e7266fbfc4 /g10/pkglue.c
parentRequire Libgcrypt 1.11.0 (diff)
downloadgnupg-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.c53
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);