diff options
Diffstat (limited to 'firmware/stub/tpm_lite_stub.c')
-rw-r--r-- | firmware/stub/tpm_lite_stub.c | 332 |
1 files changed, 170 insertions, 162 deletions
diff --git a/firmware/stub/tpm_lite_stub.c b/firmware/stub/tpm_lite_stub.c index 5e6c7192..109b8c11 100644 --- a/firmware/stub/tpm_lite_stub.c +++ b/firmware/stub/tpm_lite_stub.c @@ -46,205 +46,213 @@ static int exit_on_failure = 1; /* Similar to VbExError, only handle the non-exit case. */ -static VbError_t DoError(VbError_t result, const char* format, ...) { - va_list ap; - va_start(ap, format); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, format, ap); - va_end(ap); - if (exit_on_failure) - exit(1); - return result; +static VbError_t DoError(VbError_t result, const char* format, ...) +{ + va_list ap; + va_start(ap, format); + fprintf(stderr, "ERROR: "); + vfprintf(stderr, format, ap); + va_end(ap); + if (exit_on_failure) + exit(1); + return result; } - /* Print |n| bytes from array |a|, with newlines. */ -__attribute__((unused)) static void PrintBytes(const uint8_t* a, int n) { - int i; - for (i = 0; i < n; i++) { - VBDEBUG(("%02x ", a[i])); - if ((i + 1) % 16 == 0) { - VBDEBUG(("\n")); - } - } - if (i % 16 != 0) { - VBDEBUG(("\n")); - } +__attribute__((unused)) static void PrintBytes(const uint8_t* a, int n) +{ + int i; + for (i = 0; i < n; i++) { + VBDEBUG(("%02x ", a[i])); + if ((i + 1) % 16 == 0) { + VBDEBUG(("\n")); + } + } + if (i % 16 != 0) { + VBDEBUG(("\n")); + } } /* Executes a command on the TPM. */ static VbError_t TpmExecute(const uint8_t *in, const uint32_t in_len, - uint8_t *out, uint32_t *pout_len) { - uint8_t response[TPM_MAX_COMMAND_SIZE]; - if (in_len <= 0) { - return DoError(TPM_E_INPUT_TOO_SMALL, - "invalid command length %d for command 0x%x\n", - in_len, in[9]); - } else if (tpm_fd < 0) { - return DoError(TPM_E_NO_DEVICE, - "the TPM device was not opened. " \ - "Forgot to call TlclLibInit?\n"); - } else { - int n = write(tpm_fd, in, in_len); - if (n != in_len) { - return DoError(TPM_E_WRITE_FAILURE, - "write failure to TPM device: %s\n", strerror(errno)); - } - n = read(tpm_fd, response, sizeof(response)); - if (n == 0) { - return DoError(TPM_E_READ_EMPTY, "null read from TPM device\n"); - } else if (n < 0) { - return DoError(TPM_E_READ_FAILURE, "read failure from TPM device: %s\n", - strerror(errno)); - } else { - if (n > *pout_len) { - return DoError(TPM_E_RESPONSE_TOO_LARGE, - "TPM response too long for output buffer\n"); - } else { - *pout_len = n; - Memcpy(out, response, n); - } - } - } - return VBERROR_SUCCESS; + uint8_t *out, uint32_t *pout_len) +{ + uint8_t response[TPM_MAX_COMMAND_SIZE]; + if (in_len <= 0) { + return DoError(TPM_E_INPUT_TOO_SMALL, + "invalid command length %d for command 0x%x\n", + in_len, in[9]); + } else if (tpm_fd < 0) { + return DoError(TPM_E_NO_DEVICE, + "the TPM device was not opened. " \ + "Forgot to call TlclLibInit?\n"); + } else { + int n = write(tpm_fd, in, in_len); + if (n != in_len) { + return DoError(TPM_E_WRITE_FAILURE, + "write failure to TPM device: %s\n", + strerror(errno)); + } + n = read(tpm_fd, response, sizeof(response)); + if (n == 0) { + return DoError(TPM_E_READ_EMPTY, + "null read from TPM device\n"); + } else if (n < 0) { + return DoError(TPM_E_READ_FAILURE, + "read failure from TPM device: %s\n", + strerror(errno)); + } else { + if (n > *pout_len) { + return DoError(TPM_E_RESPONSE_TOO_LARGE, + "TPM response too long for " + "output buffer\n"); + } else { + *pout_len = n; + Memcpy(out, response, n); + } + } + } + return VBERROR_SUCCESS; } - /* Gets the tag field of a TPM command. */ __attribute__((unused)) -static inline int TpmTag(const uint8_t* buffer) { - uint16_t tag; - FromTpmUint16(buffer, &tag); - return (int) tag; +static inline int TpmTag(const uint8_t* buffer) +{ + uint16_t tag; + FromTpmUint16(buffer, &tag); + return (int) tag; } - /* Gets the size field of a TPM command. */ __attribute__((unused)) -static inline int TpmResponseSize(const uint8_t* buffer) { - uint32_t size; - FromTpmUint32(buffer + sizeof(uint16_t), &size); - return (int) size; +static inline int TpmResponseSize(const uint8_t* buffer) +{ + uint32_t size; + FromTpmUint32(buffer + sizeof(uint16_t), &size); + return (int) size; } - -VbError_t VbExTpmInit(void) { - char *no_exit = getenv("TPM_NO_EXIT"); - if (no_exit) - exit_on_failure = !atoi(no_exit); - return VbExTpmOpen(); +VbError_t VbExTpmInit(void) +{ + char *no_exit = getenv("TPM_NO_EXIT"); + if (no_exit) + exit_on_failure = !atoi(no_exit); + return VbExTpmOpen(); } - -VbError_t VbExTpmClose(void) { - if (tpm_fd != -1) { - close(tpm_fd); - tpm_fd = -1; - } - return VBERROR_SUCCESS; +VbError_t VbExTpmClose(void) +{ + if (tpm_fd != -1) { + close(tpm_fd); + tpm_fd = -1; + } + return VBERROR_SUCCESS; } - -VbError_t VbExTpmOpen(void) { - char* device_path; - struct timespec delay; - int retries, saved_errno; - - if (tpm_fd >= 0) - return VBERROR_SUCCESS; /* Already open */ - - device_path = getenv("TPM_DEVICE_PATH"); - if (device_path == NULL) { - device_path = TPM_DEVICE_PATH; - } - - /* Retry TPM opens on EBUSY failures. */ - for (retries = 0; retries < OPEN_RETRY_MAX_NUM; ++ retries) { - errno = 0; - tpm_fd = open(device_path, O_RDWR); - saved_errno = errno; - if (tpm_fd >= 0) - return VBERROR_SUCCESS; - if (saved_errno != EBUSY) - break; - - VBDEBUG(("TPM: retrying %s: %s\n", device_path, strerror(errno))); - - /* Stall until TPM comes back. */ - delay.tv_sec = 0; - delay.tv_nsec = OPEN_RETRY_DELAY_NS; - nanosleep(&delay, NULL); - } - return DoError(TPM_E_NO_DEVICE, "TPM: Cannot open TPM device %s: %s\n", - device_path, strerror(saved_errno)); +VbError_t VbExTpmOpen(void) +{ + char* device_path; + struct timespec delay; + int retries, saved_errno; + + if (tpm_fd >= 0) + return VBERROR_SUCCESS; /* Already open */ + + device_path = getenv("TPM_DEVICE_PATH"); + if (device_path == NULL) { + device_path = TPM_DEVICE_PATH; + } + + /* Retry TPM opens on EBUSY failures. */ + for (retries = 0; retries < OPEN_RETRY_MAX_NUM; ++ retries) { + errno = 0; + tpm_fd = open(device_path, O_RDWR); + saved_errno = errno; + if (tpm_fd >= 0) + return VBERROR_SUCCESS; + if (saved_errno != EBUSY) + break; + + VBDEBUG(("TPM: retrying %s: %s\n", + device_path, strerror(errno))); + + /* Stall until TPM comes back. */ + delay.tv_sec = 0; + delay.tv_nsec = OPEN_RETRY_DELAY_NS; + nanosleep(&delay, NULL); + } + return DoError(TPM_E_NO_DEVICE, "TPM: Cannot open TPM device %s: %s\n", + device_path, strerror(saved_errno)); } - VbError_t VbExTpmSendReceive(const uint8_t* request, uint32_t request_length, - uint8_t* response, uint32_t* response_length) { - /* - * In a real firmware implementation, this function should contain - * the equivalent API call for the firmware TPM driver which takes a - * raw sequence of bytes as input command and a pointer to the - * output buffer for putting in the results. - * - * For EFI firmwares, this can make use of the EFI TPM driver as - * follows (based on page 16, of TCG EFI Protocol Specs Version 1.20 - * availaible from the TCG website): - * - * EFI_STATUS status; - * status = TcgProtocol->EFI_TCG_PASS_THROUGH_TO_TPM(TpmCommandSize(request), - * request, - * max_length, - * response); - * // Error checking depending on the value of the status above - */ + uint8_t* response, uint32_t* response_length) +{ + /* + * In a real firmware implementation, this function should contain + * the equivalent API call for the firmware TPM driver which takes a + * raw sequence of bytes as input command and a pointer to the + * output buffer for putting in the results. + * + * For EFI firmwares, this can make use of the EFI TPM driver as + * follows (based on page 16, of TCG EFI Protocol Specs Version 1.20 + * availaible from the TCG website): + * + * EFI_STATUS status; + * status = TcgProtocol->EFI_TCG_PASS_THROUGH_TO_TPM( + * TpmCommandSize(request), + * request, + * max_length, + * response); + * // Error checking depending on the value of the status above + */ #ifndef NDEBUG - int tag, response_tag; + int tag, response_tag; #endif - VbError_t result; + VbError_t result; - struct timeval before, after; - gettimeofday(&before, NULL); - result = TpmExecute(request, request_length, response, response_length); - if (result != VBERROR_SUCCESS) - return result; - gettimeofday(&after, NULL); + struct timeval before, after; + gettimeofday(&before, NULL); + result = TpmExecute(request, request_length, response, response_length); + if (result != VBERROR_SUCCESS) + return result; + gettimeofday(&after, NULL); #ifdef VBOOT_DEBUG - { - int x = request_length; - int y = *response_length; - VBDEBUG(("request (%d bytes): ", x)); - PrintBytes(request, 10); - PrintBytes(request + 10, x - 10); - VBDEBUG(("response (%d bytes): ", y)); - PrintBytes(response, 10); - PrintBytes(response + 10, y - 10); - VBDEBUG(("execution time: %dms\n", - (int) ((after.tv_sec - before.tv_sec) * 1000 + - (after.tv_usec - before.tv_usec) / 1000))); - } + { + int x = request_length; + int y = *response_length; + VBDEBUG(("request (%d bytes): ", x)); + PrintBytes(request, 10); + PrintBytes(request + 10, x - 10); + VBDEBUG(("response (%d bytes): ", y)); + PrintBytes(response, 10); + PrintBytes(response + 10, y - 10); + VBDEBUG(("execution time: %dms\n", + (int) ((after.tv_sec - before.tv_sec) * 1000 + + (after.tv_usec - before.tv_usec) / 1000))); + } #endif #ifndef NDEBUG - /* sanity checks */ - tag = TpmTag(request); - response_tag = TpmTag(response); - assert( - (tag == TPM_TAG_RQU_COMMAND && - response_tag == TPM_TAG_RSP_COMMAND) || - (tag == TPM_TAG_RQU_AUTH1_COMMAND && - response_tag == TPM_TAG_RSP_AUTH1_COMMAND) || - (tag == TPM_TAG_RQU_AUTH2_COMMAND && - response_tag == TPM_TAG_RSP_AUTH2_COMMAND)); - assert(*response_length == TpmResponseSize(response)); + /* sanity checks */ + tag = TpmTag(request); + response_tag = TpmTag(response); + assert( + (tag == TPM_TAG_RQU_COMMAND && + response_tag == TPM_TAG_RSP_COMMAND) || + (tag == TPM_TAG_RQU_AUTH1_COMMAND && + response_tag == TPM_TAG_RSP_AUTH1_COMMAND) || + (tag == TPM_TAG_RQU_AUTH2_COMMAND && + response_tag == TPM_TAG_RSP_AUTH2_COMMAND)); + assert(*response_length == TpmResponseSize(response)); #endif - return VBERROR_SUCCESS; + return VBERROR_SUCCESS; } |