// =================================================================== // // Copyright (c) 2005, Intel Corp. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Intel Corporation nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. // =================================================================== // // vtsp.c // // Higher level interface to TCS for use in service. // // ================================================================== #include #include "tcg.h" #include "tcs.h" #include "bsg.h" #include "log.h" #include "crypto.h" #include "vtsp.h" #include "buffer.h" #define RSA_KEY_SIZE 0x0800 /*********************************************************************************** * GenerateAuth: Generate authorization info to be sent back to application * * Parameters: outParamDigestText The concatenation of output parameters to be SHA1ed * outParamDigestTextSize Size of inParamDigestText * HMACkey Key to be used for HMACing * For OIAP use key.authUsage or PersistStore.ownerAuth * For OSAP use shared secret * pAuth Authorization information from the application * * Return: TPM_SUCCESS Authorization data created * TPM_AUTHFAIL Invalid (NULL) HMACkey presented for OSAP *************************************************************************************/ TPM_RESULT GenerateAuth( /*[IN]*/ const BYTE *inParamDigestText, /*[IN]*/ UINT32 inParamDigestTextSize, /*[IN]*/ const TPM_SECRET *HMACkey, /*[IN,OUT]*/ TCS_AUTH *auth) { if (inParamDigestText == NULL || auth == NULL) return (TPM_AUTHFAIL); else { //Generate new OddNonce Crypto_GetRandom(auth->NonceOdd.nonce, sizeof(TPM_NONCE)); // Create SHA1 inParamDigest TPM_DIGEST inParamDigest; Crypto_SHA1Full(inParamDigestText, inParamDigestTextSize, (BYTE *) &inParamDigest); // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams). BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)]; BSG_PackList( hmacText, 4, BSG_TPM_DIGEST, &inParamDigest, BSG_TPM_NONCE, &(auth->NonceEven), BSG_TPM_NONCE, &(auth->NonceOdd), BSG_TYPE_BOOL, &(auth->fContinueAuthSession) ); Crypto_HMAC((BYTE *) hmacText, sizeof(hmacText), (BYTE *) HMACkey, sizeof(TPM_DIGEST), (BYTE *) &(auth->HMAC)); return(TPM_SUCCESS); } } /*********************************************************************************** * VerifyAuth: Verify the authdata for a command requiring authorization * * Parameters: inParamDigestText The concatenation of parameters to be SHA1ed * inParamDigestTextSize Size of inParamDigestText * authDataUsage AuthDataUsage for the Entity being used * Key->authDataUsage or TPM_AUTH_OWNER * HMACkey Key to be used for HMACing * For OIAP use key.authUsage or PersistStore.ownerAuth * For OSAP use NULL (It will be aquired from the Auth Session) * If unknown (default), assume OIAP * sessionAuth A TCS_AUTH info for the session * pAuth Authorization information from the application * hContext If specified, on failed Auth, VerifyAuth will * generate a new OIAP session in place of themselves * destroyed session. * * Return: TPM_SUCCESS Authorization Verified * TPM_AUTHFAIL Authorization Failed * TPM_FAIL Failure during SHA1 routines *************************************************************************************/ TPM_RESULT VerifyAuth( /*[IN]*/ const BYTE *outParamDigestText, /*[IN]*/ UINT32 outParamDigestTextSize, /*[IN]*/ const TPM_SECRET *HMACkey, /*[IN,OUT]*/ TCS_AUTH *auth, /*[IN]*/ TCS_CONTEXT_HANDLE hContext) { if (outParamDigestText == NULL || auth == NULL) return (TPM_AUTHFAIL); // Create SHA1 inParamDigest TPM_DIGEST outParamDigest; Crypto_SHA1Full(outParamDigestText, outParamDigestTextSize, (BYTE *) &outParamDigest); // Create HMAC text. (Concat inParamsDigest with inAuthSetupParams). TPM_DIGEST hm; BYTE hmacText[sizeof(TPM_DIGEST) + (2 * sizeof(TPM_NONCE)) + sizeof(BOOL)]; BSG_PackList( hmacText, 4, BSG_TPM_DIGEST, &outParamDigest, BSG_TPM_NONCE, &(auth->NonceEven), BSG_TPM_NONCE, &(auth->NonceOdd), BSG_TYPE_BOOL, &(
#
#             LUFA Library
#     Copyright (C) Dean Camera, 2017.
#
#  dean [at] fourwalledcubicle [dot] com
#           www.lufa-lib.org
#
# --------------------------------------
#         LUFA Project Makefile.
# --------------------------------------

