1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

common:kem: Factor out a function to retrieve ECC parameters.

* common/util.h (struct gnupg_ecc_params, gnupg_get_ecc_params): New.
(ECC_SCALAR_LEN_MAX, ECC_POINT_LEN_MAX, ECC_HASH_LEN_MAX): New.
* agent/pkdecrypt.c (ecc_extract_pk_from_key, ecc_extract_sk_from_key):
Follow the change of gnupg_get_ecc_params.
(ecc_raw_kem, ecc_pgp_kem_decap, composite_pgp_kem_decrypt): Likewise.
(ecc_kem_decrypt): Likewise.
(get_ecc_params): Move to...
* common/kem.c (gnupg_get_ecc_params): ... here
* g10/pkglue.c (ECC_POINT_LEN_MAX, ECC_HASH_LEN_MAX): Remove duplicates.

--

GnuPG-bug-id: 7649
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2025-07-03 15:45:52 +09:00
parent a354018bf3
commit 5e623b71d5
No known key found for this signature in database
GPG key ID: 640114AF89DE6054
4 changed files with 104 additions and 112 deletions

View file

@ -28,102 +28,9 @@
#include "agent.h" #include "agent.h"
#include "../common/openpgpdefs.h" #include "../common/openpgpdefs.h"
#include "../common/util.h"
/* Table with parameters for KEM decryption. Use get_ecc_parms to
* find an entry. */
struct ecc_params
{
const char *curve; /* Canonical name of the curve. */
size_t pubkey_len; /* Pubkey length in the SEXP representation. */
size_t scalar_len;
size_t point_len;
int hash_algo; /* Hash algo when it's used for composite KEM. */
int kem_algo;
int scalar_reverse;
};
/* The first entry must be Curve25519, to handle the prefix of 0x40 in
OpenPGP. */
#define ECC_CURVE25519_INDEX 0
static const struct ecc_params ecc_table[] =
{
{
"Curve25519",
33, 32, 32,
GCRY_MD_SHA3_256, GCRY_KEM_RAW_X25519,
1
},
{
"X448",
56, 56, 56,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_X448,
0
},
{
"NIST P-256",
65, 32, 65,
GCRY_MD_SHA3_256, GCRY_KEM_RAW_P256R1,
0
},
{
"NIST P-384",
97, 48, 97,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_P384R1,
0
},
{
"NIST P-521",
133, 66, 133,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_P521R1,
0
},
{
"brainpoolP256r1",
65, 32, 65,
GCRY_MD_SHA3_256, GCRY_KEM_RAW_BP256,
0
},
{
"brainpoolP384r1",
97, 48, 97,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP384,
0
},
{
"brainpoolP512r1",
129, 64, 129,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP512,
0
},
{ NULL, 0, 0, 0, 0, 0, 0 }
};
/* Maximum buffer sizes required for ECC KEM. Keep this aligned to
* the ecc_table above. */
#define ECC_SCALAR_LEN_MAX 66
#define ECC_POINT_LEN_MAX (1+2*ECC_SCALAR_LEN_MAX)
#define ECC_HASH_LEN_MAX 64
/* Return the ECC parameters for CURVE. CURVE is expected to be the
* canonical name. */
static const struct ecc_params *
get_ecc_params (const char *curve)
{
int i;
for (i = 0; ecc_table[i].curve; i++)
if (!strcmp (ecc_table[i].curve, curve))
return &ecc_table[i];
return NULL;
}
/* DECRYPT the stuff in ciphertext which is expected to be a S-Exp. /* DECRYPT the stuff in ciphertext which is expected to be a S-Exp.
Try to get the key from CTRL and write the decoded stuff back to Try to get the key from CTRL and write the decoded stuff back to
OUTFP. The padding information is stored at R_PADDING with -1 OUTFP. The padding information is stored at R_PADDING with -1
@ -265,8 +172,8 @@ reverse_buffer (unsigned char *buffer, unsigned int length)
static gpg_error_t static gpg_error_t
ecc_extract_pk_from_key (const struct ecc_params *ecc, gcry_sexp_t s_skey, ecc_extract_pk_from_key (const struct gnupg_ecc_params *ecc,
unsigned char *ecc_pk) gcry_sexp_t s_skey, unsigned char *ecc_pk)
{ {
gpg_error_t err; gpg_error_t err;
unsigned int nbits; unsigned int nbits;
@ -311,8 +218,8 @@ ecc_extract_pk_from_key (const struct ecc_params *ecc, gcry_sexp_t s_skey,
} }
static gpg_error_t static gpg_error_t
ecc_extract_sk_from_key (const struct ecc_params *ecc, gcry_sexp_t s_skey, ecc_extract_sk_from_key (const struct gnupg_ecc_params *ecc,
unsigned char *ecc_sk) gcry_sexp_t s_skey, unsigned char *ecc_sk)
{ {
gpg_error_t err; gpg_error_t err;
unsigned int nbits; unsigned int nbits;
@ -353,7 +260,7 @@ ecc_extract_sk_from_key (const struct ecc_params *ecc, gcry_sexp_t s_skey,
} }
static gpg_error_t static gpg_error_t
ecc_raw_kem (const struct ecc_params *ecc, gcry_sexp_t s_skey, ecc_raw_kem (const struct gnupg_ecc_params *ecc, gcry_sexp_t s_skey,
const unsigned char *ecc_ct, unsigned char *ecc_ecdh) const unsigned char *ecc_ct, unsigned char *ecc_ecdh)
{ {
gpg_error_t err = 0; gpg_error_t err = 0;
@ -456,11 +363,11 @@ ecc_pgp_kem_decap (ctrl_t ctrl, gcry_sexp_t s_skey0,
const unsigned char *ecc_ct, size_t ecc_point_len, const unsigned char *ecc_ct, size_t ecc_point_len,
unsigned char ecc_ecdh[ECC_POINT_LEN_MAX], unsigned char ecc_ecdh[ECC_POINT_LEN_MAX],
unsigned char ecc_pk[ECC_POINT_LEN_MAX], unsigned char ecc_pk[ECC_POINT_LEN_MAX],
const struct ecc_params **r_ecc) const struct gnupg_ecc_params **r_ecc)
{ {
gpg_error_t err; gpg_error_t err;
const char *curve; const char *curve;
const struct ecc_params *ecc = NULL; const struct gnupg_ecc_params *ecc = NULL;
if (ecc_point_len > ECC_POINT_LEN_MAX) if (ecc_point_len > ECC_POINT_LEN_MAX)
return gpg_error (GPG_ERR_INV_DATA); return gpg_error (GPG_ERR_INV_DATA);
@ -478,7 +385,7 @@ ecc_pgp_kem_decap (ctrl_t ctrl, gcry_sexp_t s_skey0,
if (DBG_CRYPTO) if (DBG_CRYPTO)
log_debug ("ECC curve: %s\n", curve); log_debug ("ECC curve: %s\n", curve);
ecc = get_ecc_params (curve); ecc = gnupg_get_ecc_params (curve);
if (!ecc) if (!ecc)
{ {
if (opt.verbose) if (opt.verbose)
@ -487,8 +394,8 @@ ecc_pgp_kem_decap (ctrl_t ctrl, gcry_sexp_t s_skey0,
} }
*r_ecc = ecc; *r_ecc = ecc;
if (ecc == &ecc_table[ECC_CURVE25519_INDEX] if (ecc->may_have_prefix && ecc_point_len == ecc->point_len + 1
&& ecc_point_len == ecc->point_len + 1 && *ecc_ct == 0x40) && *ecc_ct == 0x40)
{ {
ecc_ct++; ecc_ct++;
ecc_point_len--; ecc_point_len--;
@ -583,7 +490,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text,
unsigned char ecc_ss[ECC_HASH_LEN_MAX]; unsigned char ecc_ss[ECC_HASH_LEN_MAX];
int ecc_hashalgo; int ecc_hashalgo;
size_t ecc_shared_len, ecc_point_len; size_t ecc_shared_len, ecc_point_len;
const struct ecc_params *ecc; const struct gnupg_ecc_params *ecc;
enum gcry_kem_algos mlkem_kem_algo; enum gcry_kem_algos mlkem_kem_algo;
gcry_mpi_t mlkem_sk_mpi = NULL; gcry_mpi_t mlkem_sk_mpi = NULL;
@ -832,7 +739,7 @@ ecc_kem_decrypt (ctrl_t ctrl, const char *desc_text,
unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; unsigned char ecc_ecdh[ECC_POINT_LEN_MAX];
unsigned char ecc_pk[ECC_POINT_LEN_MAX]; unsigned char ecc_pk[ECC_POINT_LEN_MAX];
size_t ecc_point_len; size_t ecc_point_len;
const struct ecc_params *ecc; const struct gnupg_ecc_params *ecc;
unsigned char *kek = NULL; unsigned char *kek = NULL;
size_t kek_len; size_t kek_len;

View file

@ -35,7 +35,7 @@
#include <gpg-error.h> #include <gpg-error.h>
#include <gcrypt.h> #include <gcrypt.h>
#include "mischelp.h" #include "mischelp.h"
#include "util.h"
/* domSeperation as per *PGP specs. */ /* domSeperation as per *PGP specs. */
#define KMAC_KEY "OpenPGPCompositeKeyDerivationFunction" #define KMAC_KEY "OpenPGPCompositeKeyDerivationFunction"
@ -248,3 +248,72 @@ gnupg_kem_combiner (void *kek, size_t kek_len,
KMAC_CUSTOM, strlen (KMAC_CUSTOM), iov, 6); KMAC_CUSTOM, strlen (KMAC_CUSTOM), iov, 6);
return err; return err;
} }
#define ECC_CURVE25519_INDEX 0
static const struct gnupg_ecc_params ecc_table[] =
{
{
"Curve25519",
33, 32, 32,
GCRY_MD_SHA3_256, GCRY_KEM_RAW_X25519,
1, 1
},
{
"X448",
56, 56, 56,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_X448,
0, 0
},
{
"NIST P-256",
65, 32, 65,
GCRY_MD_SHA3_256, GCRY_KEM_RAW_P256R1,
0, 0
},
{
"NIST P-384",
97, 48, 97,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_P384R1,
0, 0
},
{
"NIST P-521",
133, 66, 133,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_P521R1,
0, 0
},
{
"brainpoolP256r1",
65, 32, 65,
GCRY_MD_SHA3_256, GCRY_KEM_RAW_BP256,
0, 0
},
{
"brainpoolP384r1",
97, 48, 97,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP384,
0, 0
},
{
"brainpoolP512r1",
129, 64, 129,
GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP512,
0, 0
},
{ NULL, 0, 0, 0, 0, 0, 0, 0 }
};
/* Return the ECC parameters for CURVE. CURVE is expected to be the
* canonical name. */
const struct gnupg_ecc_params *
gnupg_get_ecc_params (const char *curve)
{
int i;
for (i = 0; ecc_table[i].curve; i++)
if (!strcmp (ecc_table[i].curve, curve))
return &ecc_table[i];
return NULL;
}

