blob: 89e478f81d8fded2a7576df0f9d9ed0932722b98 [file] [log] [blame]
/*
* Licensed Materials - Property of IBM
*
* trousers - An open source TCG Software Stack
*
* (C) Copyright International Business Machines Corp. 2004-2007
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_utils.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsps.h"
#include "tcslog.h"
#define TSS_TPM_RSP_BLOB_AUTH_LEN (sizeof(TPM_NONCE) + sizeof(TPM_DIGEST) + sizeof(TPM_BOOL))
TSS_RESULT
tpm_rsp_parse(TPM_COMMAND_CODE ordinal, BYTE *b, UINT32 len, ...)
{
TSS_RESULT result = TSS_SUCCESS;
UINT64 offset1, offset2;
va_list ap;
DBG_ASSERT(ordinal);
DBG_ASSERT(b);
va_start(ap, len);
switch (ordinal) {
case TPM_ORD_ExecuteTransport:
{
UINT32 *val1 = va_arg(ap, UINT32 *);
UINT32 *val2 = va_arg(ap, UINT32 *);
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (auth1 && auth2) {
offset1 = offset2 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
UnloadBlob_Auth(&offset1, b, auth1);
UnloadBlob_Auth(&offset1, b, auth2);
} else if (auth1) {
offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
} else if (auth2) {
offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth2);
} else
offset2 = len;
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
if (val1)
UnloadBlob_UINT32(&offset1, val1, b);
if (val2)
UnloadBlob_UINT32(&offset1, val2, b);
*len1 = offset2 - offset1;
if (*len1) {
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1);
} else
*blob1 = NULL;
break;
}
#ifdef TSS_BUILD_TICK
/* TPM BLOB: TPM_CURRENT_TICKS, UINT32, BLOB, optional AUTH */
case TPM_ORD_TickStampBlob:
{
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
UINT32 *len2 = va_arg(ap, UINT32 *);
BYTE **blob2 = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!len1 || !blob1 || !len2 || !blob2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
}
offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_CURRENT_TICKS(&offset2, b, NULL);
*len1 = (UINT32)offset2 - offset1;
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1);
UnloadBlob_UINT32(&offset1, len2, b);
if ((*blob2 = malloc(*len2)) == NULL) {
LogError("malloc of %u bytes failed", *len2);
free(*blob1);
*blob1 = NULL;
*len1 = 0;
*len2 = 0;
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len2, b, *blob2);
break;
}
#endif
#ifdef TSS_BUILD_QUOTE
/* TPM BLOB: TPM_PCR_COMPOSITE, UINT32, BLOB, 1 optional AUTH
* return UINT32*, BYTE**, UINT32*, BYTE**, 1 optional AUTH */
case TPM_ORD_Quote:
{
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
UINT32 *len2 = va_arg(ap, UINT32 *);
BYTE **blob2 = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!len1 || !blob1 || !len2 || !blob2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
}
offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_PCR_COMPOSITE(&offset2, b, NULL);
*len1 = offset2 - offset1;
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1);
UnloadBlob_UINT32(&offset1, len2, b);
if ((*blob2 = malloc(*len2)) == NULL) {
LogError("malloc of %u bytes failed", *len2);
free(*blob1);
*blob1 = NULL;
*len1 = 0;
*len2 = 0;
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len2, b, *blob2);
break;
}
#endif
#ifdef TSS_BUILD_TSS12
/* TPM BLOB: TPM_PCR_INFO_SHORT, (UINT32, BLOB,) UINT32, BLOB, 1 optional AUTH */
case TPM_ORD_Quote2:
{
UINT32 *len1 = va_arg(ap, UINT32 *); /* pcrDataSizeOut */
BYTE **blob1 = va_arg(ap, BYTE **); /* pcrDataOut */
TSS_BOOL *addVersion = va_arg(ap, TSS_BOOL *); /* addVersion */
UINT32 *len2 = va_arg(ap, UINT32 *); /* versionInfoSize */
BYTE **blob2 = va_arg(ap, BYTE **); /* versionInfo */
UINT32 *len3 = va_arg(ap, UINT32 *); /* sigSize */
BYTE **blob3 = va_arg(ap, BYTE **); /* sig */
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *); /* privAuth */
va_end(ap);
if (!len1 || !blob1 || !len2 || !blob2 || !len3 || !blob3 || !addVersion) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
}
offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
/* Adjust the offset to take the TPM_PCR_INFO_SHORT size:
* need to allocate this size into blob1
*/
UnloadBlob_PCR_INFO_SHORT(&offset2, b, NULL);
/* Get the size of the TSS_TPM_INFO_SHORT
* and copy it into blob1 */
*len1 = offset2 - offset1;
LogDebugFn("QUOTE2 Core: PCR_INFO_SHORT is %u size", *len1);
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1); /* TPM_PCR_INFO_SHORT */
UnloadBlob_UINT32(&offset1, len2,b); /* versionInfoSize */
LogDebugFn("QUOTE2 Core: versionInfoSize=%u", *len2);
if ((*blob2 = malloc(*len2)) == NULL) {
LogError("malloc of %u bytes failed", *len2);
free(*blob1);
*blob1 = NULL;
*len1 = 0;
*len2 = 0;
*len3 = 0;
*blob3 = NULL;
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len2, b, *blob2);
/* Take the sigSize */
UnloadBlob_UINT32(&offset1, len3, b);
LogDebugFn("QUOTE2 Core: sigSize=%u", *len3);
/* sig */
if ((*blob3 = malloc(*len3)) == NULL) {
LogError("malloc of %u bytes failed", *len3);
free(*blob1);
*blob1 = NULL;
if (*len2 > 0){
free(*blob2);
*blob2 = NULL;
}
*len1 = 0;
*len2 = 0;
*len3 = 0;
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len3, b, *blob3);
break;
}
#endif
/* TPM BLOB: TPM_CERTIFY_INFO, UINT32, BLOB, 2 optional AUTHs
* return UINT32*, BYTE**, UINT32*, BYTE**, 2 optional AUTHs */
case TPM_ORD_CertifyKey:
{
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
UINT32 *len2 = va_arg(ap, UINT32 *);
BYTE **blob2 = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!len1 || !blob1 || !len2 || !blob2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1 && auth2) {
offset1 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
UnloadBlob_Auth(&offset1, b, auth1);
UnloadBlob_Auth(&offset1, b, auth2);
} else if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
} else if (auth2) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth2);
}
offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_CERTIFY_INFO(&offset2, b, NULL);
*len1 = offset2 - offset1;
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1);
UnloadBlob_UINT32(&offset1, len2, b);
if ((*blob2 = malloc(*len2)) == NULL) {
LogError("malloc of %u bytes failed", *len2);
free(*blob1);
*blob1 = NULL;
*len1 = 0;
*len2 = 0;
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len2, b, *blob2);
break;
}
#ifdef TSS_BUILD_AUDIT
/* TPM_BLOB: TPM_COUNTER_VALUE, DIGEST, DIGEST, UINT32, BLOB, optional AUTH
* return: UINT32*, BYTE**, DIGEST*, DIGEST*, UINT32*, BYTE**, optional AUTH */
case TPM_ORD_GetAuditDigestSigned:
{
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
TPM_DIGEST *digest1 = va_arg(ap, TPM_DIGEST *);
TPM_DIGEST *digest2 = va_arg(ap, TPM_DIGEST *);
UINT32 *len2 = va_arg(ap, UINT32 *);
BYTE **blob2 = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!digest1 || !digest2 || !len1 || !blob1 || !len2 || !blob2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_COUNTER_VALUE(&offset2, b, NULL);
*len1 = offset2 - offset1;
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1);
UnloadBlob_DIGEST(&offset1, b, digest1);
UnloadBlob_DIGEST(&offset1, b, digest2);
UnloadBlob_UINT32(&offset1, len2, b);
if ((*blob2 = malloc(*len2)) == NULL) {
LogError("malloc of %u bytes failed", *len2);
free(*blob1);
*blob1 = NULL;
*len1 = 0;
*len2 = 0;
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len2, b, *blob2);
if (auth1)
UnloadBlob_Auth(&offset1, b, auth1);
break;
}
/* TPM_BLOB: TPM_COUNTER_VALUE, DIGEST, BOOL, UINT32, BLOB
* return: DIGEST*, UINT32*, BYTE**, BOOL, UINT32*, BYTE** */
case TPM_ORD_GetAuditDigest:
{
TPM_DIGEST *digest1 = va_arg(ap, TPM_DIGEST *);
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
TSS_BOOL *bool1 = va_arg(ap, TSS_BOOL *);
UINT32 *len2 = va_arg(ap, UINT32 *);
BYTE **blob2 = va_arg(ap, BYTE **);
va_end(ap);
if (!digest1 || !len1 || !blob1 || !len2 || !blob2 || !bool1) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_COUNTER_VALUE(&offset2, b, NULL);
*len1 = offset2 - offset1;
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1);
UnloadBlob_DIGEST(&offset1, b, digest1);
UnloadBlob_BOOL(&offset1, bool1, b);
UnloadBlob_UINT32(&offset1, len2, b);
if ((*blob2 = malloc(*len2)) == NULL) {
LogError("malloc of %u bytes failed", *len2);
free(*blob1);
*blob1 = NULL;
*len1 = 0;
*len2 = 0;
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len2, b, *blob2);
break;
}
#endif
#ifdef TSS_BUILD_COUNTER
/* optional UINT32, TPM_COUNTER_VALUE, optional AUTH */
case TPM_ORD_ReadCounter:
case TPM_ORD_CreateCounter:
case TPM_ORD_IncrementCounter:
{
UINT32 *val1 = va_arg(ap, UINT32 *);
TPM_COUNTER_VALUE *ctr = va_arg(ap, TPM_COUNTER_VALUE *);
TPM_AUTH * auth1 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!ctr) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
if (val1)
UnloadBlob_UINT32(&offset1, val1, b);
UnloadBlob_COUNTER_VALUE(&offset1, b, ctr);
break;
}
#endif
/* TPM BLOB: UINT32, BLOB, UINT32, BLOB, optional AUTH, optional AUTH */
case TPM_ORD_CreateMaintenanceArchive:
case TPM_ORD_CreateMigrationBlob:
case TPM_ORD_Delegate_ReadTable:
case TPM_ORD_CMK_CreateBlob:
{
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
UINT32 *len2 = va_arg(ap, UINT32 *);
BYTE **blob2 = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!len1 || !blob1 || !len2 || !blob2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1 && auth2) {
offset1 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
UnloadBlob_Auth(&offset1, b, auth1);
UnloadBlob_Auth(&offset1, b, auth2);
} else if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
} else if (auth2) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth2);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_UINT32(&offset1, len1, b);
if ((*blob1 = malloc(*len1)) == NULL) {
LogError("malloc of %u bytes failed", *len1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len1, b, *blob1);
UnloadBlob_UINT32(&offset1, len2, b);
if ((*blob2 = malloc(*len2)) == NULL) {
free(*blob1);
LogError("malloc of %u bytes failed", *len2);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *len2, b, *blob2);
break;
}
/* TPM BLOB: BLOB, optional AUTH, AUTH
* return: UINT32 *, BYTE **, optional AUTH, AUTH */
case TPM_ORD_ActivateIdentity:
{
UINT32 *len1 = va_arg(ap, UINT32 *);
BYTE **blob1 = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!len1 || !blob1 || !auth2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1) {
offset1 = offset2 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
UnloadBlob_Auth(&offset1, b, auth1);
UnloadBlob_Auth(&offset1, b, auth2);
} else {
offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth2);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
offset2 -= TSS_TPM_TXBLOB_HDR_LEN;
if ((*blob1 = malloc(offset2)) == NULL) {
LogError("malloc of %zd bytes failed", (size_t)offset2);
return TCSERR(TSS_E_OUTOFMEMORY);
}
*len1 = offset2;
UnloadBlob(&offset1, *len1, b, *blob1);
break;
}
/* TPM BLOB: TPM_KEY, UINT32, BLOB, optional AUTH, AUTH
* return: UINT32 *, BYTE **, UINT32 *, BYTE **, optional AUTH, AUTH */
case TPM_ORD_MakeIdentity:
{
UINT32 *len1, *len2;
BYTE **blob1, **blob2;
TPM_AUTH *auth1, *auth2;
len1 = va_arg(ap, UINT32 *);
blob1 = va_arg(ap, BYTE **);
len2 = va_arg(ap, UINT32 *);
blob2 = va_arg(ap, BYTE **);
auth1 = va_arg(ap, TPM_AUTH *);
auth2 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!len1 || !blob1 || !len2 || !blob2 || !auth2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_TSS_KEY(&offset1, b, NULL);
offset1 -= TSS_TPM_TXBLOB_HDR_LEN;
if ((*blob1 = malloc(offset1)) == NULL) {
LogError("malloc of %zd bytes failed", (size_t)offset1);
return TCSERR(TSS_E_OUTOFMEMORY);
}
*len1 = offset1;
UnloadBlob(&offset2, offset1, b, *blob1);
/* offset2 points to the stuff after the key */
UnloadBlob_UINT32(&offset2, len2, b);
if ((*blob2 = malloc(*len2)) == NULL) {
free(*blob1);
LogError("malloc of %u bytes failed", *len2);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset2, *len2, b, *blob2);
if (auth1)
UnloadBlob_Auth(&offset2, b, auth1);
UnloadBlob_Auth(&offset2, b, auth2);
break;
}
/* 1 TPM_VERSION, 2 UINT32s, 1 optional AUTH */
case TPM_ORD_GetCapabilityOwner:
{
TPM_VERSION *ver1 = va_arg(ap, TPM_VERSION *);
UINT32 *data1 = va_arg(ap, UINT32 *);
UINT32 *data2 = va_arg(ap, UINT32 *);
TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!data1 || !data2 || !ver1) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_VERSION(&offset1, b, ver1);
UnloadBlob_UINT32(&offset1, data1, b);
UnloadBlob_UINT32(&offset1, data2, b);
break;
}
/* TPM BLOB: 1 UINT32, 1 BLOB, 2 optional AUTHs
* return: UINT32 *, BYTE**, 2 optional AUTHs */
case TPM_ORD_Sign:
case TPM_ORD_GetTestResult:
case TPM_ORD_CertifySelfTest:
case TPM_ORD_Unseal:
case TPM_ORD_GetRandom:
case TPM_ORD_DAA_Join:
case TPM_ORD_DAA_Sign:
case TPM_ORD_ChangeAuth:
case TPM_ORD_GetCapability:
case TPM_ORD_LoadMaintenanceArchive:
case TPM_ORD_ConvertMigrationBlob:
case TPM_ORD_NV_ReadValue:
case TPM_ORD_NV_ReadValueAuth:
case TPM_ORD_Delegate_Manage:
case TPM_ORD_Delegate_CreateKeyDelegation:
case TPM_ORD_Delegate_CreateOwnerDelegation:
case TPM_ORD_Delegate_UpdateVerification:
case TPM_ORD_CMK_ConvertMigration:
{
UINT32 *data_len = va_arg(ap, UINT32 *);
BYTE **data = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!data || !data_len) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1 && auth2) {
offset1 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
UnloadBlob_Auth(&offset1, b, auth1);
UnloadBlob_Auth(&offset1, b, auth2);
} else if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
} else if (auth2) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth2);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_UINT32(&offset1, data_len, b);
if ((*data = malloc(*data_len)) == NULL) {
LogError("malloc of %u bytes failed", *data_len);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *data_len, b, *data);
break;
}
/* TPM BLOB: 1 UINT32, 1 BLOB, 1 optional AUTH
* return: UINT32 *, BYTE**, 1 optional AUTH*/
case TPM_ORD_UnBind:
{
UINT32 *data_len = va_arg(ap, UINT32 *);
BYTE **data = va_arg(ap, BYTE **);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!data || !data_len) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth1) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth1);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_UINT32(&offset1, data_len, b);
if ((*data = malloc(*data_len)) == NULL) {
LogError("malloc of %u bytes failed", *data_len);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, *data_len, b, *data);
break;
}
/* TPM BLOB: 1 BLOB, 1 optional AUTH
* return: UINT32 *, BYTE**, 1 optional AUTH*/
case TPM_ORD_GetTicks:
case TPM_ORD_Seal:
case TPM_ORD_Sealx:
case TPM_ORD_FieldUpgrade:
case TPM_ORD_CreateWrapKey:
case TPM_ORD_GetPubKey:
case TPM_ORD_OwnerReadPubek:
case TPM_ORD_OwnerReadInternalPub:
case TPM_ORD_AuthorizeMigrationKey:
case TPM_ORD_TakeOwnership:
case TPM_ORD_CMK_CreateKey:
{
UINT32 *data_len = va_arg(ap, UINT32 *);
BYTE **data = va_arg(ap, BYTE **);
TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!data || !data_len) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
/* remove the auth data from the back end of the data */
if (auth) {
offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth);
} else
offset2 = len;
/* everything after the header is returned as the blob */
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
offset2 -= offset1;
if ((*data = malloc((size_t)offset2)) == NULL) {
LogError("malloc of %zd bytes failed", (size_t)offset2);
return TCSERR(TSS_E_OUTOFMEMORY);
}
if ((offset1 + offset2) > TSS_TPM_TXBLOB_SIZE)
return TCSERR(TSS_E_INTERNAL_ERROR);
memcpy(*data, &b[offset1], offset2);
*data_len = offset2;
break;
}
/* TPM BLOB: TPM_PUBKEY, optional DIGEST */
case TPM_ORD_CreateEndorsementKeyPair:
case TPM_ORD_ReadPubek:
{
UINT32 *data_len = va_arg(ap, UINT32 *);
BYTE **data = va_arg(ap, BYTE **);
BYTE *digest1 = va_arg(ap, BYTE *);
va_end(ap);
if (!data || !data_len) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (digest1) {
offset1 = offset2 = len - TPM_DIGEST_SIZE;
memcpy(digest1, &b[offset2], TPM_DIGEST_SIZE);
if ((offset2 + TPM_DIGEST_SIZE) > TSS_TPM_TXBLOB_SIZE)
return TCSERR(TSS_E_INTERNAL_ERROR);
} else {
offset2 = len;
if (offset2 > TSS_TPM_TXBLOB_SIZE)
return TCSERR(TSS_E_INTERNAL_ERROR);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
offset2 -= offset1;
if ((*data = malloc((size_t)offset2)) == NULL) {
LogError("malloc of %zd bytes failed", (size_t)offset2);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, offset2, b, *data);
*data_len = offset2;
break;
}
#ifdef TSS_BUILD_TSS12
/* TPM BLOB: BLOB, DIGEST, DIGEST
* return: UINT32 *, BYTE**, DIGEST, DIGEST */
case TPM_ORD_CreateRevocableEK:
{
UINT32 *data_len = va_arg(ap, UINT32 *);
BYTE **data = va_arg(ap, BYTE **);
BYTE *digest1 = va_arg(ap, BYTE *);
BYTE *digest2 = va_arg(ap, BYTE *);
va_end(ap);
if (!data || !data_len || !digest1 || !digest2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (len > TSS_TPM_TXBLOB_SIZE)
return TCSERR(TSS_E_INTERNAL_ERROR);
offset2 = len - TPM_DIGEST_SIZE;
memcpy(digest2, &b[offset2], TPM_DIGEST_SIZE);
offset2 -= TPM_DIGEST_SIZE;
memcpy(digest1, &b[offset2], TPM_DIGEST_SIZE);
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
offset2 -= offset1;
if ((*data = malloc((size_t)offset2)) == NULL) {
LogError("malloc of %zd bytes failed", (size_t)offset2);
return TCSERR(TSS_E_OUTOFMEMORY);
}
UnloadBlob(&offset1, offset2, b, *data);
*data_len = offset2;
break;
}
#endif
/* 1 UINT32, 1 optional AUTH */
case TPM_ORD_LoadKey:
case TPM_ORD_LoadKey2:
{
UINT32 *handle;
TPM_AUTH *auth;
handle = va_arg(ap, UINT32 *);
auth = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!handle) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
if (auth) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_UINT32(&offset1, handle, b);
break;
}
/* 1 optional UINT32, 1 20 byte value */
case TPM_ORD_DirRead:
case TPM_ORD_OIAP:
case TPM_ORD_LoadManuMaintPub:
case TPM_ORD_ReadManuMaintPub:
case TPM_ORD_Extend:
case TPM_ORD_PcrRead:
{
UINT32 *handle = va_arg(ap, UINT32 *);
BYTE *nonce = va_arg(ap, BYTE *);
va_end(ap);
if (!nonce) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
if (handle)
UnloadBlob_UINT32(&offset1, handle, b);
UnloadBlob(&offset1, TPM_NONCE_SIZE, b, nonce);
break;
}
/* 1 UINT32, 2 20 byte values */
case TPM_ORD_OSAP:
case TPM_ORD_DSAP:
{
UINT32 *handle = va_arg(ap, UINT32 *);
BYTE *nonce1 = va_arg(ap, BYTE *);
BYTE *nonce2 = va_arg(ap, BYTE *);
va_end(ap);
if (!handle || !nonce1 || !nonce2) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob_UINT32(&offset1, handle, b);
UnloadBlob(&offset1, TPM_NONCE_SIZE, b, nonce1);
UnloadBlob(&offset1, TPM_NONCE_SIZE, b, nonce2);
break;
}
#ifdef TSS_BUILD_CMK
/* 1 20 byte value, 1 optional AUTH */
case TPM_ORD_CMK_ApproveMA:
case TPM_ORD_CMK_CreateTicket:
{
BYTE *hmac1 = va_arg(ap, BYTE *);
TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (!hmac1) {
LogError("Internal error for ordinal 0x%x", ordinal);
return TCSERR(TSS_E_INTERNAL_ERROR);
}
offset1 = TSS_TPM_TXBLOB_HDR_LEN;
UnloadBlob(&offset1, TPM_SHA1_160_HASH_LEN, b, hmac1);
if (auth) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth);
}
break;
}
#endif
/* 1 optional AUTH */
case TPM_ORD_DisablePubekRead:
case TPM_ORD_DirWriteAuth:
case TPM_ORD_ReleaseCounter:
case TPM_ORD_ReleaseCounterOwner:
case TPM_ORD_ChangeAuthOwner:
case TPM_ORD_SetCapability:
case TPM_ORD_SetOrdinalAuditStatus:
case TPM_ORD_ResetLockValue:
case TPM_ORD_SetRedirection:
case TPM_ORD_DisableOwnerClear:
case TPM_ORD_OwnerSetDisable:
case TPM_ORD_SetTempDeactivated:
case TPM_ORD_KillMaintenanceFeature:
case TPM_ORD_NV_DefineSpace:
case TPM_ORD_NV_WriteValue:
case TPM_ORD_NV_WriteValueAuth:
case TPM_ORD_OwnerClear:
case TPM_ORD_Delegate_LoadOwnerDelegation:
case TPM_ORD_CMK_SetRestrictions:
case TPM_ORD_FlushSpecific:
case TPM_ORD_KeyControlOwner:
{
TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
va_end(ap);
if (auth) {
offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
UnloadBlob_Auth(&offset1, b, auth);
}
break;
}
default:
LogError("Unknown ordinal: 0x%x", ordinal);
result = TCSERR(TSS_E_INTERNAL_ERROR);
va_end(ap);
break;
}
return result;
}
TSS_RESULT
tpm_rqu_build(TPM_COMMAND_CODE ordinal, UINT64 *outOffset, BYTE *out_blob, ...)
{
va_list ap;
TSS_RESULT result;
va_start(ap, out_blob);
result = tpm_rqu_build_internal(ordinal, outOffset,out_blob, ap);
va_end(ap);
return result;
}
TSS_RESULT
tpm_rqu_build_checked(TPM_COMMAND_CODE ordinal, UINT64 *outOffset, UINT64 maxOffset, BYTE *out_blob, ...)
{
va_list ap;
TSS_RESULT result;
UINT64 tempOffset = *outOffset;
va_start(ap, out_blob);
result = tpm_rqu_build_internal(ordinal, &tempOffset, NULL, ap);
va_end(ap);
if (result)
{
return result;
}
if (tempOffset > maxOffset)
{
return TCSERR(TSS_E_BAD_PARAMETER);
}
va_start(ap, out_blob);
result = tpm_rqu_build_internal(ordinal, outOffset, out_blob, ap);
va_end(ap);
if (tempOffset != *outOffset)
{
return TCSERR(TSS_E_INTERNAL_ERROR);
}
return result;
}
/* XXX optimize these cases by always passing in lengths for blobs, no more "20 byte values" */
TSS_RESULT
tpm_rqu_build_internal(TPM_COMMAND_CODE ordinal, UINT64 *outOffset, BYTE *out_blob, va_list ap)
{
TSS_RESULT result = TSS_SUCCESS;
UINT64 blob_size;
DBG_ASSERT(ordinal);
DBG_ASSERT(outOffset);
/* |out_blob| could be set to NULL in order to calculate the output size, */
/* so don't make assertion to its value. */
switch (ordinal) {
#ifdef TSS_BUILD_DELEGATION
/* 1 UINT16, 1 UINT32, 1 20 bytes value, 1 UINT32, 1 BLOB */
case TPM_ORD_DSAP:
{
UINT16 val1 = va_arg(ap, int);
UINT32 handle1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
if (!digest1 || !in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT16(outOffset, val1, out_blob);
LoadBlob_UINT32(outOffset, handle1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 1 BOOL, 1 UINT32, 1 BLOB, 1 20 byte value, 1 AUTH */
case TPM_ORD_Delegate_CreateOwnerDelegation:
{
TSS_BOOL bool1 = va_arg(ap, int);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
BYTE *digest1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!in_len1 || !in_blob1 || !digest1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_BOOL(outOffset, bool1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 2 UINT32's, 1 BLOB, 1 20 byte value, 1 AUTH */
case TPM_ORD_Delegate_CreateKeyDelegation:
{
UINT32 keyslot1 = va_arg(ap, UINT32);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
BYTE *digest1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!keyslot1 || !in_len1 || !in_blob1 || !digest1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keyslot1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
#ifdef TSS_BUILD_TRANSPORT
/* 3 UINT32's, 1 BLOB, 2 AUTHs */
case TPM_ORD_ExecuteTransport:
{
UINT32 ord1 = va_arg(ap, UINT32);
UINT32 *keyslot1 = va_arg(ap, UINT32 *);
UINT32 *keyslot2 = va_arg(ap, UINT32 *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
if (keyslot1)
LoadBlob_UINT32(outOffset, *keyslot1, out_blob);
if (keyslot2)
LoadBlob_UINT32(outOffset, *keyslot2, out_blob);
//LoadBlob_UINT32(outOffset, in_len1, out_blob);
if (in_blob1)
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1 && auth2) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ord1, out_blob);
} else if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ord1, out_blob);
} else if (auth2) {
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ord1, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ord1, out_blob);
}
break;
}
#endif
/* 1 UINT32, 1 UINT16, 1 BLOB, 1 UINT32, 1 BLOB, 1 options AUTH, 1 AUTH */
case TPM_ORD_CreateMigrationBlob:
{
UINT32 keyslot1 = va_arg(ap, UINT32);
UINT16 type1 = va_arg(ap, int);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
if (!in_blob1 || !in_blob2 || !auth2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keyslot1, out_blob);
LoadBlob_UINT16(outOffset, type1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 UINT32, 1 UINT16, 1 20 byte value, 1 UINT16, 1 UINT32, 1 BLOB, 2 AUTHs */
case TPM_ORD_ChangeAuth:
{
UINT32 keyslot1 = va_arg(ap, UINT32);
UINT16 proto1 = va_arg(ap, int);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT16 entity1 = va_arg(ap, int);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
if (!digest1 || !in_blob1 || !auth1 || !auth2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keyslot1, out_blob);
LoadBlob_UINT16(outOffset, proto1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_UINT16(outOffset, entity1, out_blob);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 2 DIGEST/ENCAUTH's, 1 UINT32, 1 BLOB, 1 optional AUTH, 1 AUTH */
case TPM_ORD_MakeIdentity:
{
BYTE *dig1, *dig2, *blob1;
UINT32 len1;
TPM_AUTH *auth1, *auth2;
dig1 = va_arg(ap, BYTE *);
dig2 = va_arg(ap, BYTE *);
len1 = va_arg(ap, UINT32);
blob1 = va_arg(ap, BYTE *);
auth1 = va_arg(ap, TPM_AUTH *);
auth2 = va_arg(ap, TPM_AUTH *);
if (!dig1 || !dig2 || !blob1 || !auth2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, dig1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, dig2);
LoadBlob(outOffset, len1, out_blob, blob1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
#if (TSS_BUILD_NV || TSS_BUILD_DELEGATION)
/* 3 UINT32's, 1 BLOB, 1 optional AUTH */
case TPM_ORD_NV_WriteValue:
case TPM_ORD_NV_WriteValueAuth:
case TPM_ORD_Delegate_Manage:
{
UINT32 i = va_arg(ap, UINT32);
UINT32 j = va_arg(ap, UINT32);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, i, out_blob);
LoadBlob_UINT32(outOffset, j, out_blob);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
#endif
/* 3 UINT32's, 1 optional AUTH */
case TPM_ORD_NV_ReadValue:
case TPM_ORD_NV_ReadValueAuth:
case TPM_ORD_SetRedirection:
{
UINT32 i = va_arg(ap, UINT32);
UINT32 j = va_arg(ap, UINT32);
UINT32 k = va_arg(ap, UINT32);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, i, out_blob);
LoadBlob_UINT32(outOffset, j, out_blob);
LoadBlob_UINT32(outOffset, k, out_blob);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 20 byte value, 1 UINT32, 1 BLOB */
case TPM_ORD_CreateEndorsementKeyPair:
{
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
if (!digest1 || !in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#ifdef TSS_BUILD_TSS12
/* 1 20 byte value, 1 UINT32, 1 BLOB, 1 BOOL, 1 20 byte value */
case TPM_ORD_CreateRevocableEK:
{
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TSS_BOOL in_bool1 = va_arg(ap, int);
BYTE *digest2 = va_arg(ap, BYTE *);
if (!digest1 || !in_blob1 || !digest2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_BOOL(outOffset, in_bool1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 1 20 byte value */
case TPM_ORD_RevokeTrust:
{
BYTE *digest1 = va_arg(ap, BYTE *);
if (!digest1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
#ifdef TSS_BUILD_COUNTER
/* 1 20 byte value, 1 UINT32, 1 BLOB, 1 AUTH */
case TPM_ORD_CreateCounter:
{
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!digest1 || !in_blob1 || !auth1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
#ifdef TSS_BUILD_DAA
/* 1 UINT32, 1 BYTE, 1 UINT32, 1 BLOB, 1 UINT32, 1 BLOB, 1 AUTH */
case TPM_ORD_DAA_Sign:
case TPM_ORD_DAA_Join:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
BYTE stage1 = va_arg(ap, int);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !in_blob1 || !auth1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob_BOOL(outOffset, stage1, out_blob);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
/* 2 UINT32's, 1 BLOB, 1 UINT32, 1 BLOB, 1 optional AUTH */
case TPM_ORD_ConvertMigrationBlob:
case TPM_ORD_SetCapability:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !in_blob1 || !in_blob2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 2 UINT32's, 1 20 byte value, 2 optional AUTHs */
case TPM_ORD_CertifyKey:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
UINT32 keySlot2 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !keySlot2 || !digest1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob_UINT32(outOffset, keySlot2, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
if (auth1 && auth2) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
} else if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else if (auth2) {
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 2 UINT32's, 1 BLOB, 1 optional AUTH */
case TPM_ORD_Delegate_LoadOwnerDelegation:
case TPM_ORD_GetCapability:
case TPM_ORD_UnBind:
case TPM_ORD_Sign:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (in_len1 && !in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
if (in_len1)
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 UINT32, 1 20 byte value, 1 UINT32, 1 optional BLOB, 1 UINT32, 1 BLOB, 1 AUTH */
case TPM_ORD_Seal:
case TPM_ORD_Sealx:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
blob_size = in_len1 + in_len2 + TPM_DIGEST_SIZE + sizeof(TPM_AUTH);
if (blob_size > TSS_TPM_TXBLOB_SIZE) {
result = TCSERR(TSS_E_BAD_PARAMETER);
LogError("Oversized input when building ordinal 0x%x", ordinal);
break;
}
if (!keySlot1 || !in_blob2 || !auth1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 2 UINT32's, 1 BLOB, 1 optional AUTH, 1 AUTH */
case TPM_ORD_ActivateIdentity:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !in_blob1 || !auth2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 UINT32, 1 20-byte blob, 1 BLOB, 1 optional AUTH */
case TPM_ORD_Quote:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !digest1 || !in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#ifdef TSS_BUILD_TSS12
/* 1 UINT32, 1 20-byte blob, 1 BLOB, 1 BOOL, 1 optional AUTH */
case TPM_ORD_Quote2:
{
/* Input vars */
UINT32 keySlot1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TSS_BOOL* addVersion = va_arg(ap,TSS_BOOL *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !digest1 || !in_blob1 || !addVersion) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
/* Load the addVersion Bool */
LoadBlob_BOOL(outOffset,*addVersion,out_blob);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
/* 1 UINT32, 2 20-byte blobs, 1 BLOB, 1 optional AUTH */
case TPM_ORD_CreateWrapKey:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
BYTE *digest2 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !digest1 || !digest2 || !in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 2 BLOBs, 1 optional AUTH */
case TPM_ORD_NV_DefineSpace:
case TPM_ORD_LoadManuMaintPub:
{
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!in_blob1 || !in_blob2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
#ifdef TSS_BUILD_TICK
/* 1 UINT32, 2 20-byte blobs, 1 optional AUTH */
case TPM_ORD_TickStampBlob:
{
UINT32 keySlot1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
BYTE *digest2 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!keySlot1 || !digest1 || !digest2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keySlot1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
/* 1 BLOB */
case TPM_ORD_ReadManuMaintPub:
case TPM_ORD_ReadPubek:
case TPM_ORD_PCR_Reset:
case TPM_ORD_SetOperatorAuth:
{
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
if (!in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 1 UINT32, 1 BLOB, 2 optional AUTHs */
case TPM_ORD_LoadKey:
case TPM_ORD_LoadKey2:
case TPM_ORD_DirWriteAuth:
case TPM_ORD_CertifySelfTest:
case TPM_ORD_Unseal:
case TPM_ORD_Extend:
case TPM_ORD_StirRandom:
case TPM_ORD_LoadMaintenanceArchive: /* XXX */
case TPM_ORD_Delegate_UpdateVerification:
case TPM_ORD_Delegate_VerifyDelegation:
{
UINT32 val1 = va_arg(ap, UINT32);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
if (in_len1 && !in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, val1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1 && auth2) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
} else if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else if (auth2) {
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 BLOB, 2 optional AUTHs */
case TPM_ORD_FieldUpgrade:
{
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
if (in_len1 && !in_blob1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
if (auth1 && auth2) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
} else if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else if (auth2) {
LoadBlob_Auth(outOffset, out_blob, auth2);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 UINT16, 1 BLOB, 1 AUTH */
case TPM_ORD_AuthorizeMigrationKey:
{
UINT16 scheme1 = va_arg(ap, int);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!in_blob1 || !auth1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT16(outOffset, scheme1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 1 UINT16, 1 UINT32, 1 BLOB, 1 UINT32, 2 BLOBs, 1 AUTH */
case TPM_ORD_TakeOwnership:
{
UINT16 scheme1 = va_arg(ap, int);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
UINT32 in_len3 = va_arg(ap, UINT32);
BYTE *in_blob3 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!in_blob1 || !in_blob2 || !in_blob3 || !auth1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT16(outOffset, scheme1, out_blob);
LoadBlob_UINT32(outOffset, in_len1, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
LoadBlob(outOffset, in_len3, out_blob, in_blob3);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#ifdef TSS_BUILD_AUDIT
/* 1 UINT32, 1 BOOL, 1 20 byte value, 1 optional AUTH */
case TPM_ORD_GetAuditDigestSigned:
{
UINT32 keyslot1 = va_arg(ap, UINT32);
TSS_BOOL bool1 = va_arg(ap, int);
BYTE *digest1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!digest1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, keyslot1, out_blob);
LoadBlob_BOOL(outOffset, bool1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
#endif
/* 1 UINT16, 1 UINT32, 1 20 byte value */
case TPM_ORD_OSAP:
{
UINT16 type1 = va_arg(ap, int);
UINT32 value1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
if (!digest1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT16(outOffset, type1, out_blob);
LoadBlob_UINT32(outOffset, value1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 1 UINT16, 1 20 byte value, 1 UINT16, 1 AUTH */
case TPM_ORD_ChangeAuthOwner:
{
UINT16 type1 = va_arg(ap, int);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT16 type2 = va_arg(ap, int);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!digest1 || !auth1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT16(outOffset, type1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_UINT16(outOffset, type2, out_blob);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#ifdef TSS_BUILD_AUDIT
/* 1 UINT32, 1 BOOL, 1 AUTH */
case TPM_ORD_SetOrdinalAuditStatus:
{
UINT32 ord1 = va_arg(ap, UINT32);
TSS_BOOL bool1 = va_arg(ap, int);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!auth1) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, ord1, out_blob);
LoadBlob_BOOL(outOffset, bool1, out_blob);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
/* 1 BOOL, 1 optional AUTH */
case TPM_ORD_OwnerSetDisable:
case TPM_ORD_PhysicalSetDeactivated:
case TPM_ORD_CreateMaintenanceArchive:
case TPM_ORD_SetOwnerInstall:
{
TSS_BOOL bool1 = va_arg(ap, int);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_BOOL(outOffset, bool1, out_blob);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 optional AUTH */
case TPM_ORD_OwnerClear:
case TPM_ORD_DisablePubekRead:
case TPM_ORD_GetCapabilityOwner:
case TPM_ORD_ResetLockValue:
case TPM_ORD_DisableOwnerClear:
case TPM_ORD_SetTempDeactivated:
case TPM_ORD_OIAP:
case TPM_ORD_OwnerReadPubek:
case TPM_ORD_SelfTestFull:
case TPM_ORD_GetTicks:
case TPM_ORD_GetTestResult:
case TPM_ORD_KillMaintenanceFeature:
case TPM_ORD_Delegate_ReadTable:
case TPM_ORD_PhysicalEnable:
case TPM_ORD_DisableForceClear:
case TPM_ORD_ForceClear:
{
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 UINT32, 1 optional AUTH */
case TPM_ORD_OwnerReadInternalPub:
case TPM_ORD_GetPubKey:
case TPM_ORD_ReleaseCounterOwner:
case TPM_ORD_ReleaseCounter:
case TPM_ORD_IncrementCounter:
case TPM_ORD_PcrRead:
case TPM_ORD_DirRead:
case TPM_ORD_ReadCounter:
case TPM_ORD_Terminate_Handle:
case TPM_ORD_GetAuditDigest:
case TPM_ORD_GetRandom:
case TPM_ORD_CMK_SetRestrictions:
{
UINT32 i = va_arg(ap, UINT32);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, i, out_blob);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
#ifdef TSS_BUILD_CMK
/* 1 20 byte value, 1 optional AUTH */
case TPM_ORD_CMK_ApproveMA:
{
BYTE *digest1 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
#endif
/* 1 UINT16 only */
case TSC_ORD_PhysicalPresence:
{
UINT16 i = va_arg(ap, int);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT16(outOffset, i, out_blob);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#ifdef TSS_BUILD_CMK
/* 1 UINT32, 1 20 byte value, 1 BLOB, 2 20 byte values, 1 optional AUTH */
case TPM_ORD_CMK_CreateKey:
{
UINT32 key1 = va_arg(ap, UINT32);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
BYTE *digest2 = va_arg(ap, BYTE *);
BYTE *digest3 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!digest1 || !in_blob1 || !digest2 || !digest3) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, key1, out_blob);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest3);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 BLOB, 1 20 byte value, 1 UINT32, 1 BLOB, 1 optional AUTH */
case TPM_ORD_CMK_CreateTicket:
{
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!digest1 || !in_blob1 || !in_blob2) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 UINT32, 1 UINT16, 1 BLOB, 1 20 byte value, 4 x (1 UINT32, 1 BLOB), 1 optional AUTH */
case TPM_ORD_CMK_CreateBlob:
{
UINT32 in_key1 = va_arg(ap, UINT32);
UINT16 i = va_arg(ap, int);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
UINT32 in_len3 = va_arg(ap, UINT32);
BYTE *in_blob3 = va_arg(ap, BYTE *);
UINT32 in_len4 = va_arg(ap, UINT32);
BYTE *in_blob4 = va_arg(ap, BYTE *);
UINT32 in_len5 = va_arg(ap, UINT32);
BYTE *in_blob5 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!digest1 || !in_blob1 || !in_blob2 || !in_blob3 || !in_blob4 || !in_blob5) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, in_key1, out_blob);
LoadBlob_UINT16(outOffset, i, out_blob);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
LoadBlob_UINT32(outOffset, in_len3, out_blob);
LoadBlob(outOffset, in_len3, out_blob, in_blob3);
LoadBlob_UINT32(outOffset, in_len4, out_blob);
LoadBlob(outOffset, in_len4, out_blob, in_blob4);
LoadBlob_UINT32(outOffset, in_len5, out_blob);
LoadBlob(outOffset, in_len5, out_blob, in_blob5);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
/* 1 UINT32, 1 60 byte value, 1 20 byte value, 1 BLOB, 2 x (1 UINT32, 1 BLOB),
* 1 optional AUTH */
case TPM_ORD_CMK_ConvertMigration:
{
UINT32 key1 = va_arg(ap, UINT32);
BYTE *cmkauth1 = va_arg(ap, BYTE *);
BYTE *digest1 = va_arg(ap, BYTE *);
UINT32 in_len1 = va_arg(ap, UINT32);
BYTE *in_blob1 = va_arg(ap, BYTE *);
UINT32 in_len2 = va_arg(ap, UINT32);
BYTE *in_blob2 = va_arg(ap, BYTE *);
UINT32 in_len3 = va_arg(ap, UINT32);
BYTE *in_blob3 = va_arg(ap, BYTE *);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
if (!cmkauth1 || !digest1 || !in_blob1 || !in_blob2 || !in_blob3) {
result = TCSERR(TSS_E_INTERNAL_ERROR);
LogError("Internal error for ordinal 0x%x", ordinal);
break;
}
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, key1, out_blob);
LoadBlob(outOffset, 3 * TPM_SHA1_160_HASH_LEN, out_blob, cmkauth1);
LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
LoadBlob(outOffset, in_len1, out_blob, in_blob1);
LoadBlob_UINT32(outOffset, in_len2, out_blob);
LoadBlob(outOffset, in_len2, out_blob, in_blob2);
LoadBlob_UINT32(outOffset, in_len3, out_blob);
LoadBlob(outOffset, in_len3, out_blob, in_blob3);
if (auth1) {
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
} else {
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
}
break;
}
#endif
#ifdef TSS_BUILD_TSS12
case TPM_ORD_FlushSpecific:
{
UINT32 val1 = va_arg(ap, UINT32);
UINT32 val2 = va_arg(ap, UINT32);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, val1, out_blob);
LoadBlob_UINT32(outOffset, val2, out_blob);
LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
break;
}
/* 1 UINT32, 1 BLOB, 1 UINT32, 1 BOOL, 1 AUTH */
case TPM_ORD_KeyControlOwner:
{
UINT32 i = va_arg(ap, UINT32);
UINT32 len1 = va_arg(ap, UINT32);
BYTE *blob1 = va_arg(ap, BYTE *);
UINT32 j = va_arg(ap, UINT32);
TSS_BOOL bool1 = va_arg(ap, int);
TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
va_end(ap);
*outOffset += TSS_TPM_TXBLOB_HDR_LEN;
LoadBlob_UINT32(outOffset, i, out_blob);
LoadBlob(outOffset, len1, out_blob, blob1);
LoadBlob_UINT32(outOffset, j, out_blob);
LoadBlob_BOOL(outOffset, bool1, out_blob);
LoadBlob_Auth(outOffset, out_blob, auth1);
LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
break;
}
#endif
default:
LogError("Unknown ordinal: 0x%x", ordinal);
break;
}
return result;
}