summaryrefslogtreecommitdiff
path: root/firmware/stub/tpm_lite_stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/stub/tpm_lite_stub.c')
-rw-r--r--firmware/stub/tpm_lite_stub.c332
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;
}