/* * Licensed Materials - Property of IBM * * trousers - An open source TCG Software Stack * * (C) Copyright International Business Machines Corp. 2004-2007 * */ #include #include #include #include #include #include #include #include #include #include #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 && auth2) { offset1 = offset2 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN); UnloadBlob_Auth(&offset1, b, auth1); UnloadBlob_Auth(&offset1, b, auth2); } else if (auth2) { 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; } /* XXX optimize these cases by always passing in lengths for blobs, no more "20 byte values" */ TSS_RESULT tpm_rqu_build(TPM_COMMAND_CODE ordinal, UINT64 *outOffset, BYTE *out_blob, ...) { TSS_RESULT result = TSS_SUCCESS; UINT64 blob_size; va_list ap; DBG_ASSERT(ordinal); DBG_ASSERT(outOffset); DBG_ASSERT(out_blob); va_start(ap, out_blob); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); *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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); *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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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_FieldUpgrade: 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 *); va_end(ap); 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 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); *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 *); va_end(ap); *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 *); va_end(ap); *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 *); va_end(ap); *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); va_end(ap); *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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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 *); va_end(ap); 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); va_end(ap); *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: va_end(ap); LogError("Unknown ordinal: 0x%x", ordinal); break; } return result; }