diff options
-rw-r--r-- | agent/agent.h | 13 | ||||
-rw-r--r-- | agent/divert-tpm2.c | 31 | ||||
-rw-r--r-- | agent/pkdecrypt.c | 9 |
3 files changed, 51 insertions, 2 deletions
diff --git a/agent/agent.h b/agent/agent.h index 5d426f6b8..e891981b2 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -655,6 +655,9 @@ int divert_tpm2_pkdecrypt (ctrl_t ctrl, char **r_buf, size_t *r_len, int *r_padding); int divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, gcry_sexp_t s_skey); +int agent_tpm2d_ecc_kem (ctrl_t ctrl, const unsigned char *shadow_info, + const unsigned char *ecc_ct, + size_t ecc_point_len, unsigned char *ecc_ecdh); #else /*!HAVE_LIBTSS*/ static inline int divert_tpm2_pksign (ctrl_t ctrl, @@ -686,6 +689,16 @@ divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, (void)ctrl; (void)grip; (void)s_skey; return gpg_error (GPG_ERR_NOT_SUPPORTED); } + +static inline int +agent_tpm2d_ecc_kem (ctrl_t ctrl, const unsigned char *shadow_info, + const unsigned char *ecc_ct, + size_t ecc_point_len, unsigned char *ecc_ecdh) +{ + (void)ctrl; (void)ecc_ct; + (void)ecc_point_len; (void)ecc_ecdh; + return gpg_error (GPG_ERR_NOT_SUPPORTED); +} #endif /*!HAVE_LIBTSS*/ diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index 5779ee974..b9e8784bd 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -168,3 +168,34 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl, return agent_tpm2d_pkdecrypt (ctrl, s, n, shadow_info, r_buf, r_len); } + +int +agent_tpm2d_ecc_kem (ctrl_t ctrl, + const unsigned char *shadow_info, + const unsigned char *ecc_ct, + size_t ecc_point_len, unsigned char *ecc_ecdh) +{ + char *ecdh = NULL; + size_t len; + int rc; + + rc = agent_tpm2d_pkdecrypt (ctrl, ecc_ct, ecc_point_len, shadow_info, + &ecdh, &len); + if (rc) + return rc; + + if (len == ecc_point_len) + memcpy (ecc_ecdh, ecdh, len); + else if (len == ecc_point_len + 1 && ecdh[0] == 0x40) /* The prefix */ + memcpy (ecc_ecdh, ecdh + 1, len - 1); + else + { + if (opt.verbose) + log_info ("%s: ECC result length invalid (%zu != %zu)\n", + __func__, len, ecc_point_len); + return gpg_error (GPG_ERR_INV_DATA); + } + + xfree (ecdh); + return rc; +} diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 6fe69e20f..90d84ee3f 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -503,8 +503,13 @@ ecc_pgp_kem_decap (ctrl_t ctrl, gcry_sexp_t s_skey0, { if (s_skey0 && agent_is_tpm2_key (s_skey0)) { - log_error ("TPM decryption failed: %s\n", gpg_strerror (err)); - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + err = agent_tpm2d_ecc_kem (ctrl, shadow_info0, + ecc_ct, ecc->point_len, ecc_ecdh); + if (err) + { + log_error ("TPM decryption failed: %s\n", gpg_strerror (err)); + return err; + } } else { |