# Run "make help" for target help.

MCU          = at90usb1287
ARCH         = AVR8
BOARD        = USBKEY
F_CPU        = 8000000
F_USB        = $(F_CPU)
OPTIMIZATION = s
TARGET       = BootloaderMassStorage
SRC          = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S Lib/SCSI.c Lib/VirtualFAT.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
LUFA_PATH    = ../../LUFA
CC_FLAGS     = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET)
LD_FLAGS     = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS)

# Flash size and bootloader section sizes of the target, in KB. These must
# match the target's total FLASH size and the bootloader size set in the
# device's fuses.
FLASH_SIZE_KB         = 128
BOOT_SECTION_SIZE_KB  = 8

# Bootloader address calculation formulas
# Do not modify these macros, but rather modify the dependent values above.
CALC_ADDRESS_IN_HEX   = $(shell printf "0x%X" $$(( $(1) )) )
BOOT_START_OFFSET     = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 )
BOOT_SEC_OFFSET       = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) )

# Bootloader linker section flags for relocating the API table sections to
# known FLASH addresses - these should not normally be user-edited.
BOOT_SECTION_LD_FLAG  = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2))
BOOT_API_LD_FLAGS     = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96)
BOOT_API_LD_FLAGS    += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable,   BootloaderAPI_JumpTable,   32)
BOOT_API_LD_FLAGS    += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures,  BootloaderAPI_Signatures,  8)

# Check if the bootloader needs an AUX section, located before the real bootloader section to store some of the
# bootloader code. This is required for 32KB and smaller devices, where the actual bootloader is 6KB but the maximum
# bootloader section size is 4KB. The actual usable application space will be reduced by 6KB for these devices.
ifeq ($(BOOT_SECTION_SIZE_KB),8)
  CC_FLAGS           += -DAUX_BOOT_SECTION_SIZE=0
