blob: 2fdb4c734357b3f79580049f80a3648df0c35ba2 [file] [log] [blame]
//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#include <stdlib.h>
#include "tss2_sys.h"
#include "sysapi_util.h"
#include "tpmclient.int.h"
#include "../integration/context-util.h"
#include "../integration/sapi-util.h"
#define LOGMODULE testtpmclient
#include "util/log.h"
void RollNonces(SESSION *session, TPM2B_NONCE *newNonce)
{
session->nonceOlder = session->nonceNewer;
session->nonceNewer = *newNonce;
}
static SESSION *sessions = NULL;
SESSION *
get_session(TPMI_SH_AUTH_SESSION hndl)
{
SESSION *s;
HASH_FIND_INT(sessions, &hndl, s);
return s;
}
static TSS2_RC
StartAuthSession(
SESSION *session,
TSS2_TCTI_CONTEXT *tctiContext)
{
TSS2_RC rval;
TPM2B_ENCRYPTED_SECRET key;
char label[] = "ATH";
TSS2_SYS_CONTEXT *tmpSysContext;
UINT16 bytes;
key.size = 0;
tmpSysContext = sapi_init_from_tcti_ctx(tctiContext);
if (tmpSysContext == NULL)
return TSS2_APP_RC_INIT_SYS_CONTEXT_FAILED;
if (session->nonceOlder.size == 0)
session->nonceOlder.size = GetDigestSize(session->authHash);
memset(session->nonceOlder.buffer, '\0', session->nonceOlder.size);
session->nonceNewer.size = session->nonceOlder.size;
session->nonceTpmDecrypt.size = 0;
session->nonceTpmEncrypt.size = 0;
session->nvNameChanged = 0;
rval = Tss2_Sys_StartAuthSession(
tmpSysContext, session->tpmKey, session->bind, 0,
&session->nonceOlder, &session->encryptedSalt,
session->sessionType, &session->symmetric,
session->authHash, &session->sessionHandle,
&session->nonceNewer, 0);
if (rval != TPM2_RC_SUCCESS)
goto out;
if (session->tpmKey == TPM2_RH_NULL)
session->salt.size = 0;
if (session->bind == TPM2_RH_NULL)
session->authValueBind.size = 0;
session->sessionKey.size = 0;
if (session->tpmKey == TPM2_RH_NULL && session->bind == TPM2_RH_NULL)
goto out;
/* Generate the key used as input to the KDF. */
rval = ConcatSizedByteBuffer((TPM2B_MAX_BUFFER *)&key,
(TPM2B *)&session->authValueBind);
if (rval != TPM2_RC_SUCCESS) {
Tss2_Sys_FlushContext(tmpSysContext, session->sessionHandle);
goto out;
}
rval = ConcatSizedByteBuffer((TPM2B_MAX_BUFFER *)&key,
(TPM2B *)&session->salt);
if (rval != TPM2_RC_SUCCESS) {
Tss2_Sys_FlushContext(tmpSysContext, session->sessionHandle);
goto out;
}
bytes = GetDigestSize(session->authHash) * 8;
rval = KDFa(session->authHash, (TPM2B *)&key, label,
(TPM2B *)&session->nonceNewer,
(TPM2B *)&session->nonceOlder,
bytes, (TPM2B_MAX_BUFFER *)&session->sessionKey);
out:
sapi_teardown(tmpSysContext);
return rval;
}
TSS2_RC StartAuthSessionWithParams(
SESSION **psession,
TPMI_DH_OBJECT tpmKey,
TPM2B_MAX_BUFFER *salt,
TPMI_DH_ENTITY bind,
TPM2B_AUTH *bindAuth,
TPM2B_NONCE *nonceCaller,
TPM2B_ENCRYPTED_SECRET *encryptedSalt,
TPM2_SE sessionType,
TPMT_SYM_DEF *symmetric,
TPMI_ALG_HASH algId,
TSS2_TCTI_CONTEXT *tctiContext)
{
TSS2_RC rval;
SESSION *session, *tmp;
if (psession == NULL)
return TSS2_APP_RC_BAD_REFERENCE;
session = calloc(1, sizeof(SESSION));
if (!session)
return TSS2_APP_ERROR(TSS2_BASE_RC_MEMORY);
session->bind = bind;
session->tpmKey = tpmKey;
CopySizedByteBuffer((TPM2B *)&session->nonceOlder, (TPM2B *)nonceCaller);
CopySizedByteBuffer((TPM2B *)&session->encryptedSalt, (TPM2B *)encryptedSalt);
session->sessionType = sessionType;
session->symmetric.algorithm = symmetric->algorithm;
session->symmetric.keyBits.sym = symmetric->keyBits.sym;
session->symmetric.mode.sym = symmetric->mode.sym;
session->authHash = algId;
if (bindAuth != NULL)
CopySizedByteBuffer((TPM2B *)&session->authValueBind, (TPM2B *)bindAuth);
if (session->tpmKey != TPM2_RH_NULL)
CopySizedByteBuffer((TPM2B *)&session->salt, (TPM2B *)salt);
rval = StartAuthSession(session, tctiContext);
if (rval != TSS2_RC_SUCCESS) {
free(session);
return rval;
}
/* Make sure this session handle is not already in the table */
HASH_FIND_INT(sessions, &session->sessionHandle, tmp);
if (tmp)
HASH_DEL(sessions, tmp);
HASH_ADD_INT(sessions, sessionHandle, session);
*psession = session;
return TSS2_RC_SUCCESS;
}
void EndAuthSession(SESSION *session)
{
HASH_DEL(sessions, session);
free(session);
}