diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssauth12.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssauth12.c')
-rw-r--r-- | roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssauth12.c | 746 |
1 files changed, 746 insertions, 0 deletions
diff --git a/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssauth12.c b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssauth12.c new file mode 100644 index 000000000..1787618a2 --- /dev/null +++ b/roms/skiboot/libstb/tss2/ibmtpm20tss/utils/tssauth12.c @@ -0,0 +1,746 @@ +/********************************************************************************/ +/* */ +/* TPM 1.2 TSS Authorization */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* */ +/* (c) Copyright IBM Corporation 2018 - 2019. */ +/* */ +/* 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 names of the IBM 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 */ +/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ +/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ +/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ +/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ +/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/********************************************************************************/ + +/* This layer handles command and response packet authorization parameters. */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#ifdef TPM_POSIX +#include <netinet/in.h> +#endif +#ifdef TPM_WINDOWS +#include <winsock2.h> +#endif + +#include <ibmtss/tsserror.h> +#include <ibmtss/tssprint.h> +#include <ibmtss/tssutils.h> +#include <ibmtss/tssmarshal.h> +#include <ibmtss/Unmarshal_fp.h> + +#include <ibmtss/tsstransmit.h> +#include "tssproperties.h" +#include <ibmtss/tssresponsecode.h> + +#include <ibmtss/tpmtypes12.h> +#include <ibmtss/tpmconstants12.h> +#include <ibmtss/tssmarshal12.h> +#include <ibmtss/Unmarshal12_fp.h> + +#include "tssauth12.h" + +extern int tssVerbose; +extern int tssVverbose; + +typedef struct MARSHAL_TABLE { + TPM_CC commandCode; + const char *commandText; + MarshalInFunction_t marshalInFunction; /* marshal input command */ + UnmarshalOutFunction_t unmarshalOutFunction; /* unmarshal output response */ +#ifndef TPM_TSS_NOCMDCHECK + UnmarshalInFunction_t unmarshalInFunction; /* unmarshal input command for parameter + checking */ +#endif +} MARSHAL_TABLE; + +static const MARSHAL_TABLE marshalTable12 [] = { + + {TPM_ORD_ActivateIdentity,"TPM_ORD_ActivateIdentity", + (MarshalInFunction_t)TSS_ActivateIdentity_In_Marshalu, + (UnmarshalOutFunction_t)TSS_ActivateIdentity_Out_Unmarshalu, + (UnmarshalInFunction_t)ActivateIdentity_In_Unmarshal}, + + {TPM_ORD_ContinueSelfTest,"TPM_ORD_ContinueSelfTest", + (MarshalInFunction_t)NULL, + (UnmarshalOutFunction_t)NULL, + (UnmarshalInFunction_t)NULL}, + + {TPM_ORD_CreateEndorsementKeyPair,"TPM_ORD_CreateEndorsementKeyPair", + (MarshalInFunction_t)TSS_CreateEndorsementKeyPair_In_Marshalu, + (UnmarshalOutFunction_t)TSS_CreateEndorsementKeyPair_Out_Unmarshalu, + (UnmarshalInFunction_t)CreateEndorsementKeyPair_In_Unmarshal}, + + {TPM_ORD_CreateWrapKey,"TPM_ORD_CreateWrapKey", + (MarshalInFunction_t)TSS_CreateWrapKey_In_Marshalu, + (UnmarshalOutFunction_t)TSS_CreateWrapKey_Out_Unmarshalu, + (UnmarshalInFunction_t)CreateWrapKey_In_Unmarshal}, + + {TPM_ORD_Extend,"TPM_ORD_Extend", + (MarshalInFunction_t)TSS_Extend_In_Marshalu, + (UnmarshalOutFunction_t)TSS_Extend_Out_Unmarshalu, + (UnmarshalInFunction_t)Extend_In_Unmarshal}, + + {TPM_ORD_FlushSpecific,"TPM_ORD_FlushSpecific", + (MarshalInFunction_t)TSS_FlushSpecific_In_Marshalu, + (UnmarshalOutFunction_t)NULL, + (UnmarshalInFunction_t)FlushSpecific_In_Unmarshal}, + + {TPM_ORD_GetCapability,"TPM_ORD_GetCapability", + (MarshalInFunction_t)TSS_GetCapability12_In_Marshalu, + (UnmarshalOutFunction_t)TSS_GetCapability12_Out_Unmarshalu, + (UnmarshalInFunction_t)GetCapability12_In_Unmarshal}, + + {TPM_ORD_LoadKey2,"TPM_ORD_LoadKey2", + (MarshalInFunction_t)TSS_LoadKey2_In_Marshalu, + (UnmarshalOutFunction_t)TSS_LoadKey2_Out_Unmarshalu, + (UnmarshalInFunction_t)LoadKey2_In_Unmarshal}, + + {TPM_ORD_MakeIdentity,"TPM_ORD_MakeIdentity", + (MarshalInFunction_t)TSS_MakeIdentity_In_Marshalu, + (UnmarshalOutFunction_t)TSS_MakeIdentity_Out_Unmarshalu, + (UnmarshalInFunction_t)MakeIdentity_In_Unmarshal}, + + {TPM_ORD_NV_DefineSpace,"TPM_ORD_NV_DefineSpace", + (MarshalInFunction_t)TSS_NV_DefineSpace12_In_Marshalu, + NULL, + (UnmarshalInFunction_t)NV_DefineSpace12_In_Unmarshal}, + + {TPM_ORD_NV_ReadValueAuth,"TPM_ORD_NV_ReadValueAuth", + (MarshalInFunction_t)TSS_NV_ReadValueAuth_In_Marshalu, + (UnmarshalOutFunction_t)TSS_NV_ReadValueAuth_Out_Unmarshalu, + (UnmarshalInFunction_t)NV_ReadValueAuth_In_Unmarshal}, + + {TPM_ORD_NV_ReadValue,"TPM_ORD_NV_ReadValue", + (MarshalInFunction_t)TSS_NV_ReadValue_In_Marshalu, + (UnmarshalOutFunction_t)TSS_NV_ReadValue_Out_Unmarshalu, + (UnmarshalInFunction_t)NV_ReadValue_In_Unmarshal}, + + {TPM_ORD_NV_WriteValue,"TPM_ORD_NV_WriteValue", + (MarshalInFunction_t)TSS_NV_WriteValue_In_Marshalu, + NULL, + (UnmarshalInFunction_t)NV_WriteValue_In_Unmarshal}, + + {TPM_ORD_NV_WriteValueAuth,"TPM_ORD_NV_WriteValueAuth", + (MarshalInFunction_t)TSS_NV_WriteValueAuth_In_Marshalu, + NULL, + (UnmarshalInFunction_t)NV_WriteValueAuth_In_Unmarshal}, + + {TPM_ORD_OIAP,"TPM_ORD_OIAP", + (MarshalInFunction_t)NULL, + (UnmarshalOutFunction_t)TSS_OIAP_Out_Unmarshalu, + (UnmarshalInFunction_t)NULL}, + + {TPM_ORD_OSAP,"TPM_ORD_OSAP", + (MarshalInFunction_t)TSS_OSAP_In_Marshalu, + (UnmarshalOutFunction_t)TSS_OSAP_Out_Unmarshalu, + (UnmarshalInFunction_t)OSAP_In_Unmarshal}, + + {TPM_ORD_OwnerReadInternalPub,"TPM_ORD_OwnerReadInternalPub", + (MarshalInFunction_t)TSS_OwnerReadInternalPub_In_Marshalu, + (UnmarshalOutFunction_t)TSS_OwnerReadInternalPub_Out_Unmarshalu, + (UnmarshalInFunction_t)OwnerReadInternalPub_In_Unmarshal}, + + {TPM_ORD_OwnerSetDisable,"TPM_ORD_OwnerSetDisable", + (MarshalInFunction_t)TSS_OwnerSetDisable_In_Marshalu, + NULL, + (UnmarshalInFunction_t)OwnerSetDisable_In_Unmarshal}, + + {TPM_ORD_MakeIdentity,"TPM_ORD_MakeIdentity", + (MarshalInFunction_t)TSS_MakeIdentity_In_Marshalu, + (UnmarshalOutFunction_t)TSS_MakeIdentity_Out_Unmarshalu, + (UnmarshalInFunction_t)MakeIdentity_In_Unmarshal}, + + {TPM_ORD_PcrRead,"TPM_ORD_PcrRead", + (MarshalInFunction_t)TSS_PcrRead12_In_Marshalu, + (UnmarshalOutFunction_t)TSS_PcrRead12_Out_Unmarshalu, + (UnmarshalInFunction_t)PcrRead12_In_Unmarshal}, + + {TPM_ORD_PCR_Reset,"TPM_ORD_PCR_Reset", + (MarshalInFunction_t)TSS_PCR_Reset12_In_Marshalu, + NULL, + (UnmarshalInFunction_t)PCR_Reset12_In_Unmarshal}, + + {TPM_ORD_Quote2,"TPM_ORD_Quote2", + (MarshalInFunction_t)TSS_Quote2_In_Marshalu, + (UnmarshalOutFunction_t)TSS_Quote2_Out_Unmarshalu, + (UnmarshalInFunction_t)Quote2_In_Unmarshal}, + + {TPM_ORD_ReadPubek,"TPM_ORD_ReadPubek", + (MarshalInFunction_t)TSS_ReadPubek_In_Marshalu, + (UnmarshalOutFunction_t)TSS_ReadPubek_Out_Unmarshalu, + (UnmarshalInFunction_t)ReadPubek_In_Unmarshal}, + + {TPM_ORD_Sign,"TPM_ORD_Sign", + (MarshalInFunction_t)TSS_Sign12_In_Marshalu, + (UnmarshalOutFunction_t)TSS_Sign12_Out_Unmarshalu, + (UnmarshalInFunction_t)Sign12_In_Unmarshal}, + + {TPM_ORD_Startup,"TPM_ORD_Startup", + (MarshalInFunction_t)TSS_Startup12_In_Marshalu, + NULL, + (UnmarshalInFunction_t)Startup12_In_Unmarshal}, + + {TPM_ORD_TakeOwnership,"TPM_ORD_TakeOwnership", + (MarshalInFunction_t)TSS_TakeOwnership_In_Marshalu, + (UnmarshalOutFunction_t)TSS_TakeOwnership_Out_Unmarshalu, + (UnmarshalInFunction_t)TakeOwnership_In_Unmarshal}, + + {TPM_ORD_Init,"TPM_ORD_Init", + NULL, + NULL, + NULL}, +}; + +/* TSS_MarshalTable12_Process() indexes into the command marshal table, and saves the marshal and + unmarshal functions */ + + +static TPM_RC TSS_MarshalTable12_Process(TSS_AUTH_CONTEXT *tssAuthContext, + TPM_CC commandCode) +{ + TPM_RC rc = 0; + size_t index; + int found = FALSE; + + /* get the command index in the dispatch table */ + for (index = 0 ; index < (sizeof(marshalTable12) / sizeof(MARSHAL_TABLE)) ; (index)++) { + if (marshalTable12[index].commandCode == commandCode) { + found = TRUE; + break; + } + } + if (found) { + tssAuthContext->commandCode = commandCode; + tssAuthContext->commandText = marshalTable12[index].commandText; + tssAuthContext->marshalInFunction = marshalTable12[index].marshalInFunction; + tssAuthContext->unmarshalOutFunction = marshalTable12[index].unmarshalOutFunction; +#ifndef TPM_TSS_NOCMDCHECK + tssAuthContext->unmarshalInFunction = marshalTable12[index].unmarshalInFunction; +#endif + } + else { + if (tssVerbose) printf("TSS_MarshalTable12_Process: " + "commandCode %08x not found in marshal table\n", + commandCode); + rc = TSS_RC_COMMAND_UNIMPLEMENTED; + } + return rc; +} + +/* TSS_Marshal12() marshals the input parameters into the TSS Authorization context. + + It also sets other member of the context in preparation for the rest of the sequence. +*/ + +TPM_RC TSS_Marshal12(TSS_AUTH_CONTEXT *tssAuthContext, + COMMAND_PARAMETERS *in, + TPM_CC commandCode) +{ + TPM_RC rc = 0; + TPM_TAG tag = TPM_TAG_RQU_COMMAND; /* default until sessions are added */ + uint8_t *buffer; /* for marshaling */ + uint8_t *bufferu; /* for test unmarshaling */ + uint32_t size; + + /* index from command code to table and save marshal and unmarshal functions for this command */ + if (rc == 0) { + rc = TSS_MarshalTable12_Process(tssAuthContext, commandCode); + } + /* get the number of command and response handles from the TPM table */ + if (rc == 0) { + tssAuthContext->tpmCommandIndex = CommandCodeToCommandIndex12(commandCode); + if (tssAuthContext->tpmCommandIndex == UNIMPLEMENTED_COMMAND_INDEX) { + if (tssVerbose) printf("TSS_Marshal12: " + "commandCode %08x not found in command attributes table\n", + commandCode); + rc = TSS_RC_COMMAND_UNIMPLEMENTED; + } + } + if (rc == 0) { + tssAuthContext->commandHandleCount = + getCommandHandleCount12(tssAuthContext->tpmCommandIndex); + tssAuthContext->responseHandleCount = + getresponseHandleCount12(tssAuthContext->tpmCommandIndex); + } + if (rc == 0) { + /* make a copy of the command buffer and size since the marshal functions move them */ + buffer = tssAuthContext->commandBuffer; + size = MAX_COMMAND_SIZE; + /* marshal header, preliminary tag and command size */ + rc = TSS_UINT16_Marshalu(&tag, &tssAuthContext->commandSize, &buffer, &size); + } + if (rc == 0) { + uint32_t commandSize = tssAuthContext->commandSize; + rc = TSS_UINT32_Marshalu(&commandSize, &tssAuthContext->commandSize, &buffer, &size); + } + if (rc == 0) { + rc = TSS_UINT32_Marshalu(&commandCode, &tssAuthContext->commandSize, &buffer, &size); + } + if (rc == 0) { + /* save pointer to marshaled data for test unmarshal */ + bufferu = buffer + + tssAuthContext->commandHandleCount * sizeof(TPM_HANDLE); + /* if there is a marshal function */ + if (tssAuthContext->marshalInFunction != NULL) { + /* if there is a structure to marshal */ + if (in != NULL) { + rc = tssAuthContext->marshalInFunction(in, &tssAuthContext->commandSize, + &buffer, &size); + } + /* caller error, no structure supplied to marshal */ + else { + if (tssVerbose) + printf("TSS_Marshal12: Command %08x requires command parameter structure\n", + commandCode); + rc = TSS_RC_IN_PARAMETER; + } + } + /* if there is no marshal function */ + else { + /* caller error, supplied structure but there is no marshal function */ + if (in != NULL) { + if (tssVerbose) + printf("TSS_Marshal12: Command %08x does not take command parameter structure\n", + commandCode); + rc = TSS_RC_IN_PARAMETER; + } + /* no marshal function and no command parameter structure is OK */ + } + } +#ifndef TPM_TSS_NOCMDCHECK + /* unmarshal to validate the input parameters */ + if ((rc == 0) && (tssAuthContext->unmarshalInFunction != NULL)) { + COMMAND_PARAMETERS target; + TPM_HANDLE handles[MAX_HANDLE_NUM]; + size = MAX_COMMAND_SIZE; + rc = tssAuthContext->unmarshalInFunction(&target, &bufferu, &size, handles); + if ((rc != 0) && tssVerbose) { + printf("TSS_Marshal12: Invalid command parameter\n"); + } + } +#endif + /* back fill the correct commandSize */ + if (rc == 0) { + uint16_t written = 0; /* dummy */ + uint32_t commandSize = tssAuthContext->commandSize; + buffer = tssAuthContext->commandBuffer + sizeof(TPMI_ST_COMMAND_TAG); + TSS_UINT32_Marshalu(&commandSize, &written, &buffer, NULL); + } + /* record the interim cpBuffer and cpBufferSize before adding authorizations */ + if (rc == 0) { + uint32_t notCpBufferSize; + + /* cpBuffer does not include the header and handles */ + notCpBufferSize = sizeof(TPMI_ST_COMMAND_TAG) + sizeof (uint32_t) + sizeof(TPM_CC) + + (sizeof(TPM_HANDLE) * tssAuthContext->commandHandleCount); + + tssAuthContext->cpBuffer = tssAuthContext->commandBuffer + notCpBufferSize; + tssAuthContext->cpBufferSize = tssAuthContext->commandSize - notCpBufferSize; + } + return rc; +} + +/* TSS_Unmarshal12() unmarshals the response parameter. + + It returns an error if either there is no unmarshal function and out is not NULL or if there is + an unmarshal function and out is not NULL. + + If there is no unmarshal function and out is NULL, the function is a noop. +*/ + +TPM_RC TSS_Unmarshal12(TSS_AUTH_CONTEXT *tssAuthContext, + RESPONSE_PARAMETERS *out) +{ + TPM_RC rc = 0; + TPM_TAG tag; + uint8_t *buffer; + uint32_t size; + + /* if there is an unmarshal function */ + if (tssAuthContext->unmarshalOutFunction != NULL) { + /* if there is a structure to unmarshal */ + if (out != NULL) { + if (rc == 0) { + /* get the response tag, determines whether there are response authorizations to + unmarshal */ + /* tag not required for TPM 1.2, where there is no parameterSize to skip, but the + response unmarshal function uses a common prototype */ + buffer = tssAuthContext->responseBuffer; + size = tssAuthContext->responseSize; + rc = TSS_TPM_TAG_Unmarshalu(&tag, &buffer, &size); + } + if (rc == 0) { + /* move the buffer and size past the header */ + buffer = tssAuthContext->responseBuffer + + sizeof(TPM_TAG) + sizeof(uint32_t) + sizeof(TPM_RC); + size = tssAuthContext->responseSize - + (sizeof(TPM_TAG) + sizeof(uint32_t) + sizeof(TPM_RC)); + rc = tssAuthContext->unmarshalOutFunction(out, tag, &buffer, &size); + } + } + /* caller error, no structure supplied to unmarshal */ + else { + if (tssVerbose) + printf("TSS_Unmarshal12: Command %08x requires response parameter structure\n", + tssAuthContext->commandCode); + rc = TSS_RC_OUT_PARAMETER; + } + } + /* if there is no unmarshal function */ + else { + /* caller error, structure supplied but no unmarshal function */ + if (out != NULL) { + if (tssVerbose) + printf("TSS_Unmarshal12: Command %08x does not take response parameter structure\n", + tssAuthContext->commandCode); + rc = TSS_RC_OUT_PARAMETER; + } + /* no unmarshal function and no response parameter structure is OK */ + } + return rc; +} + +/* TSS_SetCmdAuths12() appends a list of TPMS_AUTH12_COMMAND structures to the command buffer. It + back fills the tag and paramSize. + +*/ + +TPM_RC TSS_SetCmdAuths12(TSS_AUTH_CONTEXT *tssAuthContext, + size_t numSessions, + TPMS_AUTH12_COMMAND *authC[]) +{ + TPM_RC rc = 0; + size_t i = 0; + TPM_TAG tag; + uint32_t cpBufferSize; + uint8_t *cpBuffer; + uint8_t *buffer; + + if (rc == 0) { + /* record the number of authorizations for the response */ + tssAuthContext->authCount = numSessions; + switch (numSessions) { + case 0: + tag = TPM_TAG_RQU_COMMAND; + break; + case 1: + tag = TPM_TAG_RQU_AUTH1_COMMAND; + break; + case 2: + tag = TPM_TAG_RQU_AUTH2_COMMAND; + break; + default: + if (tssVerbose) printf("TSS_SetCmdAuths12: Invalid number of sessions %u\n", + (unsigned int)numSessions); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + /* back fill the tag */ + if (rc == 0) { + uint16_t written = 0; /* dummy */ + buffer = tssAuthContext->commandBuffer; + TSS_UINT16_Marshalu(&tag, &written, &buffer, NULL); + } + /* get cpBuffer, command parameters */ + if (rc == 0) { + rc = TSS_GetCpBuffer(tssAuthContext, &cpBufferSize, &cpBuffer); + } + /* index to the beginning of the authorization area, and range check the command buffer */ + if (rc == 0) { + cpBuffer += cpBufferSize; + } + for (i = 0 ; (rc == 0) && (i < numSessions) ; i++) { + uint16_t written = 0; + uint32_t size = MAX_COMMAND_SIZE - cpBufferSize; + /* marshal authHandle */ + if (rc == 0) { + rc = TSS_UINT32_Marshalu(&authC[i]->sessionHandle, &written, &cpBuffer, &size); + } + /* marshal nonceOdd */ + if (rc == 0) { + rc = TSS_Array_Marshalu(authC[i]->nonce, SHA1_DIGEST_SIZE, + &written, &cpBuffer, &size); + } + /* marshal attributes */ + if (rc == 0) { + rc = TSS_UINT8_Marshalu(&authC[i]->sessionAttributes.val, &written, &cpBuffer, &size); + } + /* marshal HMAC */ + if (rc == 0) { + rc = TSS_Array_Marshalu(authC[i]->hmac, SHA1_DIGEST_SIZE, + &written, &cpBuffer, &size); + } + } + if (rc == 0) { + uint16_t written = 0; /* dummy */ + uint32_t commandSize; + /* record command stream used size */ + tssAuthContext->commandSize = cpBuffer - tssAuthContext->commandBuffer; + /* back fill the correct commandSize */ + buffer = tssAuthContext->commandBuffer + sizeof(TPMI_ST_COMMAND_TAG); + commandSize = tssAuthContext->commandSize; + TSS_UINT32_Marshalu(&commandSize, &written, &buffer, NULL); + } + return rc; +} + +/* TSS_GetRspAuths12() unmarshals a response buffer into a list of list of TPMS_AUTH12_RESPONSE + structures. This should not be called if the TPM returned a non-success response code. + + Returns an error if the number of response auths requested is not equal to the number of command + auths, including zero. + + If the response tag is TPM_TAG_RSP_COMMAND, the function is a noop (except for error checking). +*/ + +TPM_RC TSS_GetRspAuths12(TSS_AUTH_CONTEXT *tssAuthContext, + size_t numSessions, + TPMS_AUTH12_RESPONSE *authR[]) +{ + TPM_RC rc = 0; + size_t i; + TPM_TAG tag; + uint32_t oneAuthAreaSize = SHA1_DIGEST_SIZE + 1 + SHA1_DIGEST_SIZE; + uint32_t authBufferSize; + uint8_t *authBuffer; + + /* range check the response buffer size before the subtraction below */ + if (rc == 0) { + if ((sizeof(TPM_TAG) + sizeof(uint32_t) + sizeof(TPM_RC) + + (numSessions * oneAuthAreaSize)) <= tssAuthContext->responseSize) { + authBufferSize = tssAuthContext->responseSize - + (sizeof(TPM_TAG) + sizeof(uint32_t) + sizeof(TPM_RC)); + } + else { + if (tssVerbose) printf("TSS_GetRspAuths12: Invalid response size %u\n", + (unsigned int)tssAuthContext->responseSize); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + /* unmarshal the response tag */ + if (rc == 0) { + uint32_t size = tssAuthContext->responseSize; + uint8_t *buffer = tssAuthContext->responseBuffer; + rc = TSS_TPM_TAG_Unmarshalu(&tag, &buffer, &size); + } + /* sanity check the response tag, range checking below */ + if (rc == 0) { + switch (tag) { + case TPM_TAG_RSP_COMMAND: + if (numSessions != 0) { + if (tssVerbose) printf("TSS_GetRspAuths12: Invalid number of sessions %u\n", + (unsigned int)numSessions); + rc = TSS_RC_MALFORMED_RESPONSE; + } + break; + case TPM_TAG_RSP_AUTH1_COMMAND: + authBuffer = tssAuthContext->responseBuffer + tssAuthContext->responseSize /* end */ + - oneAuthAreaSize; /* minus one auth area */ + authBufferSize = oneAuthAreaSize; + if (numSessions != 1) { + if (tssVerbose) printf("TSS_GetRspAuths12: Invalid number of sessions %u\n", + (unsigned int)numSessions); + rc = TSS_RC_MALFORMED_RESPONSE; + } + break; + case TPM_TAG_RSP_AUTH2_COMMAND: + authBuffer = tssAuthContext->responseBuffer + tssAuthContext->responseSize /* end */ + - oneAuthAreaSize - oneAuthAreaSize ; /* minus two auth areas */ + authBufferSize = oneAuthAreaSize + oneAuthAreaSize; + if (numSessions != 2) { + if (tssVerbose) printf("TSS_GetRspAuths12: Invalid number of sessions %u\n", + (unsigned int)numSessions); + rc = TSS_RC_MALFORMED_RESPONSE; + } + break; + default: + if (tssVerbose) printf("TSS_GetRspAuths12: Bad tag %04x\n", tag); + rc = TSS_RC_MALFORMED_RESPONSE; + break; + } + } + /* unmarshal into the TPMS_AUTH12_RESPONSE structures */ + for (i = 0 ; (rc == 0) && (i < numSessions) ; i++) { + /* TPM 1.2 has fixed size auth area - nonceEven + continue + auth HMAC */ + if (rc == 0) { + rc = TSS_Array_Unmarshalu(authR[i]->nonce, + SHA1_DIGEST_SIZE, &authBuffer, &authBufferSize); + } + if (rc == 0) { + rc = TSS_UINT8_Unmarshalu(&authR[i]->sessionAttributes.val, &authBuffer, &authBufferSize); + } + if (rc == 0) { + rc = TSS_Array_Unmarshalu(authR[i]->hmac, + SHA1_DIGEST_SIZE, &authBuffer, &authBufferSize); + } + } + return rc; +} + +/* TSS_GetRpBuffer12() returns a pointer to the response parameter area. + + NOTE could move to execute so it only has to be done once. +*/ + +TPM_RC TSS_GetRpBuffer12(TSS_AUTH_CONTEXT *tssAuthContext, + uint32_t *rpBufferSize, + uint8_t **rpBuffer, + size_t numSessions) +{ + TPM_RC rc = 0; + uint32_t headerSize = sizeof(TPM_TAG) + sizeof (uint32_t) + sizeof(TPM_RC) + + (sizeof(TPM_HANDLE) * tssAuthContext->responseHandleCount); + uint32_t oneAuthAreaSize = SHA1_DIGEST_SIZE + 1 + SHA1_DIGEST_SIZE; + + if (rc == 0) { + *rpBuffer = tssAuthContext->responseBuffer + headerSize; + + if (headerSize + (numSessions * oneAuthAreaSize) <= tssAuthContext->responseSize) { + *rpBufferSize = + tssAuthContext->responseSize - headerSize - (numSessions * oneAuthAreaSize); + } + else { + if (tssVerbose) printf("TSS_GetRpBuffer12: " + "response size %u too small for number of sessions %u\n", + tssAuthContext->responseSize, (unsigned int)numSessions); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + return rc; +} + +/* TSS_SetEncAuth() are called from the TPM 1.2 command pre-processor to record the location(s) of + the encrypted authorizations. + + Cannot range check here, because command parameters have not been marshaled yet. + + NOTE: This is a bit of a hack, depending on the location being a fixed distance from the + beginning or end of the command buffer. It could break if there is both a variable size argument + before and a variable number of authorizations or variable size argument after the location. + + If this occurs, the pointers nust be set during marshaling, but this is more intrusive, requiring + TSS_AUTH_CONTEXT to be passed into the marshaling code. + +*/ + +TPM_RC TSS_SetEncAuthOffset0(TSS_AUTH_CONTEXT *tssAuthContext, + int16_t offset) +{ + tssAuthContext->encAuthOffset0 = offset; + return 0; +} +TPM_RC TSS_SetEncAuthOffset1(TSS_AUTH_CONTEXT *tssAuthContext, + int16_t offset) +{ + tssAuthContext->encAuthOffset1 = offset; + return 0; +} +TPM_RC TSS_GetEncAuths(TSS_AUTH_CONTEXT *tssAuthContext, + uint8_t **encAuth0, + uint8_t **encAuth1) +{ + TPM_RC rc = 0; + + if (tssAuthContext->encAuthOffset0 > 0) { + if ((uint16_t)tssAuthContext->encAuthOffset0 < tssAuthContext->cpBufferSize) { + *encAuth0 = tssAuthContext->commandBuffer + tssAuthContext->encAuthOffset0; + } + else { + if (tssVerbose) printf("TSS_GetEncAuths: " + "encAuthOffset0 %d too large for command buffer %u\n", + tssAuthContext->encAuthOffset0, tssAuthContext->cpBufferSize); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + else if (tssAuthContext->encAuthOffset0 < 0) { + if ((uint16_t)(-tssAuthContext->encAuthOffset0) < tssAuthContext->commandSize) { + *encAuth0 = tssAuthContext->commandBuffer + + tssAuthContext->commandSize + tssAuthContext->encAuthOffset0; + } + else { + if (tssVerbose) printf("TSS_GetEncAuths: " + "encAuthOffset0 %d too large for command buffer %u\n", + tssAuthContext->encAuthOffset0, tssAuthContext->commandSize); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + else { + *encAuth0 = NULL; + } + if (tssAuthContext->encAuthOffset1 > 0) { + if ((uint16_t)tssAuthContext->encAuthOffset1 < tssAuthContext->cpBufferSize) { + *encAuth1 = tssAuthContext->commandBuffer + tssAuthContext->encAuthOffset1; + } + else { + if (tssVerbose) printf("TSS_GetEncAuths: " + "encAuthOffset1 %u too large for command buffer %u\n", + tssAuthContext->encAuthOffset1, tssAuthContext->cpBufferSize); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + else if (tssAuthContext->encAuthOffset1 < 0) { + if ((uint16_t)(-tssAuthContext->encAuthOffset1) < tssAuthContext->commandSize) { + *encAuth1 = tssAuthContext->commandBuffer + + tssAuthContext->commandSize + tssAuthContext->encAuthOffset1; + } + else { + if (tssVerbose) printf("TSS_GetEncAuths: " + "encAuthOffset1 %d too large for command buffer %u\n", + tssAuthContext->encAuthOffset1, tssAuthContext->commandSize); + rc = TSS_RC_MALFORMED_RESPONSE; + } + } + else { + *encAuth1 = NULL; + } + return rc; +} + +TPM_RC TSS_SetSessionNumber(TSS_AUTH_CONTEXT *tssAuthContext, + uint16_t sessionNumber) +{ + TPM_RC rc = 0; + + tssAuthContext->sessionNumber = sessionNumber; + if (sessionNumber > 1) { + if (tssVerbose) printf("TSS_SetSessionNumber: %u out of range\n", + sessionNumber); + rc = TSS_RC_SESSION_NUMBER; + } + return rc; +} +TPM_RC TSS_GetSessionNumber(TSS_AUTH_CONTEXT *tssAuthContext, + uint16_t *sessionNumber) +{ + *sessionNumber = tssAuthContext->sessionNumber; + return 0; +} |