summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/i2c/tpm/Makefile.inc1
-rw-r--r--src/include/antirollback.h138
-rw-r--r--src/include/tpm_lite/tlcl.h116
-rw-r--r--src/lib/Makefile.inc1
-rw-r--r--src/lib/tlcl.c592
-rw-r--r--src/lib/tlcl_internal.h34
-rw-r--r--src/soc/nvidia/tegra124/Makefile.inc3
-rw-r--r--src/soc/nvidia/tegra124/bootblock.c81
-rw-r--r--src/vendorcode/google/chromeos/Makefile.inc1
-rw-r--r--src/vendorcode/google/chromeos/antirollback.c602
-rw-r--r--src/vendorcode/google/chromeos/vboot_main.c81
11 files changed, 554 insertions, 1096 deletions
diff --git a/src/drivers/i2c/tpm/Makefile.inc b/src/drivers/i2c/tpm/Makefile.inc
index e06097f774..55c01def17 100644
--- a/src/drivers/i2c/tpm/Makefile.inc
+++ b/src/drivers/i2c/tpm/Makefile.inc
@@ -1,2 +1,3 @@
ramstage-$(CONFIG_I2C_TPM) += tis.c tpm.c
romstage-$(CONFIG_I2C_TPM) += tis.c tpm.c
+verstage-$(CONFIG_I2C_TPM) += tis.c tpm.c \ No newline at end of file
diff --git a/src/include/antirollback.h b/src/include/antirollback.h
index dd0de32aef..0473e2446c 100644
--- a/src/include/antirollback.h
+++ b/src/include/antirollback.h
@@ -6,133 +6,39 @@
* stored in the TPM NVRAM.
*/
-#ifndef VBOOT_REFERENCE_ROLLBACK_INDEX_H_
-#define VBOOT_REFERENCE_ROLLBACK_INDEX_H_
+#ifndef ANTIROLLBACK_H_
+#define ANTIROLLBACK_H_
-#include "sysincludes.h"
-#include "tss_constants.h"
+#include "2sysincludes.h"
+#include <2api.h>
+#include "tpm_lite/tss_constants.h"
/* TPM NVRAM location indices. */
#define FIRMWARE_NV_INDEX 0x1007
-#define KERNEL_NV_INDEX 0x1008
-/* This is just an opaque space for backup purposes */
-#define BACKUP_NV_INDEX 0x1009
-#define BACKUP_NV_SIZE 16
-
/* Structure definitions for TPM spaces */
-/* Kernel space - KERNEL_NV_INDEX, locked with physical presence. */
-#define ROLLBACK_SPACE_KERNEL_VERSION 2
-#define ROLLBACK_SPACE_KERNEL_UID 0x4752574C /* 'GRWL' */
-
-typedef struct RollbackSpaceKernel {
- /* Struct version, for backwards compatibility */
- uint8_t struct_version;
- /* Unique ID to detect space redefinition */
- uint32_t uid;
- /* Kernel versions */
- uint32_t kernel_versions;
- /* Reserved for future expansion */
- uint8_t reserved[3];
- /* Checksum (v2 and later only) */
- uint8_t crc8;
-} __attribute__((packed)) RollbackSpaceKernel;
-
/* Flags for firmware space */
+
/*
* Last boot was developer mode. TPM ownership is cleared when transitioning
* to/from developer mode.
*/
#define FLAG_LAST_BOOT_DEVELOPER 0x01
-/*
- * Some systems may not have a dedicated dev-mode switch, but enter and leave
- * dev-mode through some recovery-mode magic keypresses. For those systems, the
- * dev-mode "switch" state is in this bit (0=normal, 1=dev). To make it work, a
- * new flag is passed to VbInit(), indicating that the system lacks a physical
- * dev-mode switch. If a physical switch is present, this bit is ignored.
- */
-#define FLAG_VIRTUAL_DEV_MODE_ON 0x02
-
-/* Firmware space - FIRMWARE_NV_INDEX, locked with global lock. */
-#define ROLLBACK_SPACE_FIRMWARE_VERSION 2
-
-typedef struct RollbackSpaceFirmware {
- /* Struct version, for backwards compatibility */
- uint8_t struct_version;
- /* Flags (see FLAG_* above) */
- uint8_t flags;
- /* Firmware versions */
- uint32_t fw_versions;
- /* Reserved for future expansion */
- uint8_t reserved[3];
- /* Checksum (v2 and later only) */
- uint8_t crc8;
-} __attribute__((packed)) RollbackSpaceFirmware;
-
/* All functions return TPM_SUCCESS (zero) if successful, non-zero if error */
-/*
- * These functions are called from VbInit(). They cannot use global
- * variables.
- */
-
-uint32_t RollbackS3Resume(void);
-
-/*
- * These functions are callable from VbSelectFirmware(). They cannot use
- * global variables.
- */
-
-/**
- * This must be called.
- */
-uint32_t RollbackFirmwareSetup(int is_hw_dev,
- int disable_dev_request,
- int clear_tpm_owner_request,
- /* two outputs on success */
- int *is_virt_dev, uint32_t *tpm_version);
+uint32_t antirollback_read_space_firmware(struct vb2_context *ctx);
/**
* Write may be called if the versions change.
*/
-uint32_t RollbackFirmwareWrite(uint32_t version);
+uint32_t antirollback_write_space_firmware(struct vb2_context *ctx);
/**
* Lock must be called.
*/
-uint32_t RollbackFirmwareLock(void);
-
-/*
- * These functions are callable from VbSelectAndLoadKernel(). They may use
- * global variables.
- */
-
-/**
- * Read stored kernel version.
- */
-uint32_t RollbackKernelRead(uint32_t *version);
-
-/**
- * Write stored kernel version.
- */
-uint32_t RollbackKernelWrite(uint32_t version);
-
-/**
- * Read backup data.
- */
-uint32_t RollbackBackupRead(uint8_t *raw);
-
-/**
- * Write backup data.
- */
-uint32_t RollbackBackupWrite(uint8_t *raw);
-
-/**
- * Lock must be called. Internally, it's ignored in recovery mode.
- */
-uint32_t RollbackKernelLock(int recovery_mode);
+uint32_t antirollback_lock_space_firmware(void);
/****************************************************************************/
@@ -144,23 +50,23 @@ uint32_t RollbackKernelLock(int recovery_mode);
/**
* Issue a TPM_Clear and reenable/reactivate the TPM.
*/
-uint32_t TPMClearAndReenable(void);
+uint32_t tpm_clear_and_reenable(void);
/**
- * Like TlclWrite(), but checks for write errors due to hitting the 64-write
+ * Like tlcl_write(), but checks for write errors due to hitting the 64-write
* limit and clears the TPM when that happens. This can only happen when the
* TPM is unowned, so it is OK to clear it (and we really have no choice).
* This is not expected to happen frequently, but it could happen.
*/
-uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length);
+uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
/**
- * Similarly to SafeWrite(), this ensures we don't fail a DefineSpace because
+ * Similarly to safe_write(), this ensures we don't fail a DefineSpace because
* we hit the TPM write limit. This is even less likely to happen than with
* writes because we only define spaces once at initialization, but we'd rather
* be paranoid about this.
*/
-uint32_t SafeDefineSpace(uint32_t index, uint32_t perm, uint32_t size);
+uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size);
/**
* Perform one-time initializations.
@@ -169,19 +75,11 @@ uint32_t SafeDefineSpace(uint32_t index, uint32_t perm, uint32_t size);
* nvLocked bit and ensures the physical presence command is enabled and
* locked.
*/
-uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf,
- RollbackSpaceKernel *rsk);
-
-/**
- * Start the TPM and establish the root of trust for the anti-rollback
- * mechanism.
- */
-uint32_t SetupTPM(int developer_mode, int disable_dev_request,
- int clear_tpm_owner_request, RollbackSpaceFirmware *rsf);
+uint32_t factory_initialize_tpm(struct vb2_context *ctx);
/**
- * Utility function to turn the virtual dev-mode flag on or off. 0=off, 1=on.
+ * Start the TPM and establish the root of trust for the antirollback mechanism.
*/
-uint32_t SetVirtualDevMode(int val);
+uint32_t setup_tpm(struct vb2_context *ctx);
-#endif /* VBOOT_REFERENCE_ROLLBACK_INDEX_H_ */
+#endif /* ANTIROLLBACK_H_ */
diff --git a/src/include/tpm_lite/tlcl.h b/src/include/tpm_lite/tlcl.h
index 5373120066..77245922c9 100644
--- a/src/include/tpm_lite/tlcl.h
+++ b/src/include/tpm_lite/tlcl.h
@@ -21,45 +21,27 @@
/**
* Call this first. Returns 0 if success, nonzero if error.
*/
-uint32_t TlclLibInit(void);
-
-/**
- * Call this on shutdown. Returns 0 if success, nonzero if error.
- */
-uint32_t TlclLibClose(void);
-
-/* Low-level operations */
+uint32_t tlcl_lib_init(void);
/**
* Perform a raw TPM request/response transaction.
*/
-uint32_t TlclSendReceive(const uint8_t *request, uint8_t *response,
+uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
int max_length);
-/**
- * Return the size of a TPM request or response packet.
- */
-int TlclPacketSize(const uint8_t *packet);
-
/* Commands */
/**
* Send a TPM_Startup(ST_CLEAR). The TPM error code is returned (0 for
* success).
*/
-uint32_t TlclStartup(void);
-
-/**
- * Save the TPM state. Normally done by the kernel before a suspend, included
- * here for tests. The TPM error code is returned (0 for success).
- */
-uint32_t TlclSaveState(void);
+uint32_t tlcl_startup(void);
/**
* Resume by sending a TPM_Startup(ST_STATE). The TPM error code is returned
* (0 for success).
*/
-uint32_t TlclResume(void);
+uint32_t tlcl_resume(void);
/**
* Run the self test.
@@ -67,143 +49,89 @@ uint32_t TlclResume(void);
* Note---this is synchronous. To run this in parallel with other firmware,
* use ContinueSelfTest(). The TPM error code is returned.
*/
-uint32_t TlclSelfTestFull(void);
+uint32_t tlcl_self_test_full(void);
/**
* Run the self test in the background.
*/
-uint32_t TlclContinueSelfTest(void);
+uint32_t tlcl_continue_self_test(void);
/**
* Define a space with permission [perm]. [index] is the index for the space,
* [size] the usable data size. The TPM error code is returned.
*/
-uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size);
+uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size);
/**
* Write [length] bytes of [data] to space at [index]. The TPM error code is
* returned.
*/
-uint32_t TlclWrite(uint32_t index, const void *data, uint32_t length);
+uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length);
/**
* Read [length] bytes from space at [index] into [data]. The TPM error code
* is returned.
*/
-uint32_t TlclRead(uint32_t index, void *data, uint32_t length);
-
-/**
- * Read PCR at [index] into [data]. [length] must be TPM_PCR_DIGEST or
- * larger. The TPM error code is returned.
- */
-uint32_t TlclPCRRead(uint32_t index, void *data, uint32_t length);
-
-/**
- * Write-lock space at [index]. The TPM error code is returned.
- */
-uint32_t TlclWriteLock(uint32_t index);
-
-/**
- * Read-lock space at [index]. The TPM error code is returned.
- */
-uint32_t TlclReadLock(uint32_t index);
+uint32_t tlcl_read(uint32_t index, void *data, uint32_t length);
/**
* Assert physical presence in software. The TPM error code is returned.
*/
-uint32_t TlclAssertPhysicalPresence(void);
+uint32_t tlcl_assert_physical_presence(void);
/**
* Enable the physical presence command. The TPM error code is returned.
*/
-uint32_t TlclPhysicalPresenceCMDEnable(void);
+uint32_t tlcl_physical_presence_cmd_enable(void);
/**
* Finalize the physical presence settings: sofware PP is enabled, hardware PP
* is disabled, and the lifetime lock is set. The TPM error code is returned.
*/
-uint32_t TlclFinalizePhysicalPresence(void);
-
-uint32_t TlclAssertPhysicalPresenceResult(void);
-
-/**
- * Turn off physical presence and locks it off until next reboot. The TPM
- * error code is returned.
- */
-uint32_t TlclLockPhysicalPresence(void);
+uint32_t tlcl_finalize_physical_presence(void);
/**
* Set the nvLocked bit. The TPM error code is returned.
*/
-uint32_t TlclSetNvLocked(void);
-
-/**
- * Return 1 if the TPM is owned, 0 otherwise.
- */
-int TlclIsOwned(void);
+uint32_t tlcl_set_nv_locked(void);
/**
* Issue a ForceClear. The TPM error code is returned.
*/
-uint32_t TlclForceClear(void);
+uint32_t tlcl_force_clear(void);
/**
* Issue a PhysicalEnable. The TPM error code is returned.
*/
-uint32_t TlclSetEnable(void);
-
-/**
- * Issue a PhysicalDisable. The TPM error code is returned.
- */
-uint32_t TlclClearEnable(void);
+uint32_t tlcl_set_enable(void);
/**
* Issue a SetDeactivated. Pass 0 to activate. Returns result code.
*/
-uint32_t TlclSetDeactivated(uint8_t flag);
+uint32_t tlcl_set_deactivated(uint8_t flag);
/**
* Get flags of interest. Pointers for flags you aren't interested in may
* be NULL. The TPM error code is returned.
*/
-uint32_t TlclGetFlags(uint8_t *disable, uint8_t *deactivated,
- uint8_t *nvlocked);
+uint32_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated,
+ uint8_t *nvlocked);
/**
* Set the bGlobalLock flag, which only a reboot can clear. The TPM error
* code is returned.
*/
-uint32_t TlclSetGlobalLock(void);
+uint32_t tlcl_set_global_lock(void);
/**
* Perform a TPM_Extend.
*/
-uint32_t TlclExtend(int pcr_num, const uint8_t *in_digest, uint8_t *out_digest);
-
-/**
- * Get the permission bits for the NVRAM space with |index|.
- */
-uint32_t TlclGetPermissions(uint32_t index, uint32_t *permissions);
+uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
+ uint8_t *out_digest);
/**
* Get the entire set of permanent flags.
*/
-uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS *pflags);
-
-/**
- * Get the entire set of volatile (ST_CLEAR) flags.
- */
-uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS *pflags);
-
-/**
- * Get the ownership flag. The TPM error code is returned.
- */
-uint32_t TlclGetOwnership(uint8_t *owned);
-
-/**
- * Request [length] bytes from TPM RNG to be stored in [data]. Actual number of
- * bytes read is stored in [size]. The TPM error code is returned.
- */
-uint32_t TlclGetRandom(uint8_t *data, uint32_t length, uint32_t *size);
+uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags);
#endif /* TPM_LITE_TLCL_H_ */
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 472bd8d8cc..beb3abe168 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -33,7 +33,6 @@ verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
verstage-y += tlcl.c
verstage-$(CONFIG_GENERIC_UDELAY) += timer.c
-
romstage-y += memchr.c
romstage-y += memcmp.c
$(foreach arch,$(ARCH_SUPPORTED),\
diff --git a/src/lib/tlcl.c b/src/lib/tlcl.c
index bf2d27f99c..3cfc40841a 100644
--- a/src/lib/tlcl.c
+++ b/src/lib/tlcl.c
@@ -14,453 +14,313 @@
* time.
*/
-#include "sysincludes.h"
-
-#include "tlcl.h"
+#include <2api.h>
+#include <2sysincludes.h>
+#include <assert.h>
+#include <tpm_lite/tlcl.h>
+#include <tpm.h>
#include "tlcl_internal.h"
#include "tlcl_structures.h"
-#include "utility.h"
-#include "vboot_api.h"
#ifdef FOR_TEST
-/* Allow unit testing implementation of TlclSendReceive() */
-#undef CHROMEOS_ENVIRONMENT
+#include <stdio.h>
+#define VBDEBUG(format, args...) printf(format, ## args)
+#else
+#include <console/console.h>
+#define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args)
#endif
+static int tpm_send_receive(const uint8_t *request,
+ uint32_t request_length,
+ uint8_t *response,
+ uint32_t *response_length)
+{
+ size_t len = *response_length;
+ if (tis_sendrecv(request, request_length, response, &len))
+ return VB2_ERROR_UNKNOWN;
+ /* check 64->32bit overflow and (re)check response buffer overflow */
+ if (len > *response_length)
+ return VB2_ERROR_UNKNOWN;
+ *response_length = len;
+ return VB2_SUCCESS;
+}
+
/* Sets the size field of a TPM command. */
-static inline void SetTpmCommandSize(uint8_t* buffer, uint32_t size) {
- ToTpmUint32(buffer + sizeof(uint16_t), size);
+static inline void set_tpm_command_size(uint8_t* buffer, uint32_t size) {
+ to_tpm_uint32(buffer + sizeof(uint16_t), size);
}
/* Gets the size field of a TPM command. */
__attribute__((unused))
-static inline int TpmCommandSize(const uint8_t* buffer) {
- uint32_t size;
- FromTpmUint32(buffer + sizeof(uint16_t), &size);
- return (int) size;
-}
-
-/* Gets the size field of a TPM request or response. */
-int TlclPacketSize(const uint8_t* packet) {
- return TpmCommandSize(packet);
+static inline int tpm_command_size(const uint8_t* buffer) {
+ uint32_t size;
+ from_tpm_uint32(buffer + sizeof(uint16_t), &size);
+ return (int) size;
}
/* Gets the code field of a TPM command. */
-static inline int TpmCommandCode(const uint8_t* buffer) {
- uint32_t code;
- FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
- return code;
+static inline int tpm_command_code(const uint8_t* buffer) {
+ uint32_t code;
+ from_tpm_uint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
+ return code;
}
/* Gets the return code field of a TPM result. */
-static inline int TpmReturnCode(const uint8_t* buffer) {
- return TpmCommandCode(buffer);
+static inline int tpm_return_code(const uint8_t* buffer) {
+ return tpm_command_code(buffer);
}
/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or
* DOING_SELFTEST errors are returned.
*/
-static uint32_t TlclSendReceiveNoRetry(const uint8_t* request,
- uint8_t* response, int max_length) {
-
- uint32_t response_length = max_length;
- uint32_t result;
+static uint32_t tlcl_send_receive_no_retry(const uint8_t* request,
+ uint8_t* response, int max_length) {
+ uint32_t response_length = max_length;
+ uint32_t result;
-#ifdef EXTRA_LOGGING
- VBDEBUG(("TPM: command: %x%x %x%x%x%x %x%x%x%x\n",
- request[0], request[1],
- request[2], request[3], request[4], request[5],
- request[6], request[7], request[8], request[9]));
-#endif
+ result = tpm_send_receive(request, tpm_command_size(request),
+ response, &response_length);
+ if (0 != result) {
+ /* Communication with TPM failed, so response is garbage */
+ VBDEBUG("TPM: command 0x%x send/receive failed: 0x%x\n",
+ tpm_command_code(request), result);
+ return result;
+ }
+ /* Otherwise, use the result code from the response */
+ result = tpm_return_code(response);
- result = VbExTpmSendReceive(request, TpmCommandSize(request),
- response, &response_length);
- if (0 != result) {
- /* Communication with TPM failed, so response is garbage */
- VBDEBUG(("TPM: command 0x%x send/receive failed: 0x%x\n",
- TpmCommandCode(request), result));
- return result;
- }
- /* Otherwise, use the result code from the response */
- result = TpmReturnCode(response);
-
- /* TODO: add paranoia about returned response_length vs. max_length
- * (and possibly expected length from the response header). See
- * crosbug.com/17017 */
-
-#ifdef EXTRA_LOGGING
- VBDEBUG(("TPM: response: %x%x %x%x%x%x %x%x%x%x\n",
- response[0], response[1],
- response[2], response[3], response[4], response[5],
- response[6], response[7], response[8], response[9]));
-#endif
+ /* TODO: add paranoia about returned response_length vs. max_length
+ * (and possibly expected length from the response header). See
+ * crosbug.com/17017 */
- VBDEBUG(("TPM: command 0x%x returned 0x%x\n",
- TpmCommandCode(request), result));
+ VBDEBUG("TPM: command 0x%x returned 0x%x\n",
+ tpm_command_code(request), result);
- return result;
+return result;
}
/* Sends a TPM command and gets a response. Returns 0 if success or the TPM
- * error code if error. In the firmware, waits for the self test to complete
- * if needed. In the host, reports the first error without retries. */
-uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response,
- int max_length) {
- uint32_t result = TlclSendReceiveNoRetry(request, response, max_length);
- /* When compiling for the firmware, hide command failures due to the self
- * test not having run or completed. */
-#ifndef CHROMEOS_ENVIRONMENT
- /* If the command fails because the self test has not completed, try it
- * again after attempting to ensure that the self test has completed. */
- if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) {
- result = TlclContinueSelfTest();
- if (result != TPM_SUCCESS) {
- return result;
- }
+ * error code if error. Waits for the self test to complete if needed. */
+uint32_t tlcl_send_receive(const uint8_t* request, uint8_t* response,
+ int max_length) {
+ uint32_t result = tlcl_send_receive_no_retry(request, response,
+ max_length);
+ /* If the command fails because the self test has not completed, try it
+ * again after attempting to ensure that the self test has completed. */
+ if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) {
+ result = tlcl_continue_self_test();
+ if (result != TPM_SUCCESS)
+ return result;
#if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE)
- /* Retry only once */
- result = TlclSendReceiveNoRetry(request, response, max_length);
+ /* Retry only once */
+ result = tlcl_send_receive_no_retry(request, response,
+ max_length);
#else
- /* This needs serious testing. The TPM specification says: "iii. The
- * caller MUST wait for the actions of TPM_ContinueSelfTest to complete
- * before reissuing the command C1." But, if ContinueSelfTest is
- * non-blocking, how do we know that the actions have completed other than
- * trying again? */
- do {
- result = TlclSendReceiveNoRetry(request, response, max_length);
- } while (result == TPM_E_DOING_SELFTEST);
+ /* This needs serious testing. The TPM specification says: "iii.
+ * The caller MUST wait for the actions of TPM_ContinueSelfTest
+ * to complete before reissuing the command C1." But, if
+ * ContinueSelfTest is non-blocking, how do we know that the
+ * actions have completed other than trying again? */
+ do {
+ result = tlcl_send_receive_no_retry(request, response,
+ max_length);
+ } while (result == TPM_E_DOING_SELFTEST);
#endif
- }
-#endif /* ! defined(CHROMEOS_ENVIRONMENT) */
- return result;
+ }
+ return result;
}
/* Sends a command and returns the error code. */
-static uint32_t Send(const uint8_t* command) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- return TlclSendReceive(command, response, sizeof(response));
+static uint32_t send(const uint8_t* command) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ return tlcl_send_receive(command, response, sizeof(response));
}
/* Exported functions. */
-uint32_t TlclLibInit(void) {
- return VbExTpmInit();
-}
-
-uint32_t TlclLibClose(void) {
- return VbExTpmClose();
-}
-
-uint32_t TlclStartup(void) {
- VBDEBUG(("TPM: Startup\n"));
- return Send(tpm_startup_cmd.buffer);
-}
-
-uint32_t TlclSaveState(void) {
- VBDEBUG(("TPM: SaveState\n"));
- return Send(tpm_savestate_cmd.buffer);
-}
-
-uint32_t TlclResume(void) {
- VBDEBUG(("TPM: Resume\n"));
- return Send(tpm_resume_cmd.buffer);
+uint32_t tlcl_lib_init(void) {
+ if (tis_init())
+ return VB2_ERROR_UNKNOWN;
+ if (tis_open())
+ return VB2_ERROR_UNKNOWN;
+ return VB2_SUCCESS;
}
-uint32_t TlclSelfTestFull(void) {
- VBDEBUG(("TPM: Self test full\n"));
- return Send(tpm_selftestfull_cmd.buffer);
+uint32_t tlcl_startup(void) {
+ VBDEBUG("TPM: Startup\n");
+ return send(tpm_startup_cmd.buffer);
}
-uint32_t TlclContinueSelfTest(void) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- VBDEBUG(("TPM: Continue self test\n"));
- /* Call the No Retry version of SendReceive to avoid recursion. */
- return TlclSendReceiveNoRetry(tpm_continueselftest_cmd.buffer,
- response, sizeof(response));
+uint32_t tlcl_resume(void) {
+ VBDEBUG("TPM: Resume\n");
+ return send(tpm_resume_cmd.buffer);
}
-uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) {
- struct s_tpm_nv_definespace_cmd cmd;
- VBDEBUG(("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size));
- Memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd));
- ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.index, index);
- ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm);
- ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.size, size);
- return Send(cmd.buffer);
+uint32_t tlcl_self_test_full(void)
+{
+ VBDEBUG("TPM: Self test full\n");
+ return send(tpm_selftestfull_cmd.buffer);
}
-uint32_t TlclWrite(uint32_t index, const void* data, uint32_t length) {
- struct s_tpm_nv_write_cmd cmd;
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- const int total_length =
- kTpmRequestHeaderLength + kWriteInfoLength + length;
-
- VBDEBUG(("TPM: TlclWrite(0x%x, %d)\n", index, length));
- Memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd));
- VbAssert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
- SetTpmCommandSize(cmd.buffer, total_length);
-
- ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.index, index);
- ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.length, length);
- Memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length);
-
- return TlclSendReceive(cmd.buffer, response, sizeof(response));
+uint32_t tlcl_continue_self_test(void)
+{
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ VBDEBUG("TPM: Continue self test\n");
+ /* Call the No Retry version of SendReceive to avoid recursion. */
+ return tlcl_send_receive_no_retry(tpm_continueselftest_cmd.buffer,
+ response, sizeof(response));
}
-uint32_t TlclRead(uint32_t index, void* data, uint32_t length) {
- struct s_tpm_nv_read_cmd cmd;
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t result_length;
- uint32_t result;
-
- VBDEBUG(("TPM: TlclRead(0x%x, %d)\n", index, length));
- Memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd));
- ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.index, index);
- ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.length, length);
-
- result = TlclSendReceive(cmd.buffer, response, sizeof(response));
- if (result == TPM_SUCCESS && length > 0) {
- uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
- FromTpmUint32(nv_read_cursor, &result_length);
- nv_read_cursor += sizeof(uint32_t);
- Memcpy(data, nv_read_cursor, result_length);
- }
-
- return result;
+uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+ struct s_tpm_nv_definespace_cmd cmd;
+ VBDEBUG("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size);
+ memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd));
+ to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.index, index);
+ to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm);
+ to_tpm_uint32(cmd.buffer + tpm_nv_definespace_cmd.size, size);
+ return send(cmd.buffer);
}
-uint32_t TlclPCRRead(uint32_t index, void* data, uint32_t length) {
- struct s_tpm_pcr_read_cmd cmd;
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t result;
-
- VBDEBUG(("TPM: TlclPCRRead(0x%x, %d)\n", index, length));
- if (length < kPcrDigestLength) {
- return TPM_E_IOERROR;
- }
- Memcpy(&cmd, &tpm_pcr_read_cmd, sizeof(cmd));
- ToTpmUint32(cmd.buffer + tpm_pcr_read_cmd.pcrNum, index);
-
- result = TlclSendReceive(cmd.buffer, response, sizeof(response));
- if (result == TPM_SUCCESS) {
- uint8_t* pcr_read_cursor = response + kTpmResponseHeaderLength;
- Memcpy(data, pcr_read_cursor, kPcrDigestLength);
- }
-
- return result;
-}
+uint32_t tlcl_write(uint32_t index, const void* data, uint32_t length)
+{
+ struct s_tpm_nv_write_cmd cmd;
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ const int total_length =
+ kTpmRequestHeaderLength + kWriteInfoLength + length;
-uint32_t TlclWriteLock(uint32_t index) {
- VBDEBUG(("TPM: Write lock 0x%x\n", index));
- return TlclWrite(index, NULL, 0);
-}
+ VBDEBUG("TPM: tlcl_write(0x%x, %d)\n", index, length);
+ memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd));
+ assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ set_tpm_command_size(cmd.buffer, total_length);
-uint32_t TlclReadLock(uint32_t index) {
- VBDEBUG(("TPM: Read lock 0x%x\n", index));
- return TlclRead(index, NULL, 0);
-}
+ to_tpm_uint32(cmd.buffer + tpm_nv_write_cmd.index, index);
+ to_tpm_uint32(cmd.buffer + tpm_nv_write_cmd.length, length);
+ memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length);
-uint32_t TlclAssertPhysicalPresence(void) {
- VBDEBUG(("TPM: Asserting physical presence\n"));
- return Send(tpm_ppassert_cmd.buffer);
+ return tlcl_send_receive(cmd.buffer, response, sizeof(response));
}
-uint32_t TlclPhysicalPresenceCMDEnable(void) {
- VBDEBUG(("TPM: Enable the physical presence command\n"));
- return Send(tpm_ppenable_cmd.buffer);
-}
+uint32_t tlcl_read(uint32_t index, void* data, uint32_t length)
+{
+ struct s_tpm_nv_read_cmd cmd;
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint32_t result_length;
+ uint32_t result;
-uint32_t TlclFinalizePhysicalPresence(void) {
- VBDEBUG(("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n"));
- return Send(tpm_finalizepp_cmd.buffer);
-}
+ VBDEBUG("TPM: tlcl_read(0x%x, %d)\n", index, length);
+ memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd));
+ to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.index, index);
+ to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.length, length);
-uint32_t TlclAssertPhysicalPresenceResult(void) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response));
-}
+ result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+ if (result == TPM_SUCCESS && length > 0) {
+ uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
+ from_tpm_uint32(nv_read_cursor, &result_length);
+ nv_read_cursor += sizeof(uint32_t);
+ memcpy(data, nv_read_cursor, result_length);
+ }
-uint32_t TlclLockPhysicalPresence(void) {
- VBDEBUG(("TPM: Lock physical presence\n"));
- return Send(tpm_pplock_cmd.buffer);
+ return result;
}
-uint32_t TlclSetNvLocked(void) {
- VBDEBUG(("TPM: Set NV locked\n"));
- return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0);
-}
-
-int TlclIsOwned(void) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE];
- uint32_t result;
- result = TlclSendReceive(tpm_readpubek_cmd.buffer,
- response, sizeof(response));
- return (result != TPM_SUCCESS);
-}
-uint32_t TlclForceClear(void) {
- VBDEBUG(("TPM: Force clear\n"));
- return Send(tpm_forceclear_cmd.buffer);
+uint32_t tlcl_assert_physical_presence(void) {
+ VBDEBUG("TPM: Asserting physical presence\n");
+ return send(tpm_ppassert_cmd.buffer);
}
-uint32_t TlclSetEnable(void) {
- VBDEBUG(("TPM: Enabling TPM\n"));
- return Send(tpm_physicalenable_cmd.buffer);
+uint32_t tlcl_physical_presence_cmd_enable(void) {
+ VBDEBUG("TPM: Enable the physical presence command\n");
+ return send(tpm_ppenable_cmd.buffer);
}
-uint32_t TlclClearEnable(void) {
- VBDEBUG(("TPM: Disabling TPM\n"));
- return Send(tpm_physicaldisable_cmd.buffer);
+uint32_t tlcl_finalize_physical_presence(void) {
+ VBDEBUG("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n");
+ return send(tpm_finalizepp_cmd.buffer);
}
-uint32_t TlclSetDeactivated(uint8_t flag) {
- struct s_tpm_physicalsetdeactivated_cmd cmd;
- VBDEBUG(("TPM: SetDeactivated(%d)\n", flag));
- Memcpy(&cmd, &tpm_physicalsetdeactivated_cmd, sizeof(cmd));
- *(cmd.buffer + cmd.deactivated) = flag;
- return Send(cmd.buffer);
+uint32_t tlcl_set_nv_locked(void) {
+ VBDEBUG("TPM: Set NV locked\n");
+ return tlcl_define_space(TPM_NV_INDEX_LOCK, 0, 0);
}
-uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS* pflags) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t size;
- uint32_t result =
- TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response));
- if (result != TPM_SUCCESS)
- return result;
- FromTpmUint32(response + kTpmResponseHeaderLength, &size);
- /* TODO(crbug.com/379255): This fails. Find out why.
- * VbAssert(size == sizeof(TPM_PERMANENT_FLAGS));
- */
- Memcpy(pflags,
- response + kTpmResponseHeaderLength + sizeof(size),
- sizeof(TPM_PERMANENT_FLAGS));
- return result;
+uint32_t tlcl_force_clear(void) {
+ VBDEBUG("TPM: Force clear\n");
+ return send(tpm_forceclear_cmd.buffer);
}
-uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS* vflags) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t size;
- uint32_t result =
- TlclSendReceive(tpm_getstclearflags_cmd.buffer, response, sizeof(response));
- if (result != TPM_SUCCESS)
- return result;
- FromTpmUint32(response + kTpmResponseHeaderLength, &size);
- /* Ugly assertion, but the struct is padded up by one byte. */
- /* TODO(crbug.com/379255): This fails. Find out why.
- * VbAssert(size == 7 && sizeof(TPM_STCLEAR_FLAGS) - 1 == 7);
- */
- Memcpy(vflags,
- response + kTpmResponseHeaderLength + sizeof(size),
- sizeof(TPM_STCLEAR_FLAGS));
- return result;
+uint32_t tlcl_set_enable(void) {
+ VBDEBUG("TPM: Enabling TPM\n");
+ return send(tpm_physicalenable_cmd.buffer);
}
-uint32_t TlclGetFlags(uint8_t* disable,
- uint8_t* deactivated,
- uint8_t *nvlocked) {
- TPM_PERMANENT_FLAGS pflags;
- uint32_t result = TlclGetPermanentFlags(&pflags);
- if (result == TPM_SUCCESS) {
- if (disable)
- *disable = pflags.disable;
- if (deactivated)
- *deactivated = pflags.deactivated;
- if (nvlocked)
- *nvlocked = pflags.nvLocked;
- VBDEBUG(("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n",
- pflags.disable, pflags.deactivated, pflags.nvLocked));
- }
- return result;
+uint32_t tlcl_set_deactivated(uint8_t flag)
+{
+ struct s_tpm_physicalsetdeactivated_cmd cmd;
+ VBDEBUG("TPM: SetDeactivated(%d)\n", flag);
+ memcpy(&cmd, &tpm_physicalsetdeactivated_cmd, sizeof(cmd));
+ *(cmd.buffer + cmd.deactivated) = flag;
+ return send(cmd.buffer);
+}
+
+uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS* pflags)
+{
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint32_t size;
+ uint32_t result = tlcl_send_receive(tpm_getflags_cmd.buffer, response,
+ sizeof(response));
+ if (result != TPM_SUCCESS)
+ return result;
+ from_tpm_uint32(response + kTpmResponseHeaderLength, &size);
+ assert(size == sizeof(TPM_PERMANENT_FLAGS));
+ memcpy(pflags, response + kTpmResponseHeaderLength + sizeof(size),
+ sizeof(TPM_PERMANENT_FLAGS));
+ return result;
}
-uint32_t TlclSetGlobalLock(void) {
- uint32_t x;
- VBDEBUG(("TPM: Set global lock\n"));
- return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0);
+uint32_t tlcl_get_flags(uint8_t* disable, uint8_t* deactivated,
+ uint8_t *nvlocked)
+{
+ TPM_PERMANENT_FLAGS pflags;
+ uint32_t result = tlcl_get_permanent_flags(&pflags);
+ if (result == TPM_SUCCESS) {
+ if (disable)
+ *disable = pflags.disable;
+ if (deactivated)
+ *deactivated = pflags.deactivated;
+ if (nvlocked)
+ *nvlocked = pflags.nvLocked;
+ VBDEBUG("TPM: flags disable=%d, deactivated=%d, nvlocked=%d\n",
+ pflags.disable, pflags.deactivated, pflags.nvLocked);
+ }
+ return result;
}
-uint32_t TlclExtend(int pcr_num, const uint8_t* in_digest,
- uint8_t* out_digest) {
- struct s_tpm_extend_cmd cmd;
- uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength];
- uint32_t result;
-
- Memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd));
- ToTpmUint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num);
- Memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength);
+uint32_t tlcl_set_global_lock(void)
+{
+ uint32_t x;
+ VBDEBUG("TPM: Set global lock\n");
+ return tlcl_write(TPM_NV_INDEX0, (uint8_t*) &x, 0);
+}
- result = TlclSendReceive(cmd.buffer, response, sizeof(response));
- if (result != TPM_SUCCESS)
- return result;
+uint32_t tlcl_extend(int pcr_num, const uint8_t* in_digest,
+ uint8_t* out_digest)
+{
+ struct s_tpm_extend_cmd cmd;
+ uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength];
+ uint32_t result;
- Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength);
- return result;
-}
-
-uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) {
- struct s_tpm_getpermissions_cmd cmd;
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint8_t* nvdata;
- uint32_t result;
- uint32_t size;
-
- Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd));
- ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index);
- result = TlclSendReceive(cmd.buffer, response, sizeof(response));
- if (result != TPM_SUCCESS)
- return result;
-
- nvdata = response + kTpmResponseHeaderLength + sizeof(size);
- FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions);
- return result;
-}
+ memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd));
+ to_tpm_uint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num);
+ memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength);
-uint32_t TlclGetOwnership(uint8_t* owned) {
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t size;
- uint32_t result =
- TlclSendReceive(tpm_getownership_cmd.buffer, response, sizeof(response));
- if (result != TPM_SUCCESS)
- return result;
- FromTpmUint32(response + kTpmResponseHeaderLength, &size);
- /* TODO(crbug.com/379255): This fails. Find out why.
- * VbAssert(size == sizeof(*owned));
- */
- Memcpy(owned,
- response + kTpmResponseHeaderLength + sizeof(size),
- sizeof(*owned));
- return result;
-}
+ result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+ if (result != TPM_SUCCESS)
+ return result;
-uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size) {
- struct s_tpm_get_random_cmd cmd;
- uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
- uint32_t result;
-
- VBDEBUG(("TPM: TlclGetRandom(%d)\n", length));
- Memcpy(&cmd, &tpm_get_random_cmd, sizeof(cmd));
- ToTpmUint32(cmd.buffer + tpm_get_random_cmd.bytesRequested, length);
- /* There must be room in the response buffer for the bytes. */
- if (length > TPM_LARGE_ENOUGH_COMMAND_SIZE - kTpmResponseHeaderLength
- - sizeof(uint32_t)) {
- return TPM_E_IOERROR;
- }
-
- result = TlclSendReceive(cmd.buffer, response, sizeof(response));
- if (result == TPM_SUCCESS) {
- uint8_t* get_random_cursor;
- FromTpmUint32(response + kTpmResponseHeaderLength, size);
-
- /* There must be room in the target buffer for the bytes. */
- if (*size > length) {
- return TPM_E_RESPONSE_TOO_LARGE;
- }
- get_random_cursor = response + kTpmResponseHeaderLength
- + sizeof(uint32_t);
- Memcpy(data, get_random_cursor, *size);
- }
-
- return result;
+ memcpy(out_digest, response + kTpmResponseHeaderLength,
+ kPcrDigestLength);
+ return result;
}
diff --git a/src/lib/tlcl_internal.h b/src/lib/tlcl_internal.h
index 51fe6ef3f0..8261b0d0e1 100644
--- a/src/lib/tlcl_internal.h
+++ b/src/lib/tlcl_internal.h
@@ -18,44 +18,44 @@
/*
- * Conversion functions. ToTpmTYPE puts a value of type TYPE into a TPM
- * command buffer. FromTpmTYPE gets a value of type TYPE from a TPM command
+ * Conversion functions. to_tpm_TYPE puts a value of type TYPE into a TPM
+ * command buffer. from_tpm_TYPE gets a value of type TYPE from a TPM command
* buffer into a variable.
*/
__attribute__((unused))
-static inline void ToTpmUint32(uint8_t *buffer, uint32_t x) {
- buffer[0] = (uint8_t)(x >> 24);
- buffer[1] = (uint8_t)((x >> 16) & 0xff);
- buffer[2] = (uint8_t)((x >> 8) & 0xff);
- buffer[3] = (uint8_t)(x & 0xff);
+static inline void to_tpm_uint32(uint8_t *buffer, uint32_t x) {
+ buffer[0] = (uint8_t)(x >> 24);
+ buffer[1] = (uint8_t)((x >> 16) & 0xff);
+ buffer[2] = (uint8_t)((x >> 8) & 0xff);
+ buffer[3] = (uint8_t)(x & 0xff);
}
/*
* See comment for above function.
*/
__attribute__((unused))
-static inline void FromTpmUint32(const uint8_t *buffer, uint32_t *x) {
- *x = ((buffer[0] << 24) |
- (buffer[1] << 16) |
- (buffer[2] << 8) |
- buffer[3]);
+static inline void from_tpm_uint32(const uint8_t *buffer, uint32_t *x) {
+ *x = ((buffer[0] << 24) |
+ (buffer[1] << 16) |
+ (buffer[2] << 8) |
+ buffer[3]);
}
/*
* See comment for above function.
*/
__attribute__((unused))
-static inline void ToTpmUint16(uint8_t *buffer, uint16_t x) {
- buffer[0] = (uint8_t)(x >> 8);
- buffer[1] = (uint8_t)(x & 0xff);
+static inline void to_tpm_uint16(uint8_t *buffer, uint16_t x) {
+ buffer[0] = (uint8_t)(x >> 8);
+ buffer[1] = (uint8_t)(x & 0xff);
}
/*
* See comment for above function.
*/
__attribute__((unused))
-static inline void FromTpmUint16(const uint8_t *buffer, uint16_t *x) {
- *x = (buffer[0] << 8) | buffer[1];
+static inline void from_tpm_uint16(const uint8_t *buffer, uint16_t *x) {
+ *x = (buffer[0] << 8) | buffer[1];
}
#endif /* TPM_LITE_TLCL_INTERNAL_H_ */
diff --git a/src/soc/nvidia/tegra124/Makefile.inc b/src/soc/nvidia/tegra124/Makefile.inc
index 9ed7669aea..8966168a78 100644
--- a/src/soc/nvidia/tegra124/Makefile.inc
+++ b/src/soc/nvidia/tegra124/Makefile.inc
@@ -28,7 +28,10 @@ verstage-y += spi.c
verstage-y += timer.c
verstage-$(CONFIG_DRIVERS_UART) += uart.c
verstage-y += ../tegra/gpio.c
+verstage-y += ../tegra/i2c.c
verstage-y += ../tegra/pinmux.c
+verstage-y += clock.c
+verstage-y += i2c.c
romstage-y += cbfs.c
romstage-y += cbmem.c
diff --git a/src/soc/nvidia/tegra124/bootblock.c b/src/soc/nvidia/tegra124/bootblock.c
index aec914532e..22e7ba8557 100644
--- a/src/soc/nvidia/tegra124/bootblock.c
+++ b/src/soc/nvidia/tegra124/bootblock.c
@@ -18,6 +18,7 @@
*/
#include <assert.h>
+#include <arch/cache.h>
#include <arch/exception.h>
#include <bootblock_common.h>
#include <cbfs.h>
@@ -27,6 +28,78 @@
#include "pinmux.h"
#include "power.h"
#include "verstage.h"
+#include <soc/addressmap.h>
+#include <soc/nvidia/tegra/i2c.h>
+#include <soc/nvidia/tegra124/gpio.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
+
+static void setup_pinmux(void)
+{
+ // Write protect.
+ gpio_input_pullup(GPIO(R1));
+ // Recovery mode.
+ gpio_input_pullup(GPIO(Q7));
+ // Lid switch.
+ gpio_input_pullup(GPIO(R4));
+ // Power switch.
+ gpio_input_pullup(GPIO(Q0));
+ // Developer mode.
+ gpio_input_pullup(GPIO(Q6));
+ // EC in RW.
+ gpio_input_pullup(GPIO(U4));
+
+ // route PU4/5 to GMI to remove conflict w/PWM1/2.
+ pinmux_set_config(PINMUX_GPIO_PU4_INDEX, PINMUX_GPIO_PU4_FUNC_NOR);
+ pinmux_set_config(PINMUX_GPIO_PU5_INDEX, PINMUX_GPIO_PU5_FUNC_NOR);
+
+ // SOC and TPM reset GPIO, active low.
+ gpio_output(GPIO(I5), 1);
+
+ // SPI1 MOSI
+ pinmux_set_config(PINMUX_ULPI_CLK_INDEX, PINMUX_ULPI_CLK_FUNC_SPI1 |
+ PINMUX_PULL_NONE |
+ PINMUX_INPUT_ENABLE);
+ // SPI1 MISO
+ pinmux_set_config(PINMUX_ULPI_DIR_INDEX, PINMUX_ULPI_DIR_FUNC_SPI1 |
+ PINMUX_PULL_NONE |
+ PINMUX_INPUT_ENABLE);
+ // SPI1 SCLK
+ pinmux_set_config(PINMUX_ULPI_NXT_INDEX, PINMUX_ULPI_NXT_FUNC_SPI1 |
+ PINMUX_PULL_NONE |
+ PINMUX_INPUT_ENABLE);
+ // SPI1 CS0
+ pinmux_set_config(PINMUX_ULPI_STP_INDEX, PINMUX_ULPI_STP_FUNC_SPI1 |
+ PINMUX_PULL_NONE |
+ PINMUX_INPUT_ENABLE);
+
+ // I2C3 (cam) clock.
+ pinmux_set_config(PINMUX_CAM_I2C_SCL_INDEX,
+ PINMUX_CAM_I2C_SCL_FUNC_I2C3 | PINMUX_INPUT_ENABLE);
+ // I2C3 (cam) data.
+ pinmux_set_config(PINMUX_CAM_I2C_SDA_INDEX,
+ PINMUX_CAM_I2C_SDA_FUNC_I2C3 | PINMUX_INPUT_ENABLE);
+
+ // switch unused pin to GPIO
+ gpio_set_mode(GPIO(X3), GPIO_MODE_GPIO);
+ gpio_set_mode(GPIO(X4), GPIO_MODE_GPIO);
+ gpio_set_mode(GPIO(X5), GPIO_MODE_GPIO);
+ gpio_set_mode(GPIO(X6), GPIO_MODE_GPIO);
+ gpio_set_mode(GPIO(X7), GPIO_MODE_GPIO);
+ gpio_set_mode(GPIO(W3), GPIO_MODE_GPIO);
+}
+
+static void configure_ec_spi_bus(void)
+{
+ clock_configure_source(sbc1, CLK_M, 3000);
+}
+
+static void configure_tpm_i2c_bus(void)
+{
+ clock_configure_i2c_scl_freq(i2c3, PLLP, 400);
+
+ i2c_init(2);
+}
void main(void)
{
@@ -70,9 +143,13 @@ void main(void)
PINMUX_PWR_INT_N_FUNC_PMICINTR |
PINMUX_INPUT_ENABLE);
- if (IS_ENABLED(CONFIG_VBOOT2_VERIFY_FIRMWARE))
+ if (IS_ENABLED(CONFIG_VBOOT2_VERIFY_FIRMWARE)) {
+ clock_enable_clear_reset(0, CLK_H_SBC1, CLK_U_I2C3, 0, 0, 0);
+ setup_pinmux();
+ configure_ec_spi_bus();
+ configure_tpm_i2c_bus();
entry = (void *)verstage_vboot_main;
- else
+ } else
entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/romstage");
ASSERT(entry);
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index cb3d9a68b8..4438a92545 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -101,6 +101,7 @@ VERSTAGE_LIB = $(obj)/vendorcode/google/chromeos/verstage.a
INCLUDES += -I$(VB_SOURCE)/firmware/2lib/include
INCLUDES += -I$(VB_SOURCE)/firmware/include
verstage-y += vboot_main.c fmap.c chromeos.c
+verstage-y += antirollback.c vbnv_ec.c
VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
diff --git a/src/vendorcode/google/chromeos/antirollback.c b/src/vendorcode/google/chromeos/antirollback.c
index 306e90329b..020a06abb2 100644
--- a/src/vendorcode/google/chromeos/antirollback.c
+++ b/src/vendorcode/google/chromeos/antirollback.c
@@ -6,261 +6,118 @@
* stored in the TPM NVRAM.
*/
-#include "sysincludes.h"
-
-#include "crc8.h"
-#include "rollback_index.h"
-#include "tlcl.h"
-#include "tss_constants.h"
-#include "utility.h"
-#include "vboot_api.h"
+#include <2api.h>
+#include <2sysincludes.h>
+#include <antirollback.h>
+#include <tpm_lite/tlcl.h>
+#include <tpm_lite/tss_constants.h>
#ifndef offsetof
#define offsetof(A,B) __builtin_offsetof(A,B)
#endif
-/*
- * Provide protoypes for functions not in the header file. These prototypes
- * fix -Wmissing-prototypes warnings.
- */
-uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf);
-uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf);
-uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk);
-uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk);
-
#ifdef FOR_TEST
-/*
- * Compiling for unit test, so we need the real implementations of
- * rollback functions. The unit test mocks the underlying tlcl
- * functions, so this is ok to run on the host.
- */
-#undef CHROMEOS_ENVIRONMENT
-#undef DISABLE_ROLLBACK_TPM
+#include <stdio.h>
+#define VBDEBUG(format, args...) printf(format, ## args)
+#else
+#include <console/console.h>
+#define VBDEBUG(format, args...) \
+ printk(BIOS_INFO, "%s():%d: " format, __func__, __LINE__, ## args)
#endif
-#define RETURN_ON_FAILURE(tpm_command) do { \
+#define RETURN_ON_FAILURE(tpm_cmd) do { \
uint32_t result_; \
- if ((result_ = (tpm_command)) != TPM_SUCCESS) { \
- VBDEBUG(("Rollback: %08x returned by " #tpm_command \
- "\n", (int)result_)); \
+ if ((result_ = (tpm_cmd)) != TPM_SUCCESS) { \
+ VBDEBUG("Antirollback: %08x returned by " #tpm_cmd \
+ "\n", (int)result_); \
return result_; \
} \
} while (0)
-uint32_t TPMClearAndReenable(void)
+uint32_t tpm_clear_and_reenable(void)
{
- VBDEBUG(("TPM: Clear and re-enable\n"));
- RETURN_ON_FAILURE(TlclForceClear());
- RETURN_ON_FAILURE(TlclSetEnable());
- RETURN_ON_FAILURE(TlclSetDeactivated(0));
+ VBDEBUG("TPM: Clear and re-enable\n");
+ RETURN_ON_FAILURE(tlcl_force_clear());
+ RETURN_ON_FAILURE(tlcl_set_enable());
+ RETURN_ON_FAILURE(tlcl_set_deactivated(0));
return TPM_SUCCESS;
}
-uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length)
+uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
{
- uint32_t result = TlclWrite(index, data, length);
+ uint32_t result = tlcl_write(index, data, length);
if (result == TPM_E_MAXNVWRITES) {
- RETURN_ON_FAILURE(TPMClearAndReenable());
- return TlclWrite(index, data, length);
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ return tlcl_write(index, data, length);
} else {
return result;
}
}
-uint32_t SafeDefineSpace(uint32_t index, uint32_t perm, uint32_t size)
+uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
{
- uint32_t result = TlclDefineSpace(index, perm, size);
+ uint32_t result = tlcl_define_space(index, perm, size);
if (result == TPM_E_MAXNVWRITES) {
- RETURN_ON_FAILURE(TPMClearAndReenable());
- return TlclDefineSpace(index, perm, size);
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ return tlcl_define_space(index, perm, size);
} else {
return result;
}
}
-/* Functions to read and write firmware and kernel spaces. */
-uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf)
+static uint32_t read_space_firmware(struct vb2_context *ctx)
{
- uint32_t r;
int attempts = 3;
while (attempts--) {
- r = TlclRead(FIRMWARE_NV_INDEX, rsf,
- sizeof(RollbackSpaceFirmware));
- if (r != TPM_SUCCESS)
- return r;
-
- /*
- * No CRC in this version, so we'll create one when we write
- * it. Note that we're marking this as version 2, not
- * ROLLBACK_SPACE_FIRMWARE_VERSION, because version 2 just
- * added the CRC. Later versions will need to set default
- * values for any extra fields explicitly (probably here).
- */
- if (rsf->struct_version < 2) {
- /* Danger Will Robinson! Danger! */
- rsf->struct_version = 2;
- return TPM_SUCCESS;
- }
+ RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
+ VB2_SECDATA_SIZE));
- /*
- * If the CRC is good, we're done. If it's bad, try a couple
- * more times to see if it gets better before we give up. It
- * could just be noise.
- */
- if (rsf->crc8 == Crc8(rsf,
- offsetof(RollbackSpaceFirmware, crc8)))
+ if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
return TPM_SUCCESS;
- VBDEBUG(("TPM: %s() - bad CRC\n", __func__));
+ VBDEBUG("TPM: %s() - bad CRC\n", __func__);
}
- VBDEBUG(("TPM: %s() - too many bad CRCs, giving up\n", __func__));
+ VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
return TPM_E_CORRUPTED_STATE;
}
-uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf)
+static uint32_t write_space_firmware(struct vb2_context *ctx)
{
- RollbackSpaceFirmware rsf2;
+ uint8_t secdata[VB2_SECDATA_SIZE];
uint32_t r;
int attempts = 3;
- /* All writes should use struct_version 2 or greater. */
- if (rsf->struct_version < 2)
- rsf->struct_version = 2;
- rsf->crc8 = Crc8(rsf, offsetof(RollbackSpaceFirmware, crc8));
-
+ memcpy(secdata, ctx->secdata, VB2_SECDATA_SIZE);
while (attempts--) {
- r = SafeWrite(FIRMWARE_NV_INDEX, rsf,
- sizeof(RollbackSpaceFirmware));
+ r = safe_write(FIRMWARE_NV_INDEX, secdata, VB2_SECDATA_SIZE);
/* Can't write, not gonna try again */
if (r != TPM_SUCCESS)
return r;
/* Read it back to be sure it got the right values. */
- r = ReadSpaceFirmware(&rsf2); /* This checks the CRC */
- if (r == TPM_SUCCESS)
+ r = read_space_firmware(ctx);
+ if (r == TPM_SUCCESS && memcmp(secdata, ctx->secdata,
+ VB2_SECDATA_SIZE) == 0)
return r;
- VBDEBUG(("TPM: %s() - bad CRC\n", __func__));
+ VBDEBUG("TPM: %s() failed\n", __func__);
/* Try writing it again. Maybe it was garbled on the way out. */
}
- VBDEBUG(("TPM: %s() - too many bad CRCs, giving up\n", __func__));
+ VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);
return TPM_E_CORRUPTED_STATE;
}
-uint32_t SetVirtualDevMode(int val)
+uint32_t factory_initialize_tpm(struct vb2_context *ctx)
{
- RollbackSpaceFirmware rsf;
-
- VBDEBUG(("TPM: Entering %s()\n", __func__));
- if (TPM_SUCCESS != ReadSpaceFirmware(&rsf))
- return VBERROR_TPM_FIRMWARE_SETUP;
-
- VBDEBUG(("TPM: flags were 0x%02x\n", rsf.flags));
- if (val)
- rsf.flags |= FLAG_VIRTUAL_DEV_MODE_ON;
- else
- rsf.flags &= ~FLAG_VIRTUAL_DEV_MODE_ON;
- /*
- * NOTE: This doesn't update the FLAG_LAST_BOOT_DEVELOPER bit. That
- * will be done by SetupTPM() on the next boot.
- */
- VBDEBUG(("TPM: flags are now 0x%02x\n", rsf.flags));
-
- if (TPM_SUCCESS != WriteSpaceFirmware(&rsf))
- return VBERROR_TPM_SET_BOOT_MODE_STATE;
-
- VBDEBUG(("TPM: Leaving %s()\n", __func__));
- return VBERROR_SUCCESS;
-}
-
-uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk)
-{
- uint32_t r;
- int attempts = 3;
-
- while (attempts--) {
- r = TlclRead(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
- if (r != TPM_SUCCESS)
- return r;
-
- /*
- * No CRC in this version, so we'll create one when we write
- * it. Note that we're marking this as version 2, not
- * ROLLBACK_SPACE_KERNEL_VERSION, because version 2 just added
- * the CRC. Later versions will need to set default values for
- * any extra fields explicitly (probably here).
- */
- if (rsk->struct_version < 2) {
- /* Danger Will Robinson! Danger! */
- rsk->struct_version = 2;
- return TPM_SUCCESS;
- }
-
- /*
- * If the CRC is good, we're done. If it's bad, try a couple
- * more times to see if it gets better before we give up. It
- * could just be noise.
- */
- if (rsk->crc8 == Crc8(rsk, offsetof(RollbackSpaceKernel, crc8)))
- return TPM_SUCCESS;
-
- VBDEBUG(("TPM: %s() - bad CRC\n", __func__));
- }
-
- VBDEBUG(("TPM: %s() - too many bad CRCs, giving up\n", __func__));
- return TPM_E_CORRUPTED_STATE;
-}
-
-uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk)
-{
- RollbackSpaceKernel rsk2;
- uint32_t r;
- int attempts = 3;
-
- /* All writes should use struct_version 2 or greater. */
- if (rsk->struct_version < 2)
- rsk->struct_version = 2;
- rsk->crc8 = Crc8(rsk, offsetof(RollbackSpaceKernel, crc8));
-
- while (attempts--) {
- r = SafeWrite(KERNEL_NV_INDEX, rsk,
- sizeof(RollbackSpaceKernel));
- /* Can't write, not gonna try again */
- if (r != TPM_SUCCESS)
- return r;
-
- /* Read it back to be sure it got the right values. */
- r = ReadSpaceKernel(&rsk2); /* This checks the CRC */
- if (r == TPM_SUCCESS)
- return r;
-
- VBDEBUG(("TPM: %s() - bad CRC\n", __func__));
- /* Try writing it again. Maybe it was garbled on the way out. */
- }
-
- VBDEBUG(("TPM: %s() - too many bad CRCs, giving up\n", __func__));
- return TPM_E_CORRUPTED_STATE;
-}
-
-uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf,
- RollbackSpaceKernel *rsk)
-{
- static const RollbackSpaceFirmware rsf_init = {
- .struct_version = ROLLBACK_SPACE_FIRMWARE_VERSION,
- };
- static const RollbackSpaceKernel rsk_init = {
- .struct_version = ROLLBACK_SPACE_KERNEL_VERSION,
- .uid = ROLLBACK_SPACE_KERNEL_UID,
- };
TPM_PERMANENT_FLAGS pflags;
uint32_t result;
- VBDEBUG(("TPM: One-time initialization\n"));
+ VBDEBUG("TPM: factory initialization\n");
/*
* Do a full test. This only happens the first time the device is
@@ -270,11 +127,11 @@ uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf,
* test---specifically the ones that set lifetime flags, and are only
* executed once per physical TPM.
*/
- result = TlclSelfTestFull();
+ result = tlcl_self_test_full();
if (result != TPM_SUCCESS)
return result;
- result = TlclGetPermanentFlags(&pflags);
+ result = tlcl_get_permanent_flags(&pflags);
if (result != TPM_SUCCESS)
return result;
@@ -282,11 +139,11 @@ uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf,
* TPM may come from the factory without physical presence finalized.
* Fix if necessary.
*/
- VBDEBUG(("TPM: physicalPresenceLifetimeLock=%d\n",
- pflags.physicalPresenceLifetimeLock));
+ VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
+ pflags.physicalPresenceLifetimeLock);
if (!pflags.physicalPresenceLifetimeLock) {
- VBDEBUG(("TPM: Finalizing physical presence\n"));
- RETURN_ON_FAILURE(TlclFinalizePhysicalPresence());
+ VBDEBUG("TPM: Finalizing physical presence\n");
+ RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
}
/*
@@ -294,40 +151,27 @@ uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf,
* execution of a TPM_NV_DefineSpace with the handle of
* TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
* exist. */
- VBDEBUG(("TPM: nvLocked=%d\n", pflags.nvLocked));
+ VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
if (!pflags.nvLocked) {
- VBDEBUG(("TPM: Enabling NV locking\n"));
- RETURN_ON_FAILURE(TlclSetNvLocked());
+ VBDEBUG("TPM: Enabling NV locking\n");
+ RETURN_ON_FAILURE(tlcl_set_nv_locked());
}
/* Clear TPM owner, in case the TPM is already owned for some reason. */
- VBDEBUG(("TPM: Clearing owner\n"));
- RETURN_ON_FAILURE(TPMClearAndReenable());
-
- /* Initializes the firmware and kernel spaces */
- Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware));
- Memcpy(rsk, &rsk_init, sizeof(RollbackSpaceKernel));
+ VBDEBUG("TPM: Clearing owner\n");
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
- /* Define the backup space. No need to initialize it, though. */
- RETURN_ON_FAILURE(SafeDefineSpace(
- BACKUP_NV_INDEX, TPM_NV_PER_PPWRITE, BACKUP_NV_SIZE));
-
- /* Define and initialize the kernel space */
- RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_NV_INDEX, TPM_NV_PER_PPWRITE,
- sizeof(RollbackSpaceKernel)));
- RETURN_ON_FAILURE(WriteSpaceKernel(rsk));
-
- /* Do the firmware space last, so we retry if we don't get this far. */
- RETURN_ON_FAILURE(SafeDefineSpace(
- FIRMWARE_NV_INDEX,
- TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE,
- sizeof(RollbackSpaceFirmware)));
- RETURN_ON_FAILURE(WriteSpaceFirmware(rsf));
+ /* Defines and sets vb2 secdata space */
+ vb2api_secdata_create(ctx);
+ RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
+ TPM_NV_PER_GLOBALLOCK |
+ TPM_NV_PER_PPWRITE,
+ VB2_SECDATA_SIZE));
+ RETURN_ON_FAILURE(write_space_firmware(ctx));
return TPM_SUCCESS;
}
-
/*
* SetupTPM starts the TPM and establishes the root of trust for the
* anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
@@ -348,329 +192,107 @@ uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware *rsf,
* to the TPM flashram at every reboot or wake-up, because of concerns about
* the durability of the NVRAM.
*/
-uint32_t SetupTPM(int developer_mode, int disable_dev_request,
- int clear_tpm_owner_request, RollbackSpaceFirmware* rsf)
+uint32_t setup_tpm(struct vb2_context *ctx)
{
- uint8_t in_flags;
uint8_t disable;
uint8_t deactivated;
uint32_t result;
- uint32_t versions;
- RETURN_ON_FAILURE(TlclLibInit());
+ RETURN_ON_FAILURE(tlcl_lib_init());
#ifdef TEGRA_SOFT_REBOOT_WORKAROUND
- result = TlclStartup();
+ result = tlcl_startup();
if (result == TPM_E_INVALID_POSTINIT) {
/*
* Some prototype hardware doesn't reset the TPM on a CPU
* reset. We do a hard reset to get around this.
*/
- VBDEBUG(("TPM: soft reset detected\n", result));
+ VBDEBUG("TPM: soft reset detected\n", result);
return TPM_E_MUST_REBOOT;
} else if (result != TPM_SUCCESS) {
- VBDEBUG(("TPM: TlclStartup returned %08x\n", result));
+ VBDEBUG("TPM: tlcl_startup returned %08x\n", result);
return result;
}
#else
- RETURN_ON_FAILURE(TlclStartup());
+ RETURN_ON_FAILURE(tlcl_startup());
#endif
- /*
- * Some TPMs start the self test automatically at power on. In that case we
- * don't need to call ContinueSelfTest. On some (other) TPMs,
- * ContinueSelfTest may block. In that case, we definitely don't want to
- * call it here. For TPMs in the intersection of these two sets, we're
- * screwed. (In other words: TPMs that require manually starting the
- * self-test AND block will have poor performance until we split
- * TlclSendReceive() into Send() and Receive(), and have a state machine to
- * control setup.)
- *
- * This comment is likely to become obsolete in the near future, so don't
- * trust it. It may have not been updated.
- */
+ /*
+ * Some TPMs start the self test automatically at power on. In that case
+ * we don't need to call ContinueSelfTest. On some (other) TPMs,
+ * continue_self_test may block. In that case, we definitely don't want
+ * to call it here. For TPMs in the intersection of these two sets, we
+ * are screwed. (In other words: TPMs that require manually starting the
+ * self-test AND block will have poor performance until we split
+ * tlcl_send_receive() into send() and receive(), and have a state
+ * machine to control setup.)
+ *
+ * This comment is likely to become obsolete in the near future, so
+ * don't trust it. It may have not been updated.
+ */
#ifdef TPM_MANUAL_SELFTEST
#ifdef TPM_BLOCKING_CONTINUESELFTEST
#warning "lousy TPM!"
#endif
- RETURN_ON_FAILURE(TlclContinueSelfTest());
+ RETURN_ON_FAILURE(tlcl_continue_self_test());
#endif
- result = TlclAssertPhysicalPresence();
+ result = tlcl_assert_physical_presence();
if (result != TPM_SUCCESS) {
/*
* It is possible that the TPM was delivered with the physical
* presence command disabled. This tries enabling it, then
* tries asserting PP again.
*/
- RETURN_ON_FAILURE(TlclPhysicalPresenceCMDEnable());
- RETURN_ON_FAILURE(TlclAssertPhysicalPresence());
+ RETURN_ON_FAILURE(tlcl_physical_presence_cmd_enable());
+ RETURN_ON_FAILURE(tlcl_assert_physical_presence());
}
/* Check that the TPM is enabled and activated. */
- RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated, NULL));
+ RETURN_ON_FAILURE(tlcl_get_flags(&disable, &deactivated, NULL));
if (disable || deactivated) {
- VBDEBUG(("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
- disable, deactivated));
- RETURN_ON_FAILURE(TlclSetEnable());
- RETURN_ON_FAILURE(TlclSetDeactivated(0));
- VBDEBUG(("TPM: Must reboot to re-enable\n"));
+ VBDEBUG("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
+ disable, deactivated);
+ RETURN_ON_FAILURE(tlcl_set_enable());
+ RETURN_ON_FAILURE(tlcl_set_deactivated(0));
+ VBDEBUG("TPM: Must reboot to re-enable\n");
return TPM_E_MUST_REBOOT;
}
- /* Read the firmware space. */
- result = ReadSpaceFirmware(rsf);
- if (TPM_E_BADINDEX == result) {
- RollbackSpaceKernel rsk;
-
- /*
- * This is the first time we've run, and the TPM has not been
- * initialized. Initialize it.
- */
- VBDEBUG(("TPM: Not initialized yet.\n"));
- RETURN_ON_FAILURE(OneTimeInitializeTPM(rsf, &rsk));
- } else if (TPM_SUCCESS != result) {
- VBDEBUG(("TPM: Firmware space in a bad state; giving up.\n"));
- return TPM_E_CORRUPTED_STATE;
- }
- Memcpy(&versions, &rsf->fw_versions, sizeof(versions));
- VBDEBUG(("TPM: Firmware space sv%d f%x v%x\n",
- rsf->struct_version, rsf->flags, versions));
- in_flags = rsf->flags;
-
- /* If we've been asked to clear the virtual dev-mode flag, do so now */
- if (disable_dev_request) {
- rsf->flags &= ~FLAG_VIRTUAL_DEV_MODE_ON;
- VBDEBUG(("TPM: Clearing virt dev-switch: f%x\n", rsf->flags));
- }
-
- /*
- * The developer_mode value that's passed in is only set by a hardware
- * dev-switch. We should OR it with the virtual switch, whether or not
- * the virtual switch is used. If it's not used, it shouldn't change,
- * so it doesn't matter.
- */
- if (rsf->flags & FLAG_VIRTUAL_DEV_MODE_ON)
- developer_mode = 1;
-
- /*
- * Clear ownership if developer flag has toggled, or if an owner-clear
- * has been requested.
- */
- if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) !=
- (in_flags & FLAG_LAST_BOOT_DEVELOPER)) {
- VBDEBUG(("TPM: Developer flag changed; clearing owner.\n"));
- RETURN_ON_FAILURE(TPMClearAndReenable());
- } else if (clear_tpm_owner_request) {
- VBDEBUG(("TPM: Clearing owner as specifically requested.\n"));
- RETURN_ON_FAILURE(TPMClearAndReenable());
- }
-
- if (developer_mode)
- rsf->flags |= FLAG_LAST_BOOT_DEVELOPER;
- else
- rsf->flags &= ~FLAG_LAST_BOOT_DEVELOPER;
-
-
- /* If firmware space is dirty, flush it back to the TPM */
- if (rsf->flags != in_flags) {
- VBDEBUG(("TPM: Updating firmware space.\n"));
- RETURN_ON_FAILURE(WriteSpaceFirmware(rsf));
- }
-
- VBDEBUG(("TPM: SetupTPM() succeeded\n"));
- return TPM_SUCCESS;
-}
-
-
-#ifdef DISABLE_ROLLBACK_TPM
-/* Dummy implementations which don't support TPM rollback protection */
-
-uint32_t RollbackS3Resume(void)
-{
-#ifndef CHROMEOS_ENVIRONMENT
- /*
- * Initialize the TPM, but ignore return codes. In ChromeOS
- * environment, don't even talk to the TPM.
- */
- TlclLibInit();
- TlclResume();
-#endif
- return TPM_SUCCESS;
-}
-
-uint32_t RollbackFirmwareSetup(int is_hw_dev,
- int disable_dev_request,
- int clear_tpm_owner_request,
- int *is_virt_dev, uint32_t *version)
-{
-#ifndef CHROMEOS_ENVIRONMENT
- /*
- * Initialize the TPM, but ignores return codes. In ChromeOS
- * environment, don't even talk to the TPM.
- */
- TlclLibInit();
- TlclStartup();
- TlclContinueSelfTest();
-#endif
- *is_virt_dev = 0;
- *version = 0;
- return TPM_SUCCESS;
-}
-
-uint32_t RollbackFirmwareWrite(uint32_t version)
-{
- return TPM_SUCCESS;
-}
-
-uint32_t RollbackFirmwareLock(void)
-{
- return TPM_SUCCESS;
-}
-
-uint32_t RollbackKernelRead(uint32_t* version)
-{
- *version = 0;
- return TPM_SUCCESS;
-}
-
-uint32_t RollbackKernelWrite(uint32_t version)
-{
- return TPM_SUCCESS;
-}
-
-uint32_t RollbackBackupRead(uint8_t *raw)
-{
+ VBDEBUG("TPM: SetupTPM() succeeded\n");
return TPM_SUCCESS;
}
-uint32_t RollbackBackupWrite(uint8_t *raw)
+uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
{
- return TPM_SUCCESS;
-}
+ uint32_t rv;
-uint32_t RollbackKernelLock(int recovery_mode)
-{
- return TPM_SUCCESS;
-}
+ rv = setup_tpm(ctx);
+ if (rv)
+ return rv;
-#else
-
-uint32_t RollbackS3Resume(void)
-{
- uint32_t result;
- RETURN_ON_FAILURE(TlclLibInit());
- result = TlclResume();
- if (result == TPM_E_INVALID_POSTINIT) {
+ /* Read the firmware space. */
+ rv = read_space_firmware(ctx);
+ if (rv == TPM_E_BADINDEX) {
/*
- * We're on a platform where the TPM maintains power in S3, so
- * it's already initialized.
+ * This seems the first time we've run. Initialize the TPM.
*/
- return TPM_SUCCESS;
- }
- return result;
-}
-
-uint32_t RollbackFirmwareSetup(int is_hw_dev,
- int disable_dev_request,
- int clear_tpm_owner_request,
- int *is_virt_dev, uint32_t *version)
-{
- RollbackSpaceFirmware rsf;
-
- /* Set version to 0 in case we fail */
- *version = 0;
-
- RETURN_ON_FAILURE(SetupTPM(is_hw_dev, disable_dev_request,
- clear_tpm_owner_request, &rsf));
- Memcpy(version, &rsf.fw_versions, sizeof(*version));
- *is_virt_dev = (rsf.flags & FLAG_VIRTUAL_DEV_MODE_ON) ? 1 : 0;
- VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)*version));
- return TPM_SUCCESS;
-}
-
-uint32_t RollbackFirmwareWrite(uint32_t version)
-{
- RollbackSpaceFirmware rsf;
- uint32_t old_version;
-
- RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf));
- Memcpy(&old_version, &rsf.fw_versions, sizeof(old_version));
- VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)old_version,
- (int)version));
- Memcpy(&rsf.fw_versions, &version, sizeof(version));
- return WriteSpaceFirmware(&rsf);
-}
-
-uint32_t RollbackFirmwareLock(void)
-{
- return TlclSetGlobalLock();
-}
-
-uint32_t RollbackKernelRead(uint32_t* version)
-{
- RollbackSpaceKernel rsk;
- uint32_t perms, uid;
-
- /*
- * Read the kernel space and verify its permissions. If the kernel
- * space has the wrong permission, or it doesn't contain the right
- * identifier, we give up. This will need to be fixed by the
- * recovery kernel. We have to worry about this because at any time
- * (even with PP turned off) the TPM owner can remove and redefine a
- * PP-protected space (but not write to it).
- */
- RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
- RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms));
- Memcpy(&uid, &rsk.uid, sizeof(uid));
- if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != uid)
+ VBDEBUG("TPM: Not initialized yet.\n");
+ RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
+ } else if (rv != TPM_SUCCESS) {
+ VBDEBUG("TPM: Firmware space in a bad state; giving up.\n");
+ //RETURN_ON_FAILURE(factory_initialize_tpm(ctx));
return TPM_E_CORRUPTED_STATE;
+ }
- Memcpy(version, &rsk.kernel_versions, sizeof(*version));
- VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)*version));
return TPM_SUCCESS;
}
-uint32_t RollbackKernelWrite(uint32_t version)
+uint32_t antirollback_write_space_firmware(struct vb2_context *ctx)
{
- RollbackSpaceKernel rsk;
- uint32_t old_version;
- RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
- Memcpy(&old_version, &rsk.kernel_versions, sizeof(old_version));
- VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n",
- (int)old_version, (int)version));
- Memcpy(&rsk.kernel_versions, &version, sizeof(version));
- return WriteSpaceKernel(&rsk);
+ return write_space_firmware(ctx);
}
-/*
- * We don't really care whether the TPM owner has been messing with this or
- * not. We lock it along with the Kernel space just to avoid problems, but it's
- * only useful in dev-mode and only when the battery has been drained
- * completely. There aren't any security issues. It's just in the TPM because
- * we don't have any other place to keep it.
- */
-uint32_t RollbackBackupRead(uint8_t *raw)
-{
- uint32_t r;
- r = TlclRead(BACKUP_NV_INDEX, raw, BACKUP_NV_SIZE);
- VBDEBUG(("TPM: %s returning 0x%x\n", __func__, r));
- return r;
-}
-
-uint32_t RollbackBackupWrite(uint8_t *raw)
+uint32_t antirollback_lock_space_firmware()
{
- uint32_t r;
- r = TlclWrite(BACKUP_NV_INDEX, raw, BACKUP_NV_SIZE);
- VBDEBUG(("TPM: %s returning 0x%x\n", __func__, r));
- return r;
+ return tlcl_set_global_lock();
}
-
-uint32_t RollbackKernelLock(int recovery_mode)
-{
- if (recovery_mode)
- return TPM_SUCCESS;
- else
- return TlclLockPhysicalPresence();
-}
-
-#endif /* DISABLE_ROLLBACK_TPM */
diff --git a/src/vendorcode/google/chromeos/vboot_main.c b/src/vendorcode/google/chromeos/vboot_main.c
index 8251cfd9b4..252dfb1bf8 100644
--- a/src/vendorcode/google/chromeos/vboot_main.c
+++ b/src/vendorcode/google/chromeos/vboot_main.c
@@ -1,10 +1,14 @@
#include <2api.h>
#include <2struct.h>
+#include <antirollback.h>
+#include <arch/exception.h>
#include <arch/stages.h>
#include <cbfs.h>
#include <console/console.h>
#include <console/vtxprintf.h>
#include <reset.h>
+#include <soc/addressmap.h>
+#include <soc/clock.h>
#include <string.h>
#include "chromeos.h"
@@ -64,8 +68,12 @@ void vb2ex_printf(const char *func, const char *fmt, ...)
int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
{
- VBDEBUG("Clearing owner\n");
- return VB2_ERROR_UNKNOWN;
+ uint32_t rv;
+ VBDEBUG("Clearing TPM owner\n");
+ rv = tpm_clear_and_reenable();
+ if (rv)
+ return VB2_ERROR_EX_TPM_CLEAR_OWNER;
+ return VB2_SUCCESS;
}
int vb2ex_read_resource(struct vb2_context *ctx,
@@ -222,6 +230,54 @@ static void enter_stage(struct cbfs_stage *stage)
stage_exit((void *)(uintptr_t)stage->entry);
}
+enum {
+ L2CTLR_ECC_PARITY = 0x1 << 21,
+ L2CTLR_TAG_RAM_LATENCY_MASK = 0x7 << 6,
+ L2CTLR_TAG_RAM_LATENCY_CYCLES_3 = 2 << 6,
+ L2CTLR_DATA_RAM_LATENCY_MASK = 0x7 << 0,
+ L2CTLR_DATA_RAM_LATENCY_CYCLES_3 = 2 << 0
+};
+
+enum {
+ L2ACTLR_FORCE_L2_LOGIC_CLOCK_ENABLE_ACTIVE = 0x1 << 27,
+ L2ACTLR_ENABLE_HAZARD_DETECT_TIMEOUT = 0x1 << 7,
+ L2ACTLR_DISABLE_CLEAN_EVICT_PUSH_EXTERNAL = 0x1 << 3
+};
+
+/* Configures L2 Control Register to use 3 cycles for DATA/TAG RAM latency. */
+static void configure_l2ctlr(void)
+{
+ uint32_t val;
+
+ val = read_l2ctlr();
+ val &= ~(L2CTLR_DATA_RAM_LATENCY_MASK | L2CTLR_TAG_RAM_LATENCY_MASK);
+ val |= (L2CTLR_DATA_RAM_LATENCY_CYCLES_3 | L2CTLR_TAG_RAM_LATENCY_CYCLES_3 |
+ L2CTLR_ECC_PARITY);
+ write_l2ctlr(val);
+}
+
+/* Configures L2 Auxiliary Control Register for Cortex A15. */
+static void configure_l2actlr(void)
+{
+ uint32_t val;
+
+ val = read_l2actlr();
+ val |= (L2ACTLR_DISABLE_CLEAN_EVICT_PUSH_EXTERNAL |
+ L2ACTLR_ENABLE_HAZARD_DETECT_TIMEOUT |
+ L2ACTLR_FORCE_L2_LOGIC_CLOCK_ENABLE_ACTIVE);
+ write_l2actlr(val);
+}
+
+static void enable_cache(void)
+{
+ mmu_init();
+ mmu_config_range(0, CONFIG_SYS_SDRAM_BASE >> 20, DCACHE_OFF);
+ mmu_config_range(0x40000000 >> 20, 2, DCACHE_WRITEBACK);
+ mmu_disable_range(0, 1);
+ VBDEBUG("Enabling cache\n");
+ dcache_mmu_enable();
+}
+
/**
* Save non-volatile and/or secure data if needed.
*/
@@ -229,16 +285,24 @@ static void save_if_needed(struct vb2_context *ctx)
{
if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
VBDEBUG("Saving nvdata\n");
- //save_vbnv(ctx->nvdata);
+ save_vbnv(ctx->nvdata);
ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
}
if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
VBDEBUG("Saving secdata\n");
- //antirollback_write_space_firmware(ctx);
+ antirollback_write_space_firmware(ctx);
ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
}
}
+/**
+ * Load and verify the next stage from RW image and jump to it
+ *
+ * If validation fails, it exits to romstage for recovery or reboots.
+ *
+ * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
+ * when per-stage verification is ready.
+ */
void __attribute__((noinline)) select_firmware(void)
{
struct vb2_context ctx;
@@ -248,7 +312,12 @@ void __attribute__((noinline)) select_firmware(void)
struct cbfs_stage *stage;
int rv;
+ /* Do minimum to enable cache and run vboot at full speed */
+ configure_l2ctlr();
+ configure_l2actlr();
console_init();
+ exception_init();
+ enable_cache();
/* Set up context */
memset(&ctx, 0, sizeof(ctx));
@@ -257,12 +326,12 @@ void __attribute__((noinline)) select_firmware(void)
memset(ctx.workbuf, 0, ctx.workbuf_size);
/* Read nvdata from a non-volatile storage */
- //read_vbnv(ctx.nvdata);
+ read_vbnv(ctx.nvdata);
/* Read secdata from TPM. Initialize TPM if secdata not found. We don't
* check the return value here because vb2api_fw_phase1 will catch
* invalid secdata and tell us what to do (=reboot). */
- //antirollback_read_space_firmware(&ctx);
+ antirollback_read_space_firmware(&ctx);
if (get_developer_mode_switch())
ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;