View file

@ -324,6 +324,27 @@ gpg_error_t gnupg_kem_combiner (void *kek, size_t kek_len,
const void *mlkem_ct, size_t mlkem_ct_len, const void *mlkem_ct, size_t mlkem_ct_len,
const void *fixedinfo, size_t fixedinfo_len); const void *fixedinfo, size_t fixedinfo_len);
/* ECC parameters for KEM encryption/decryption. */
struct gnupg_ecc_params
{
const char *curve; /* Canonical name of the curve. */
size_t pubkey_len; /* Pubkey length in the SEXP representation. */
size_t scalar_len;
size_t point_len;
int hash_algo; /* Hash algo when it's used for composite KEM. */
int kem_algo;
int scalar_reverse; /* Byte-oder is reverse. */
int may_have_prefix; /* Point representation may have prefix. */
};
const struct gnupg_ecc_params *gnupg_get_ecc_params (const char *curve);
/* Maximum buffer sizes required for ECC KEM. */
#define ECC_SCALAR_LEN_MAX 66
#define ECC_POINT_LEN_MAX (1+2*ECC_SCALAR_LEN_MAX)
#define ECC_HASH_LEN_MAX 64
/*-- miscellaneous.c --*/ /*-- miscellaneous.c --*/
/* This function is called at startup to tell libgcrypt to use our own /* This function is called at startup to tell libgcrypt to use our own

View file

@ -33,11 +33,6 @@
#include "options.h" #include "options.h"
/* Maximum buffer sizes required for ECC KEM. */
#define ECC_POINT_LEN_MAX (1+2*66)
#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