summaryrefslogtreecommitdiffstats
path: root/sm/decrypt.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-05-07 08:03:26 +0200
committerWerner Koch <wk@gnupg.org>2020-05-07 08:03:26 +0200
commitee6d29f1797e06977ae3d2edae9edc1165c6f144 (patch)
treeb43cd2216fcd1b0b2929bb946edb9e78f104f459 /sm/decrypt.c
parentscd: Extend an internal function to also return the algo. (diff)
downloadgnupg2-ee6d29f1797e06977ae3d2edae9edc1165c6f144.tar.xz
gnupg2-ee6d29f1797e06977ae3d2edae9edc1165c6f144.zip
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 <wk@gnupg.org>
Diffstat (limited to 'sm/decrypt.c')
-rw-r--r--sm/decrypt.c19
1 files 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)