Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Support TPM2 auth
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
  • Loading branch information
dwmw2 committed Oct 8, 2018
1 parent b7b29a5 commit 0173d30
Showing 1 changed file with 84 additions and 25 deletions.
109 changes: 84 additions & 25 deletions gnutls_tpm2_esys.c
Expand Up @@ -43,10 +43,12 @@
#include <tss2/tss2_esys.h>

struct oc_tpm2_ctx {
TPM2B_DIGEST userauth;
TPM2B_PUBLIC pub;
TPM2B_PRIVATE priv;
TPM2B_DIGEST userauth;
TPM2B_DIGEST ownerauth;
unsigned int need_userauth:1;
unsigned int need_ownerauth:1;
};

static TPM2B_PUBLIC primaryTemplate = {
Expand Down Expand Up @@ -111,8 +113,8 @@ static TPML_PCR_SELECTION allCreationPCR = {
* @retval TSS2_RC_SUCCESS on success
* @retval TSS2_RCs according to the error
*/
static TSS2_RC init_tpm2_primary(struct openconnect_info *vpninfo,
ESYS_CONTEXT **ctx, ESYS_TR *primaryHandle)
static int init_tpm2_primary(struct openconnect_info *vpninfo,
ESYS_CONTEXT **ctx, ESYS_TR *primaryHandle)
{
TSS2_RC r;
*primaryHandle = ESYS_TR_NONE;
Expand Down Expand Up @@ -140,7 +142,26 @@ static TSS2_RC init_tpm2_primary(struct openconnect_info *vpninfo,
}

vpn_progress(vpninfo, PRG_DEBUG, _("Creating primary key under owner.\n"));
reauth:
if (vpninfo->tpm2->need_ownerauth) {
char *pass = NULL;
int err = request_passphrase(vpninfo, "openconnect_tpm2_owner",
&pass, _("Enter TPM2 owner password:"));
if (err)
goto error;

if (strlen(pass) > sizeof(vpninfo->tpm2->ownerauth.buffer) - 1) {
vpn_progress(vpninfo, PRG_ERR,
_("TPM2 owner password too long; truncating\n"));
pass[sizeof(vpninfo->tpm2->ownerauth.buffer) - 1] = 0;
}
vpninfo->tpm2->ownerauth.size = strlen(pass);
strcpy((char *)vpninfo->tpm2->ownerauth.buffer, pass);
memset(pass, 0, strlen(pass));
free(pass);

vpninfo->tpm2->need_ownerauth = 0;
}
r = Esys_TR_SetAuth(*ctx, ESYS_TR_RH_OWNER, &vpninfo->tpm2->ownerauth);
if (r) {
vpn_progress(vpninfo, PRG_ERR,
Expand All @@ -157,23 +178,23 @@ static TSS2_RC init_tpm2_primary(struct openconnect_info *vpninfo,
if (r == 0x000009a2) {
vpn_progress(vpninfo, PRG_DEBUG,
_("TPM2 Esys_CreatePrimary owner auth failed\n"));
/* XXX: Prompt and retry */
goto error;
vpninfo->tpm2->need_ownerauth = 1;
goto reauth;
} else if (r) {
vpn_progress(vpninfo, PRG_ERR,
_("TPM2 Esys_CreatePrimary failed: 0x%x\n"),
r);
goto error;
}

return TSS2_RC_SUCCESS;
return 0;
error:
if (*primaryHandle != ESYS_TR_NONE)
Esys_FlushContext(*ctx, *primaryHandle);
*primaryHandle = ESYS_TR_NONE;

Esys_Finalize(ctx);
return r;
return -EIO;
}

/** Initialize the ESYS TPM connection and load the key
Expand All @@ -187,15 +208,14 @@ static TSS2_RC init_tpm2_primary(struct openconnect_info *vpninfo,
* @retval TSS2_RC_SUCCESS on success
* @retval TSS2_RCs according to the error
*/
static TSS2_RC init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
struct openconnect_info *vpninfo)
static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
struct openconnect_info *vpninfo)
{
TSS2_RC r;
ESYS_TR primaryHandle = ESYS_TR_NONE;
*keyHandle = ESYS_TR_NONE;

r = init_tpm2_primary(vpninfo, ctx, &primaryHandle);
if (r)
if (init_tpm2_primary(vpninfo, ctx, &primaryHandle))
goto error;

vpn_progress(vpninfo, PRG_DEBUG, _("Loading TPM2 key blob.\n"));
Expand All @@ -220,15 +240,7 @@ static TSS2_RC init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
}
primaryHandle = ESYS_TR_NONE;

r = Esys_TR_SetAuth(*ctx, *keyHandle, &vpninfo->tpm2->userauth);
if (r) {
vpn_progress(vpninfo, PRG_ERR,
_("TPM2 Esys_TR_SetAuth failed: 0x%x\n"),
r);
goto error;
}

return TSS2_RC_SUCCESS;
return 0;
error:
if (primaryHandle != ESYS_TR_NONE)
Esys_FlushContext(*ctx, primaryHandle);
Expand All @@ -237,7 +249,46 @@ static TSS2_RC init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
*keyHandle = ESYS_TR_NONE;

Esys_Finalize(ctx);
return r;
return -EIO;
}

static int auth_tpm2_key(struct openconnect_info *vpninfo, ESYS_CONTEXT *ctx, ESYS_TR key_handle)
{
TSS2_RC r;

if (vpninfo->tpm2->need_userauth || vpninfo->cert_password) {
char *pass = NULL;

if (vpninfo->cert_password) {
pass = vpninfo->cert_password;
vpninfo->cert_password = NULL;
} else {
int err = request_passphrase(vpninfo, "openconnect_tpm2_key",
&pass, _("Enter TPM2 key password:"));
if (err)
return err;
}
if (strlen(pass) > sizeof(vpninfo->tpm2->userauth.buffer) - 1) {
vpn_progress(vpninfo, PRG_ERR,
_("TPM2 key password too long; truncating\n"));
pass[sizeof(vpninfo->tpm2->userauth.buffer) - 1] = 0;
}
vpninfo->tpm2->userauth.size = strlen(pass);
strcpy((char *)vpninfo->tpm2->userauth.buffer, pass);
memset(pass, 0, strlen(pass));
free(pass);

vpninfo->tpm2->need_userauth = 0;
}

r = Esys_TR_SetAuth(ctx, key_handle, &vpninfo->tpm2->userauth);
if (r) {
vpn_progress(vpninfo, PRG_ERR,
_("TPM2 Esys_TR_SetAuth failed: 0x%x\n"),
r);
return -EIO;
}
return 0;
}

#define PKCS1_PAD_OVERHEAD 11
Expand Down Expand Up @@ -277,18 +328,26 @@ static int tpm2_rsa_sign_fn(gnutls_privkey_t key, void *_vpninfo,

if (init_tpm2_key(&ectx, &key_handle, vpninfo))
goto out;
reauth:
if (auth_tpm2_key(vpninfo, ectx, key_handle))
goto out;

r = Esys_RSA_Decrypt(ectx, key_handle,
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
&digest, &inScheme, &label, &tsig);
if (r == 0x9a2) {
vpn_progress(vpninfo, PRG_DEBUG,
_("TPM2 Esys_RSA_Decrypt auth failed\n"));
vpninfo->tpm2->need_userauth = 1;
goto reauth;
}
if (r) {
vpn_progress(vpninfo, PRG_ERR,
_("TPM2 failed to generate RSA signature: %d\n"),
_("TPM2 failed to generate RSA signature: 0x%x\n"),
r);
goto out;
}


sig->data = malloc(tsig->size);
if (!sig->data)
goto out;
Expand Down Expand Up @@ -337,7 +396,7 @@ int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, g
&vpninfo->tpm2->priv);
if (r) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to import RPM2 private key data: %d\n"),
_("Failed to import TPM2 private key data: 0x%x\n"),
r);
err_out:
release_tpm2_ctx(vpninfo);
Expand All @@ -348,7 +407,7 @@ int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, g
&vpninfo->tpm2->pub);
if (r) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to import RPM2 private key data: %d\n"),
_("Failed to import TPM2 private key data: 0x%x\n"),
r);
goto err_out;
}
Expand Down

0 comments on commit 0173d30

Please sign in to comment.