in TAs/optee_ta/fTPM/fTPM.c [259:324]
static TEE_Result fTPM_Submit_Command(uint32_t param_types,
TEE_Param params[4]
)
{
uint8_t *cmdBuf, *respBuf;
uint32_t cmdLen, respLen;
uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_MEMREF_INOUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);
DMSG("fTPM submit command");
// Validate parameter types
if (param_types != exp_param_types) {
#ifdef fTPMDebug
IMSG("Bad param type(s)\n");
#endif
return TEE_ERROR_BAD_PARAMETERS;
}
// Sanity check our buffer sizes
if ((params[0].memref.size == 0) ||
(params[1].memref.size == 0) ||
(params[0].memref.size > MAX_COMMAND_SIZE) ||
(params[1].memref.size > MAX_RESPONSE_SIZE)) {
#ifdef fTPMDebug
IMSG("Bad param size(s)\n");
#endif
return TEE_ERROR_BAD_PARAMETERS;
}
// Copy command locally
memcpy(fTPMCommand, params[0].memref.buffer, params[0].memref.size);
// Pull the command length from the actual TPM command. The memref size
// field descibes the buffer containing the command, not the command.
cmdBuf = fTPMCommand;
cmdLen = BYTE_ARRAY_TO_UINT32((uint8_t *)&(cmdBuf[2]));
// Sanity check cmd length included in TPM command
if (cmdLen > params[0].memref.size) {
return TEE_ERROR_BAD_PARAMETERS;
}
respBuf = (uint8_t *)(params[1].memref.buffer);
respLen = params[1].memref.size;
// Check if this is a PPI Command
if (!_admin__PPICommand(cmdLen, cmdBuf, &respLen, &respBuf)) {
// If not, pass through to TPM
ExecuteCommand(cmdLen, cmdBuf, &respLen, &respBuf);
}
// Unfortunately, this cannot be done until after we have our response in
// hand. We will, however, make an effort to return at least a portion of
// the response along with TEE_ERROR_SHORT_BUFFER.
if (respLen > params[1].memref.size)
{
#ifdef fTPMDebug
IMSG("Insufficient buffer length RS: 0x%x > BL: 0x%x\n", respLen, params[1].memref.size);
#endif
return TEE_ERROR_SHORT_BUFFER;
}
#ifdef fTPMDebug
DMSG("Success, RS: 0x%x\n", respLen);
#endif
params[1].memref.size = respLen;
return TEE_SUCCESS;
}