TPM_RC TSS_GetRpBuffer(struct TSS_CONTEXT *tssContext, uint32_t *rpBufferSize, uint8_t **rpBuffer) { TPM_RC rc = 0; TPM_ST tag; /* response tag */ uint32_t offsetSize; /* to beginning of parameter area */ INT32 size; /* tmp for unmarshal */ uint8_t *buffer; /* tmp for unmarshal */ uint32_t parameterSize; /* response parameter (if sessions) */ /* unmarshal the response tag */ if (rc == 0) { size = tssContext->responseSize; buffer = tssContext->responseBuffer; rc = TPM_ST_Unmarshal(&tag, &buffer, &size); } if (rc == 0) { /* offset to parameterSize or parameters */ offsetSize = sizeof(TPM_ST) + + sizeof (uint32_t) + sizeof(TPM_RC) + (sizeof(TPM_HANDLE) * tssContext->responseHandleCount); /* no sessions -> no parameterSize */ if (tag == TPM_ST_NO_SESSIONS) { *rpBufferSize = tssContext->responseSize - offsetSize; *rpBuffer = tssContext->responseBuffer + offsetSize; } /* sessions -> parameterSize */ else { if (rc == 0) { size = tssContext->responseSize - offsetSize; buffer = tssContext->responseBuffer + offsetSize; rc = UINT32_Unmarshal(¶meterSize, &buffer, &size); } /* FIXME need consistency check */ if (rc == 0) { offsetSize += sizeof(uint32_t); *rpBufferSize = parameterSize; *rpBuffer = tssContext->responseBuffer + offsetSize; } } } return rc; }
static int unmarshal_array(uint8_t* dstptr, uint32_t size, uint8_t** curr_pos, uint32_t* curr_size) { int result; TPM_RC tpm_res = UINT32_Unmarshal((uint32_t*)dstptr, curr_pos, (int32_t*)curr_size); if (tpm_res != TPM_RC_SUCCESS) { LogError("Failure: unmarshalling array."); result = __FAILURE__; } else if (*curr_size < size) { LogError("Failure: unmarshalling array need %d bytes, while only %d left.", size, *curr_size); result = __FAILURE__; } else { dstptr = *curr_pos - sizeof(UINT16); *(UINT16*)dstptr = (UINT16)size; curr_pos += size; result = 0; } return result; }
TPM_RC TSS_GetRspAuths(struct TSS_CONTEXT *tssContext, ...) { TPM_RC rc = 0; va_list ap; TPMS_AUTH_RESPONSE *authResponse = NULL; INT32 size; uint8_t *buffer; TPM_ST tag; BOOL done; uint16_t authCount = 0; /* authorizations in response */ uint32_t parameterSize; /* unmarshal the response tag */ if (rc == 0) { size = tssContext->responseSize; buffer = tssContext->responseBuffer; rc = TPM_ST_Unmarshal(&tag, &buffer, &size); } /* check that the tag indicates that there are sessions */ if (tag == TPM_ST_SESSIONS) { /* offset the buffer past the header and handles, and get the response parameterSize */ if (rc == 0) { uint32_t offsetSize = sizeof(TPM_ST) + + sizeof (uint32_t) + sizeof(TPM_RC) + (sizeof(TPM_HANDLE) * tssContext->responseHandleCount); buffer = tssContext->responseBuffer + offsetSize; size = tssContext->responseSize - offsetSize; rc = UINT32_Unmarshal(¶meterSize, &buffer, &size); } if (rc == 0) { /* index past the response parameters to the authorization area */ buffer += parameterSize; size -= parameterSize; } /* unmarshal the response authorization area */ done = FALSE; va_start(ap, tssContext); while ((rc == 0) && !done){ authResponse = va_arg(ap, TPMS_AUTH_RESPONSE *); if (authResponse != NULL) { rc = TPMS_AUTH_RESPONSE_Unmarshal(authResponse, &buffer, &size); authCount++; } else { done = TRUE; } } va_end(ap); /* check for extra bytes at the end of the response */ if (rc == 0) { if (size != 0) { if (tseVerbose) printf("TSS_GetRspAuths: Extra bytes at the end of response authorizations\n"); rc = TSE_RC_MALFORMED_RESPONSE; } } } /* check that the same number was requested as were sent in the command. Check for zero if not TPM_ST_SESSIONS */ if (rc == 0) { if (tssContext->authCount != authCount) { if (tseVerbose) printf("TSS_GetRspAuths: " "Command authorizations requested not equal number in command\n"); rc = TSE_RC_MALFORMED_RESPONSE; } } return rc; }