diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/call-agent.c | 17 | ||||
-rw-r--r-- | g10/call-agent.h | 3 | ||||
-rw-r--r-- | g10/ecdh.c | 2 | ||||
-rw-r--r-- | g10/pkglue.c | 1 | ||||
-rw-r--r-- | g10/pkglue.h | 3 | ||||
-rw-r--r-- | g10/pubkey-enc.c | 41 |
6 files changed, 61 insertions, 6 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index f545b6690..baa293b28 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -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); diff --git a/g10/call-agent.h b/g10/call-agent.h index 45af95422..398d68df4 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -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, diff --git a/g10/ecdh.c b/g10/ecdh.c index eb14154a1..7a0524ffa 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -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]) { diff --git a/g10/pkglue.c b/g10/pkglue.c index 360edc8cb..c9169f85b 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -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; diff --git a/g10/pkglue.h b/g10/pkglue.h index abeddb811..f0d7a0414 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -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 diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 6e1b0898e..605f5c00e 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -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) |