aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2025-10-07 03:59:48 +0200
committerNIIBE Yutaka <[email protected]>2025-10-07 03:59:48 +0200
commit06f993dc0eceee0f6ec99b9417d4368eee203e6d (patch)
tree829c77502dfc0566a0f2189d312639cf8e95c663 /common
parentdirmngr: Fix wrong diagnostic "failed to create alarm thread". (diff)
downloadgnupg-06f993dc0eceee0f6ec99b9417d4368eee203e6d.tar.gz
gnupg-06f993dc0eceee0f6ec99b9417d4368eee203e6d.zip
agent,common,gpg: Clean up for S/MIME decryption with KEM API.
* agent/agent.h (agent_kem_decrypt): Remove OPTION argument. * agent/command.c (cmd_pkdecrypt): No option is needed. * agent/pkdecrypt.c (composite_pgp_kem_decrypt): Use gnupg_ecc_kem_simple_kdf. (ecc_kem_decrypt): Support the S/MIME case too. Follow the change of gnupg_ecc_kem_kdf. (agent_kem_decrypt): Remove OPTION argument. Also support the S/MIME case. * common/kem.c (gnupg_ecc_kem_kdf): Support the S/MIME case too. Don't support simple ECC part for combined KEM. (gnupg_ecc_kem_simple_kdf): New. * common/util.h (gnupg_ecc_kem_kdf): Support the S/MIME case too. (gnupg_ecc_kem_simple_kdf): New. * g10/pkglue.c (do_encrypt_kem): Use gnupg_ecc_kem_simple_kdf. Use gnupg_ecc_kem_kdf with IS_GPG=1. -- GnuPG-bug-id: 7811 Signed-off-by: NIIBE Yutaka <[email protected]>
Diffstat (limited to 'common')
-rw-r--r--common/kem.c93
-rw-r--r--common/util.h17
2 files changed, 63 insertions, 47 deletions
diff --git a/common/kem.c b/common/kem.c
index 94ad13457..2f479aa7a 100644
--- a/common/kem.c
+++ b/common/kem.c
@@ -144,60 +144,67 @@ compute_kmac256 (void *digest, size_t digestlen,
}
-/* Compute KEK for ECC with HASHALGO, ECDH result, ciphertext in
- * ECC_CT (which is an ephemeral key), and public key in ECC_PK.
+/* Compute KEK for ECC with HASHALGO, ECDH result, and KDF_PARAMS.
*
- * For traditional ECC (of v4), KDF_PARAMS is specified by upper layer
- * and an ephemeral key and public key are not used for the
- * computation.
+ * KDF_PARAMS is specified by upper layer.
*/
gpg_error_t
-gnupg_ecc_kem_kdf (void *kek, size_t kek_len,
+gnupg_ecc_kem_kdf (void *kek, size_t kek_len, int is_pgp,
int hashalgo, const void *ecdh, size_t ecdh_len,
- const void *ecc_ct, size_t ecc_ct_len,
- const void *ecc_pk, size_t ecc_pk_len,
- unsigned char *kdf_params, size_t kdf_params_len)
+ const unsigned char *kdf_params, size_t kdf_params_len)
{
- if (kdf_params)
- {
- /* Traditional ECC */
- gpg_error_t err;
- gcry_kdf_hd_t hd;
- unsigned long param[1];
-
- param[0] = kek_len;
- err = gcry_kdf_open (&hd, GCRY_KDF_ONESTEP_KDF, hashalgo, param, 1,
- ecdh, ecdh_len, NULL, 0, NULL, 0,
- kdf_params, kdf_params_len);
- if (!err)
- {
- gcry_kdf_compute (hd, NULL);
- gcry_kdf_final (hd, kek_len, kek);
- gcry_kdf_close (hd);
- }
+ /* Traditional ECC */
+ gpg_error_t err;
+ gcry_kdf_hd_t hd;
+ unsigned long param[1];
+ int kdf_algo;
- return err;
- }
+ if (is_pgp)
+ kdf_algo = GCRY_KDF_ONESTEP_KDF;
else
+ kdf_algo = GCRY_KDF_X963_KDF;
+
+ param[0] = kek_len;
+ err = gcry_kdf_open (&hd, kdf_algo, hashalgo, param, 1,
+ ecdh, ecdh_len, NULL, 0, NULL, 0,
+ kdf_params, kdf_params_len);
+ if (!err)
{
- /* ECC in composite KEM */
- gcry_buffer_t iov[3];
- unsigned int dlen;
+ gcry_kdf_compute (hd, NULL);
+ gcry_kdf_final (hd, kek_len, kek);
+ gcry_kdf_close (hd);
+ }
+
+ return err;
+}
+
+
+/* Compute KEK for ECC with HASHALGO, ECDH result, ciphertext in
+ * ECC_CT (which is an ephemeral key), and public key in ECC_PK.
+ */
+gpg_error_t
+gnupg_ecc_kem_simple_kdf (void *kek, size_t kek_len,
+ int hashalgo, const void *ecdh, size_t ecdh_len,
+ const void *ecc_ct, size_t ecc_ct_len,
+ const void *ecc_pk, size_t ecc_pk_len)
+{
+ /* ECC part in composite KEM */
+ gcry_buffer_t iov[3];
+ unsigned int dlen;
- dlen = gcry_md_get_algo_dlen (hashalgo);
- if (kek_len != dlen)
- return gpg_error (GPG_ERR_INV_LENGTH);
+ dlen = gcry_md_get_algo_dlen (hashalgo);
+ if (kek_len != dlen)
+ return gpg_error (GPG_ERR_INV_LENGTH);
- memset (iov, 0, sizeof (iov));
+ memset (iov, 0, sizeof (iov));
- iov[0].data = (unsigned char *)ecdh;
- iov[0].len = ecdh_len;
- iov[1].data = (unsigned char *)ecc_ct;
- iov[1].len = ecc_ct_len;
- iov[2].data = (unsigned char *)ecc_pk;
- iov[2].len = ecc_pk_len;
- gcry_md_hash_buffers (hashalgo, 0, kek, iov, 3);
- }
+ iov[0].data = (unsigned char *)ecdh;
+ iov[0].len = ecdh_len;
+ iov[1].data = (unsigned char *)ecc_ct;
+ iov[1].len = ecc_ct_len;
+ iov[2].data = (unsigned char *)ecc_pk;
+ iov[2].len = ecc_pk_len;
+ gcry_md_hash_buffers (hashalgo, 0, kek, iov, 3);
return 0;
}
diff --git a/common/util.h b/common/util.h
index 3fb205685..8f54ffaa5 100644
--- a/common/util.h
+++ b/common/util.h
@@ -315,13 +315,22 @@ char *gnupg_get_help_string (const char *key, int only_current_locale);
const char *gnupg_messages_locale_name (void);
/*-- kem.c --*/
-gpg_error_t gnupg_ecc_kem_kdf (void *kek, size_t kek_len,
+gpg_error_t
+gpgsm_ecc_kem_kdf (void *kek, size_t kek_len,
+ int hashalgo, const void *ecdh, size_t ecdh_len,
+ const unsigned char *wrap, size_t wrap_len,
+ const unsigned char *ukm, size_t ukm_len);
+
+gpg_error_t gnupg_ecc_kem_kdf (void *kek, size_t kek_len, int is_pgp,
int hashalgo, const void *ecdh, size_t ecdh_len,
- const void *ecc_ct, size_t ecc_ct_len,
- const void *ecc_pk, size_t ecc_pk_len,
- unsigned char *kdf_params,
+ const unsigned char *kdf_params,
size_t kdf_params_len);
+gpg_error_t gnupg_ecc_kem_simple_kdf (void *kek, size_t kek_len, int hashalgo,
+ const void *ecdh, size_t ecdh_len,
+ const void *ecc_ct, size_t ecc_ct_len,
+ const void *ecc_pk, size_t ecc_pk_len);
+
gpg_error_t gnupg_kem_combiner (void *kek, size_t kek_len,
const void *ecc_ss, size_t ecc_ss_len,
const void *ecc_ct, size_t ecc_ct_len,