From ee6d29f1797e06977ae3d2edae9edc1165c6f144 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 May 2020 08:03:26 +0200 Subject: [PATCH] sm: Support decryption of ECDH data using a smartcard. * sm/decrypt.c (ecdh_decrypt): Add arg nbits and detect bare secret. (prepare_decryption): Add arg nbits and pass on. (gpgsm_decrypt): Pass size of curve to prepare_decryption. -- GnuPG-bug-id: 4098 Signed-off-by: Werner Koch --- sm/decrypt.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sm/decrypt.c b/sm/decrypt.c index f9dc0376e..d64c6091b 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -135,10 +135,11 @@ hash_ecc_cms_shared_info (gcry_md_hd_t hash_hd, const char *wrap_algo_str, } -/* This function will modify SECRET. */ +/* This function will modify SECRET. NBITS is the size of the curve + * which which we took from the certificate. */ static gpg_error_t ecdh_decrypt (unsigned char *secret, size_t secretlen, - gcry_sexp_t enc_val, + unsigned int nbits, gcry_sexp_t enc_val, unsigned char **r_result, unsigned int *r_resultlen) { gpg_error_t err; @@ -159,8 +160,8 @@ ecdh_decrypt (unsigned char *secret, size_t secretlen, *r_resultlen = 0; *r_result = NULL; - /* Extract X from SECRET; this is the actual secret. It must be in - * the format of: + /* Extract X from SECRET; this is the actual secret. Unless a + * smartcard diretcly returns X, it must be in the format of: * * 04 || X || Y * 40 || X @@ -168,7 +169,9 @@ ecdh_decrypt (unsigned char *secret, size_t secretlen, */ if (secretlen < 2) return gpg_error (GPG_ERR_BAD_DATA); - if (*secret == 0x04) + if (secretlen == (nbits+7)/8) + ; /* Matches curve length - this is already the X coordinate. */ + else if (*secret == 0x04) { secretlen--; memmove (secret, secret+1, secretlen); @@ -367,7 +370,7 @@ ecdh_decrypt (unsigned char *secret, size_t secretlen, algo and the IV is expected to be already in PARM. */ static int prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, - int pk_algo, const char *desc, + int pk_algo, unsigned int nbits, const char *desc, ksba_const_sexp_t enc_val, struct decrypt_filter_parm_s *parm) { @@ -400,7 +403,7 @@ prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, if (rc) goto leave; - rc = ecdh_decrypt (seskey, seskeylen, s_enc_val, + rc = ecdh_decrypt (seskey, seskeylen, nbits, s_enc_val, &decrypted, &decryptedlen); gcry_sexp_release (s_enc_val); if (rc) @@ -859,7 +862,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) recp); else { - rc = prepare_decryption (ctrl, hexkeygrip, pk_algo, + rc = prepare_decryption (ctrl, hexkeygrip, pk_algo, nbits, desc, enc_val, &dfparm); xfree (enc_val); if (rc)