else
  AUX_BOOT_SECTION_SIZE_KB = (6 - $(BOOT_SECTION_SIZE_KB))

  CC_FLAGS           += -DAUX_BOOT_SECTION_SIZE='($(AUX_BOOT_SECTION_SIZE_KB) * 1024)'
  LD_FLAGS           += -Wl,--section-start=.boot_aux=$(call BOOT_SEC_OFFSET, (($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024 - 16))
  LD_FLAGS           += $(call BOOT_SECTION_LD_FLAG, .boot_aux_trampoline, Boot_AUX_Trampoline, ($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024)
endif

# Default target
all:

# Include LUFA-specific DMBS extension modules
DMBS_LUFA_PATH ?= $(LUFA_PATH)/Build/LUFA
include $(DMBS_LUFA_PATH)/lufa-sources.mk
include $(DMBS_LUFA_PATH)/lufa-gcc.mk

# Include common DMBS build system modules
DMBS_PATH      ?= $(LUFA_PATH)/Build/DMBS/DMBS
include $(DMBS_PATH)/core.mk
include $(DMBS_PATH)/cppcheck.mk
include $(DMBS_PATH)/doxygen.mk
include $(DMBS_PATH)/dfu.mk
include $(DMBS_PATH)/gcc.mk
include $(DMBS_PATH)/hid.mk
include $(DMBS_PATH)/avrdude.mk
include $(DMBS_PATH)/atprogram.mk
*newKeyHandle, TCS_AUTH *auth, CRYPTO_INFO *cryptoinfo, const BOOL skipTPMLoad) { vtpmloginfo(VTPM_LOG_VTSP, "Loading Key %s.\n", (!skipTPMLoad ? "into TPM" : "only into memory")); TPM_RESULT status = TPM_SUCCESS; TPM_COMMAND_CODE command = TPM_ORD_LoadKey; BYTE *paramText=NULL; // Digest to make Auth. UINT32 paramTextSize; // SkipTPMLoad stops key from being loaded into TPM, but still generates CRYPTO_INFO for it if (! skipTPMLoad) { if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || (newKeyHandle==NULL) || (auth==NULL)) { status = TPM_BAD_PARAMETER; goto abort_egress; } // Generate Extra TCS Parameters TPM_HANDLE phKeyHMAC; paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); paramTextSize = BSG_PackList(paramText, 1, BSG_TPM_COMMAND_CODE, &command); memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob)); paramTextSize += buffer_len(rgbWrappedKeyBlob); TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, parentAuth, auth) ); // Call TCS TPMTRYRETURN( TCSP_LoadKeyByBlob( hContext, hUnwrappingKey, buffer_len(rgbWrappedKeyBlob), rgbWrappedKeyBlob->bytes, auth, newKeyHandle, &phKeyHMAC) ); // Verify Auth paramTextSize = BSG_PackList(paramText, 3, BSG_TPM_RESULT, &status, BSG_TPM_COMMAND_CODE, &command, BSG_TPM_HANDLE, newKeyHandle); TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, parentAuth, auth, hContext) ); } // Build cryptoinfo structure for software crypto function. if (cryptoinfo != NULL) { TPM_KEY newKey; // Unpack/return key structure BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey); TPM_RSA_KEY_PARMS rsaKeyParms; BSG_Unpack(BSG_TPM_RSA_KEY_PARMS, newKey.algorithmParms.parms, &rsaKeyParms); Crypto_RSABuildCryptoInfoPublic(rsaKeyParms.exponentSize, rsaKeyParms.exponent, newKey.pubKey.keyLength, newKey.pubKey.key, cryptoinfo); // Destroy rsaKeyParms BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms); // Set encryption scheme cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1; } goto egress; abort_egress: egress: free(paramText); return status; } TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE hContext, const TPM_KEY_HANDLE key_handle, const buffer_t *bound_data, const TPM_AUTHDATA *usage_auth, buffer_t *clear_data, TCS_AUTH *auth) { vtpmloginfo(VTPM_LOG_VTSP, "Unbinding %d bytes of data.\n", buffer_len(bound_data)); TPM_RESULT status = TPM_SUCCESS; TPM_COMMAND_CODE command = TPM_ORD_UnBind; BYTE *paramText; // Digest to make Auth. UINT32 paramTextSize; // Generate Extra TCS Parameters struct pack_buf_t clear_data32; BYTE *clear_data_text; UINT32 clear_data_size; struct pack_buf_t bound_data32 = {bound_data->size, bound_data->bytes}; paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); paramTextSize = BSG_PackList(paramText, 2, BSG_TPM_COMMAND_CODE, &command, BSG_TPM_SIZE32_DATA, &bound_data32); TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, usage_auth, auth) ); // Call TCS TPMTRYRETURN( TCSP_UnBind( hContext, key_handle, buffer_len(bound_data), bound_data->bytes, auth, &clear_data_size, &clear_data_text) ); // Verify Auth clear_data32.size = clear_data_size; clear_data32.data = clear_data_text; paramTextSize = BSG_PackList(paramText, 3, BSG_TPM_RESULT, &status, BSG_TPM_COMMAND_CODE, &command, BSG_TPM_SIZE32_DATA, &clear_data32); TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, usage_auth, auth, hContext) ); // Unpack/return key structure TPMTRYRETURN(buffer_init(clear_data, 0, 0)); TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size, clear_data_text) ); goto egress; abort_egress: egress: free(paramText); TCS_FreeMemory(hContext, clear_data_text); return status; } TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo, const buffer_t *inData, buffer_t *outData) { vtpmloginfo(VTPM_LOG_VTSP, "Binding %d bytes of data.\n", buffer_len(inData)); TPM_RESULT status = TPM_SUCCESS; TPM_BOUND_DATA boundData; UINT32 i; // Fill boundData's accessory information boundData.ver = TPM_STRUCT_VER_1_1; boundData.payload = TPM_PT_BIND; boundData.payloadData = inData->bytes; // Pack boundData before encryption BYTE* flatBoundData = (BYTE *)malloc(sizeof(BYTE) * (sizeof(TPM_VERSION) + sizeof(TPM_PAYLOAD_TYPE) + buffer_len(inData))); if (flatBoundData == NULL) { return TPM_NOSPACE; } UINT32 flatBoundDataSize = 0; flatBoundDataSize = BSG_PackList( flatBoundData, 2, BSG_TPM_VERSION, &boundData.ver, BSG_TYPE_BYTE, &boundData.payload); memcpy(flatBoundData+flatBoundDataSize, inData->bytes, buffer_len(inData)); flatBoundDataSize += buffer_len(inData); BYTE out_tmp[RSA_KEY_SIZE/8]; // RSAEnc does not do blocking, So this is what will come out. UINT32 out_tmp_size; // Encrypt flatBoundData TPMTRY(TPM_ENCRYPT_ERROR, Crypto_RSAEnc( cryptoInfo, flatBoundDataSize, flatBoundData, &out_tmp_size, out_tmp) ); if (out_tmp_size > RSA_KEY_SIZE/8) { // The result of RSAEnc should be a fixed size based on key size. vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n"); } buffer_init(outData, 0, NULL); buffer_append_raw(outData, out_tmp_size, out_tmp); vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size); for(i = 0 ; i < out_tmp_size ; i++) { vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out_tmp[i]); } vtpmloginfomore(VTPM_LOG_TXDATA, "\n"); goto egress; abort_egress: egress: // Free flatBoundData free(flatBoundData); return TPM_SUCCESS; } TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext, const TPM_KEY_HANDLE keyHandle, const TPM_AUTHDATA *sealDataAuth, const TPM_PCR_COMPOSITE *pcrComp, const buffer_t *inData, TPM_STORED_DATA *sealedData, const TPM_SECRET *osapSharedSecret, TCS_AUTH *auth) { TPM_RESULT status = TPM_SUCCESS; TPM_COMMAND_CODE command = TPM_ORD_Seal; BYTE *paramText; // Digest to make Auth. UINT32 paramTextSize; // Generate PCR_Info Struct from Comp TPM_PCR_INFO pcrInfo; UINT32 pcrInfoSize, flatpcrSize; BYTE flatpcr[3 + // PCR_Select = 3 1 byte banks sizeof(UINT16) + // 2 byte UINT16 sizeof(UINT32) + // PCR_Comp = 4 byte UINT32 24 * sizeof(TPM_PCRVALUE) ]; // up to 24 PCRs if (pcrComp != NULL) { //printf("\n\tBinding to PCRs: "); //for(int i = 0 ; i < pcrComp->select.sizeOfSelect ; i++) //printf("%2.2x", pcrComp->select.pcrSelect[i]); memcpy(&pcrInfo.pcrSelection, &pcrComp->select, sizeof(TPM_PCR_SELECTION)); flatpcrSize = BSG_Pack(BSG_TPM_PCR_COMPOSITE, (BYTE *) pcrComp, flatpcr); Crypto_SHA1Full((BYTE *) flatpcr, flatpcrSize, (BYTE *) &(pcrInfo.digestAtRelease)); memset(&(pcrInfo.digestAtCreation), 0, sizeof(TPM_DIGEST)); pcrInfoSize = BSG_Pack(BSG_TPM_PCR_INFO, (BYTE *) &pcrInfo, flatpcr); } else { //printf("\n\tBinding to no PCRS."); pcrInfoSize = 0; } // Calculate encUsageAuth BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)]; UINT32 XORbufferSize = sizeof(XORbuffer); TPM_DIGEST XORKey; TPM_ENCAUTH encAuth; BSG_PackList( XORbuffer, 2, BSG_TPM_SECRET, osapSharedSecret, BSG_TPM_NONCE, &auth->NonceEven ); Crypto_SHA1Full(XORbuffer, XORbufferSize, (BYTE *) &XORKey); int i; for (i=0; i < TPM_DIGEST_SIZE; i++) ((BYTE *) &encAuth)[i] = ((BYTE *) &XORKey)[i] ^ ((BYTE *) sealDataAuth)[i]; // Generate Extra TCS Parameters UINT32 inDataSize = buffer_len(inData); struct pack_buf_t inData_pack = {inDataSize, inData->bytes}; struct pack_buf_t pcrInfo_pack = {pcrInfoSize, flatpcr}; UINT32 sealedDataSize; BYTE *flatSealedData=NULL; paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); paramTextSize = BSG_PackList(paramText, 4, BSG_TPM_COMMAND_CODE, &command, BSG_TPM_ENCAUTH, &encAuth, BSG_TPM_SIZE32_DATA, &pcrInfo_pack, BSG_TPM_SIZE32_DATA, &inData_pack); TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, osapSharedSecret, auth) ); // Call TCS TPMTRYRETURN( TCSP_Seal( hContext, keyHandle, encAuth, pcrInfoSize, flatpcr, inDataSize, inData->bytes, auth, &sealedDataSize, &flatSealedData) ); // Unpack/return key structure BSG_Unpack( BSG_TPM_STORED_DATA, flatSealedData, sealedData ); paramTextSize = BSG_PackList(paramText, 3, BSG_TPM_RESULT, &status, BSG_TPM_COMMAND_CODE, &command, BSG_TPM_STORED_DATA, sealedData); TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, osapSharedSecret, auth, 0) ); goto egress; abort_egress: egress: if (flatSealedData) TCS_FreeMemory( hContext, flatSealedData); free(paramText); return status; } TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext, const TPM_KEY_HANDLE keyHandle, const TPM_STORED_DATA *sealedData, const TPM_AUTHDATA *key_usage_auth, const TPM_AUTHDATA *data_usage_auth, buffer_t *outData, TCS_AUTH *auth, TCS_AUTH *dataAuth) { TPM_RESULT status = TPM_SUCCESS; TPM_COMMAND_CODE command = TPM_ORD_Unseal; BYTE *paramText; // Digest to make Auth. UINT32 paramTextSize; // Generate Extra TCS Parameters UINT32 sealDataSize, clearDataSize; BYTE *flatSealedData= (BYTE *) malloc(sizeof(TPM_VERSION) + 2 * sizeof(UINT32) + sealedData->sealInfoSize + sealedData->encDataSize), *clearData=NULL; sealDataSize = BSG_Pack(BSG_TPM_STORED_DATA, sealedData, flatSealedData ); paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); paramTextSize = BSG_PackList(paramText, 2, BSG_TPM_COMMAND_CODE, &command, BSG_TPM_STORED_DATA, sealedData); TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, key_usage_auth, auth) ); TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, data_usage_auth, dataAuth) ); // Call TCS TPMTRYRETURN( TCSP_Unseal( hContext, keyHandle, sealDataSize, flatSealedData, auth, dataAuth, &clearDataSize, &clearData) ); // Verify Auth struct pack_buf_t clearData_pack = {clearDataSize, clearData}; paramTextSize = BSG_PackList(paramText, 3, BSG_TPM_RESULT, &status, BSG_TPM_COMMAND_CODE, &command, BSG_TPM_SIZE32_DATA, &clearData_pack); TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, key_usage_auth, auth, hContext) ); TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, data_usage_auth, dataAuth, hContext) ); // Unpack/return key structure TPMTRYRETURN( buffer_init(outData, clearDataSize, clearData) ); goto egress; abort_egress: egress: if (flatSealedData) TCS_FreeMemory( hContext, clearData); free(paramText); return status; } TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE hContext) { vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n"); TPM_RESULT status = TPM_SUCCESS; // Call TCS return ( TCSP_SaveState ( hContext ) ); } // Function Reaches into unsupported TCS command, beware. TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE hContext, const buffer_t *inbuf, buffer_t *outbuf ) { vtpmloginfo(VTPM_LOG_VTSP, "Passthrough in use.\n"); TPM_RESULT status = TPM_SUCCESS; // Generate Extra TCS Parameters BYTE *resultText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); UINT32 resultTextSize = TCPA_MAX_BUFFER_LENGTH; // Call TCS TPMTRYRETURN( TCSP_RawTransmitData(buffer_len(inbuf), inbuf->bytes, &resultTextSize, resultText) ); // Unpack/return key structure TPMTRYRETURN(buffer_init (outbuf, resultTextSize, resultText) ); goto egress; abort_egress: egress: TCS_FreeMemory(hContext, resultText); free(resultText); return status; }