diff options
| author | NIIBE Yutaka <[email protected]> | 2025-10-07 03:59:48 +0200 |
|---|---|---|
| committer | NIIBE Yutaka <[email protected]> | 2025-10-07 03:59:48 +0200 |
| commit | 06f993dc0eceee0f6ec99b9417d4368eee203e6d (patch) | |
| tree | 829c77502dfc0566a0f2189d312639cf8e95c663 /common | |
| parent | dirmngr: Fix wrong diagnostic "failed to create alarm thread". (diff) | |
| download | gnupg-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.c | 93 | ||||
| -rw-r--r-- | common/util.h | 17 |
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, |
