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

Experiment to use KEM interface for Curve25519 ECDH.

Works now with hard-coded, but not checked things.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2024-01-26 15:34:03 +09:00
parent eaa3be7ff2
commit 3114d16bf2
No known key found for this signature in database
GPG key ID: 640114AF89DE6054
9 changed files with 253 additions and 13 deletions

View file

@ -75,6 +75,8 @@ struct cipher_parm_s
assuan_context_t ctx;
unsigned char *ciphertext;
size_t ciphertextlen;
const unsigned char *option;
size_t optionlen;
};
struct writecert_parm_s
@ -2748,6 +2750,13 @@ inq_ciphertext_cb (void *opaque, const char *line)
parm->ciphertext, parm->ciphertextlen);
assuan_end_confidential (parm->ctx);
}
else if (has_leading_keyword (line, "OPTION"))
{
assuan_begin_confidential (parm->ctx);
rc = assuan_send_data (parm->dflt->ctx,
parm->option, parm->optionlen);
assuan_end_confidential (parm->ctx);
}
else
rc = default_inq_cb (parm->dflt, line);
@ -2782,7 +2791,8 @@ gpg_error_t
agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
u32 *keyid, u32 *mainkeyid, int pubkey_algo,
gcry_sexp_t s_ciphertext,
unsigned char **r_buf, size_t *r_buflen, int *r_padding)
unsigned char **r_buf, size_t *r_buflen, int *r_padding,
int use_kem, const unsigned char *option, size_t optionlen)
{
gpg_error_t err;
char line[ASSUAN_LINELENGTH];
@ -2837,7 +2847,10 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen);
if (err)
return err;
err = assuan_transact (agent_ctx, "PKDECRYPT",
parm.option = option;
parm.optionlen = optionlen;
snprintf (line, sizeof line, "PKDECRYPT%s", use_kem? " --kem" : "");
err = assuan_transact (agent_ctx, line,
put_membuf_cb, &data,
inq_ciphertext_cb, &parm,
padding_info_cb, r_padding);

View file

@ -219,7 +219,8 @@ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
u32 *keyid, u32 *mainkeyid, int pubkey_algo,
gcry_sexp_t s_ciphertext,
unsigned char **r_buf, size_t *r_buflen,
int *r_padding);
int *r_padding, int use_kem,
const unsigned char *option, size_t optionlen);
/* Retrieve a key encryption key. */
gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,

View file

@ -142,7 +142,7 @@ extract_secret_x (byte **r_secret_x,
master key fingerprint". For v5 key, it is considered "adequate"
(in terms of NIST SP 800 56A, see 5.8.2 FixedInfo) to use the first
20 octets of its 32 octets fingerprint. */
static gpg_error_t
gpg_error_t
build_kdf_params (unsigned char kdf_params[256], size_t *r_size,
gcry_mpi_t *pkey, const byte pk_fp[MAX_FINGERPRINT_LEN])
{

View file

@ -471,6 +471,7 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
int kdf_encr_algo;
gcry_cipher_hd_t hd;
/*FIXME use build_kdf_params! */
oid = gcry_mpi_get_opaque (pkey[0], &nbits);
oidlen = (nbits + 7) / 8;

View file

@ -37,6 +37,9 @@ int pk_check_secret_key (pubkey_algo_t algo, gcry_mpi_t *skey);
/*-- ecdh.c --*/
gpg_error_t
build_kdf_params (unsigned char kdf_params[256], size_t *r_size,
gcry_mpi_t *pkey, const byte pk_fp[MAX_FINGERPRINT_LEN]);
gcry_mpi_t pk_ecdh_default_params (unsigned int qbits);
gpg_error_t pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k);
gpg_error_t pk_ecdh_encrypt_with_shared_point

View file

@ -244,13 +244,48 @@ get_it (ctrl_t ctrl,
goto leave;
if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
fingerprint_from_pk (sk, fp, NULL);
{
int with_ecdh_cv25519;
fingerprint_from_pk (sk, fp, NULL);
with_ecdh_cv25519 = openpgp_oid_is_cv25519 (sk->pkey[0]);
if (with_ecdh_cv25519)
{
unsigned char kdf_params[256];
size_t kdf_params_size;
log_info ("ECDH KEM\n");
build_kdf_params (kdf_params, &kdf_params_size,
sk->pkey, fp);
log_printhex (kdf_params, kdf_params_size, "KDF (option):");
log_printsexp ("sexp data:", s_data);
/* Do PKDECRYPT with --kem. */
desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1);
err = agent_pkdecrypt (NULL, keygrip,
desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
s_data, &frame, &nframe, &padding,
1, kdf_params, kdf_params_size);
xfree (desc);
gcry_sexp_release (s_data);
log_printhex (frame, nframe, "DEK frame:");
if (err)
goto leave;
goto decryption_done;
}
}
/* Decrypt. */
desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1);
err = agent_pkdecrypt (NULL, keygrip,
desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
s_data, &frame, &nframe, &padding);
s_data, &frame, &nframe, &padding,
0, NULL, 0);
xfree (desc);
gcry_sexp_release (s_data);
if (err)
@ -293,6 +328,8 @@ get_it (ctrl_t ctrl,
if (err)
goto leave;
decryption_done:
/* Now the frame are the bytes decrypted but padded session key. */
if (!nframe || nframe <= 8
|| frame[nframe-1] > nframe)