aboutsummaryrefslogtreecommitdiffstats
path: root/g10/pkglue.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/pkglue.c280
1 files changed, 71 insertions, 209 deletions
diff --git a/g10/pkglue.c b/g10/pkglue.c
index a97bb39c7..a6bd893b3 100644
--- a/g10/pkglue.c
+++ b/g10/pkglue.c
@@ -33,11 +33,6 @@
#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
gcrypt macros. */
gcry_mpi_t
@@ -432,7 +427,9 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
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 char *curve;
+ const struct gnupg_ecc_params *ecc;
+ enum gcry_kem_algos kyber_algo;
const unsigned char *ecc_pubkey;
size_t ecc_pubkey_len;
@@ -473,68 +470,35 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
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 development\n");
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- 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)
+ curve = openpgp_oid_to_curve (ecc_oid, 1);
+ if (!curve)
{
- 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;
+ err = gpg_error (GPG_ERR_INV_DATA);
+ log_error ("%s: error getting curve for ECC key\n", __func__);
+ goto leave;
}
- else if (ecc_algo == GCRY_KEM_RAW_BP256)
+ ecc = gnupg_get_ecc_params (curve);
+ if (!ecc)
{
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 65)
- {
- 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 = 65;
- ecc_ss_len = 32;
- ecc_hash_algo = GCRY_MD_SHA3_256;
+ if (opt.verbose)
+ log_info ("%s: ECC curve %s not supported\n", __func__, curve);
+ err = gpg_error (GPG_ERR_INV_DATA);
+ goto leave;
}
- else if (ecc_algo == GCRY_KEM_RAW_BP384)
+ ecc_ct_len = ecc_ecdh_len = ecc->point_len;
+ ecc_ss_len = ecc->scalar_len;
+ ecc_hash_algo = ecc->hash_algo;
+
+ ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
+ ecc_pubkey_len = (nbits+7)/8;
+ if (ecc_pubkey_len != ecc->pubkey_len)
{
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 97)
+ if (ecc->kem_algo == GCRY_KEM_RAW_X25519
+ && ecc_pubkey_len == ecc->pubkey_len - 1)
+ /* For Curve25519, we also accept no prefix in the point
+ * representation. */
+ ;
+ else
{
if (opt.verbose)
log_info ("%s: ECC public key length invalid (%zu)\n",
@@ -542,42 +506,28 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo,
err = gpg_error (GPG_ERR_INV_DATA);
goto leave;
}
- ecc_ct_len = ecc_ecdh_len = 97;
- ecc_ss_len = 64;
- ecc_hash_algo = GCRY_MD_SHA3_512;
}
- else if (ecc_algo == GCRY_KEM_RAW_BP512)
+
+ if (ecc->kem_algo == GCRY_KEM_RAW_X25519)
{
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 129)
+ if (!strcmp (ecc_oid, "1.3.6.1.4.1.3029.1.5.1"))
+ log_info ("Warning: "
+ "legacy OID for cv25519 accepted during development\n");
+ /* Optional prefix handling */
+ if (ecc_pubkey_len == 33 && *ecc_pubkey == 0x40)
{
- 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_pubkey++; /* Remove the 0x40 prefix. */
+ ecc_pubkey_len--;
}
- ecc_ct_len = ecc_ecdh_len = 129;
- ecc_ss_len = 64;
- ecc_hash_algo = GCRY_MD_SHA3_512;
- }
- 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;
}
-
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,
+ err = gcry_kem_encap (ecc->kem_algo,
ecc_pubkey, ecc_pubkey_len,
ecc_ct, ecc_ct_len,
ecc_ecdh, ecc_ecdh_len,
@@ -754,7 +704,8 @@ do_encrypt_ecdh (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr)
unsigned int nbits;
gcry_cipher_hd_t hd = NULL;
char *ecc_oid = NULL;
- enum gcry_kem_algos ecc_algo;
+ const char *curve;
+ const struct gnupg_ecc_params *ecc;
const unsigned char *ecc_pubkey;
size_t ecc_pubkey_len;
@@ -766,7 +717,6 @@ do_encrypt_ecdh (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr)
unsigned char ecc_ct[ECC_POINT_LEN_MAX];
unsigned char ecc_ecdh[ECC_POINT_LEN_MAX];
size_t ecc_ct_len, ecc_ecdh_len;
- int is_weierstrass;
unsigned char *kek = NULL;
size_t kek_len;
@@ -787,108 +737,33 @@ do_encrypt_ecdh (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr)
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)
- {
- /* Legacy OID is OK here. */
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- 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;
- is_weierstrass = 0;
- }
- 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;
- is_weierstrass = 0;
- }
- else if (ecc_algo == GCRY_KEM_RAW_BP256)
- {
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 65)
- {
- 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 = 65;
- is_weierstrass = 1;
- }
- else if (ecc_algo == GCRY_KEM_RAW_BP384)
+ curve = openpgp_oid_to_curve (ecc_oid, 1);
+ if (!curve)
{
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 97)
- {
- 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 = 97;
- is_weierstrass = 1;
- }
- else if (ecc_algo == GCRY_KEM_RAW_BP512)
- {
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 129)
- {
- 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 = 129;
- is_weierstrass = 1;
+ err = gpg_error (GPG_ERR_INV_DATA);
+ log_error ("%s: error getting curve for ECC key\n", __func__);
+ goto leave;
}
- else if (ecc_algo == GCRY_KEM_RAW_P256R1)
+ ecc = gnupg_get_ecc_params (curve);
+ if (!ecc)
{
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 65)
- {
- 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 = 65;
- is_weierstrass = 1;
+ if (opt.verbose)
+ log_info ("%s: ECC curve %s not supported\n", __func__, curve);
+ err = gpg_error (GPG_ERR_INV_DATA);
+ goto leave;
}
- else if (ecc_algo == GCRY_KEM_RAW_P384R1)
+ ecc_ct_len = ecc_ecdh_len = ecc->point_len;
+
+ ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
+ ecc_pubkey_len = (nbits+7)/8;
+ if (ecc_pubkey_len != ecc->pubkey_len)
{
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 97)
+ if (ecc->kem_algo == GCRY_KEM_RAW_X25519
+ && ecc_pubkey_len == ecc->pubkey_len - 1)
+ /* For Curve25519, we also accept no prefix in the point
+ * representation. */
+ ;
+ else
{
if (opt.verbose)
log_info ("%s: ECC public key length invalid (%zu)\n",
@@ -896,30 +771,17 @@ do_encrypt_ecdh (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr)
err = gpg_error (GPG_ERR_INV_DATA);
goto leave;
}
- ecc_ct_len = ecc_ecdh_len = 97;
- is_weierstrass = 1;
}
- else if (ecc_algo == GCRY_KEM_RAW_P521R1)
+
+ if (ecc->kem_algo == GCRY_KEM_RAW_X25519)
{
- ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits);
- ecc_pubkey_len = (nbits+7)/8;
- if (ecc_pubkey_len != 133)
+ /* Note: Legacy OID is OK here. */
+ /* Optional prefix handling */
+ if (ecc_pubkey_len == 33 && *ecc_pubkey == 0x40)
{
- 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_pubkey++; /* Remove the 0x40 prefix. */
+ ecc_pubkey_len--;
}
- ecc_ct_len = ecc_ecdh_len = 133;
- is_weierstrass = 1;
- }
- 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;
}
if (DBG_CRYPTO)
@@ -928,7 +790,7 @@ do_encrypt_ecdh (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr)
log_printhex (ecc_pubkey, ecc_pubkey_len, "ECC pubkey:");
}
- err = gcry_kem_encap (ecc_algo,
+ err = gcry_kem_encap (ecc->kem_algo,
ecc_pubkey, ecc_pubkey_len,
ecc_ct, ecc_ct_len,
ecc_ecdh, ecc_ecdh_len,
@@ -990,9 +852,9 @@ do_encrypt_ecdh (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr)
}
err = gnupg_ecc_kem_kdf (kek, kek_len, kdf_hash_algo,
- is_weierstrass ?
+ ecc->is_weierstrauss ?
ecc_ecdh + 1 : ecc_ecdh,
- is_weierstrass ?
+ ecc->is_weierstrauss ?
(ecc_ecdh_len - 1) / 2 : ecc_ecdh_len,
NULL, 0, NULL, 0,
kdf_params, kdf_params_len);