Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Unified Diff: firmware/stub/tpm_lite_stub.c

Issue 2919010: Add tpm lite to vboot reference (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « firmware/stub/tlcl.c ('k') | firmware/version.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: firmware/stub/tpm_lite_stub.c
diff --git a/firmware/stub/tpm_lite_stub.c b/firmware/stub/tpm_lite_stub.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee1cbf13664c1d7b2e9d1b353cd3fca65f0d7b65
--- /dev/null
+++ b/firmware/stub/tpm_lite_stub.c
@@ -0,0 +1,178 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Stub implementations of utility functions which call their linux-specific
+ * equivalents.
+ */
+
+#define _STUB_IMPLEMENTATION_
+#include "tlcl.h"
+#include "tlcl_internal.h"
+#include "utility.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <tss/tcs.h>
+#include "tpmextras.h"
+#define TPM_DEVICE_PATH "/dev/tpm0"
+
+/* TODO: these functions should pass errors back rather than returning void */
+/* TODO: if the only callers to these are just wrappers, should just
+ * remove the wrappers and call us directly. */
+
+
+/* The file descriptor for the TPM device.
+ */
+static int tpm_fd = -1;
+
+
+/* Print |n| bytes from array |a|, with newlines.
+ */
+POSSIBLY_UNUSED static void PrintBytes(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 void 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) {
+ error("invalid command length %d\n", in_len);
+ } else if (tpm_fd < 0) {
+ error("the TPM device was not opened. Forgot to call TlclLibInit?\n");
+ } else {
+ int n = write(tpm_fd, in, in_len);
+ if (n != in_len) {
+ error("write failure to TPM device: %s\n", strerror(errno));
+ }
+ n = read(tpm_fd, response, sizeof(response));
+ if (n == 0) {
+ error("null read from TPM device\n");
+ } else if (n < 0) {
+ error("read failure from TPM device: %s\n", strerror(errno));
+ } else {
+ if (n > *pout_len) {
+ error("TPM response too long for output buffer\n");
+ } else {
+ *pout_len = n;
+ Memcpy(out, response, n);
+ }
+ }
+ }
+}
+
+
+/* Gets the tag field of a TPM command.
+ */
+POSSIBLY_UNUSED static INLINE int TpmTag(uint8_t* buffer) {
+ uint16_t tag;
+ FromTpmUint16(buffer, &tag);
+ return (int) tag;
+}
+
+
+/* Gets the size field of a TPM command.
+ */
+POSSIBLY_UNUSED static INLINE int TpmResponseSize(const uint8_t* buffer) {
+ uint32_t size;
+ FromTpmUint32(buffer + sizeof(uint16_t), &size);
+ return (int) size;
+}
+
+
+void TlclStubInit(void) {
+ TlclOpenDevice();
+}
+
+
+void TlclCloseDevice(void) {
+ close(tpm_fd);
+ tpm_fd = -1;
+}
+
+
+void TlclOpenDevice(void) {
+ if (tpm_fd >= 0)
+ return; /* Already open */
+
+ tpm_fd = open(TPM_DEVICE_PATH, O_RDWR);
+ if (tpm_fd < 0) {
+ error("cannot open TPM device %s: %s\n", TPM_DEVICE_PATH, strerror(errno));
+ }
+}
+
+
+void TlclStubSendReceive(uint8_t* request, int request_length,
+ uint8_t* response, int max_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
+ */
+ uint32_t response_length = max_length;
+ int tag, response_tag;
+
+ struct timeval before, after;
+ gettimeofday(&before, NULL);
+ TpmExecute(request, request_length, response, &response_length);
+ 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)));
+ }
+#endif
+
+ /* 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));
+}
« no previous file with comments | « firmware/stub/tlcl.c ('k') | firmware/version.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698