diff options
author | Randall Spangler <rspangler@chromium.org> | 2016-10-11 15:28:16 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-10-13 17:27:07 -0700 |
commit | fb267154d29356937eb304234793ab2e28ad0bab (patch) | |
tree | 609b8d39adab9b4cf8c7dac8859d76541e50e75f | |
parent | a1001da56512fdcd3bd648a5a04da03ffea3e91b (diff) | |
download | vboot-fb267154d29356937eb304234793ab2e28ad0bab.tar.gz |
Fix indentation in firmware and host libs
vboot_reference originally used 2-space indentation, rather than
kernel-style tabs. This makes it painful to maintain given that newer
source files are kernel-style.
Re-indent the files that need it, and reflow comments.
No functionality changes.
BUG=none
BRANCH=none
TEST=make runtests
Change-Id: I7dabed41f69434b1988a52600c0cb1eac8c8d7e6
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/396488
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r-- | firmware/lib/cgptlib/cgptlib_internal.c | 9 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/cgptlib_internal.h | 10 | ||||
-rw-r--r-- | firmware/lib/mocked_rollback_index.c | 27 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/mocked_tlcl.c | 194 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/tlcl.c | 722 | ||||
-rw-r--r-- | firmware/stub/tpm_lite_stub.c | 332 | ||||
-rw-r--r-- | firmware/stub/vboot_api_stub_disk.c | 24 | ||||
-rw-r--r-- | host/arch/arm/lib/crossystem_arch.c | 734 | ||||
-rw-r--r-- | host/arch/mips/lib/crossystem_arch.c | 101 | ||||
-rw-r--r-- | host/arch/x86/lib/crossystem_arch.c | 1360 | ||||
-rw-r--r-- | host/include/cgpt_params.h | 165 | ||||
-rw-r--r-- | host/lib/crossystem.c | 1439 | ||||
-rw-r--r-- | host/lib/file_keys.c | 6 | ||||
-rw-r--r-- | host/lib/host_misc.c | 172 | ||||
-rw-r--r-- | host/lib/include/fmap.h | 23 | ||||
-rw-r--r-- | host/lib/signature_digest.c | 107 | ||||
-rw-r--r-- | host/linktest/main.c | 24 |
17 files changed, 2822 insertions, 2627 deletions
diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 24b7ba15..d09fa090 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -14,10 +14,11 @@ const static int SECTOR_SIZE = 512; -size_t CalculateEntriesSectors(GptHeader* h) { - size_t bytes = h->number_of_entries * h->size_of_entry; - size_t ret = (bytes + SECTOR_SIZE - 1) / SECTOR_SIZE; - return ret; +size_t CalculateEntriesSectors(GptHeader* h) +{ + size_t bytes = h->number_of_entries * h->size_of_entry; + size_t ret = (bytes + SECTOR_SIZE - 1) / SECTOR_SIZE; + return ret; } int CheckParameters(GptData *gpt) diff --git a/firmware/lib/cgptlib/include/cgptlib_internal.h b/firmware/lib/cgptlib/include/cgptlib_internal.h index cd616e5c..55e79765 100644 --- a/firmware/lib/cgptlib/include/cgptlib_internal.h +++ b/firmware/lib/cgptlib/include/cgptlib_internal.h @@ -34,17 +34,17 @@ #define CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET (56 - 48) #define CGPT_ATTRIBUTE_MAX_SUCCESSFUL (1ULL) #define CGPT_ATTRIBUTE_SUCCESSFUL_MASK (CGPT_ATTRIBUTE_MAX_SUCCESSFUL << \ - CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET) + CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET) #define CGPT_ATTRIBUTE_TRIES_OFFSET (52 - 48) #define CGPT_ATTRIBUTE_MAX_TRIES (15ULL) #define CGPT_ATTRIBUTE_TRIES_MASK (CGPT_ATTRIBUTE_MAX_TRIES << \ - CGPT_ATTRIBUTE_TRIES_OFFSET) + CGPT_ATTRIBUTE_TRIES_OFFSET) #define CGPT_ATTRIBUTE_PRIORITY_OFFSET (48 - 48) #define CGPT_ATTRIBUTE_MAX_PRIORITY (15ULL) #define CGPT_ATTRIBUTE_PRIORITY_MASK (CGPT_ATTRIBUTE_MAX_PRIORITY << \ - CGPT_ATTRIBUTE_PRIORITY_OFFSET) + CGPT_ATTRIBUTE_PRIORITY_OFFSET) #define CGPT_ATTRIBUTE_LEGACY_BOOT_OFFSET (2) #define CGPT_ATTRIBUTE_MAX_LEGACY_BOOT (1ULL) @@ -90,8 +90,8 @@ int CheckParameters(GptData* gpt); * Returns 0 if header is valid, 1 if invalid. */ int CheckHeader(GptHeader *h, int is_secondary, - uint64_t streaming_drive_sectors, - uint64_t gpt_drive_sectors, uint32_t flags); + uint64_t streaming_drive_sectors, + uint64_t gpt_drive_sectors, uint32_t flags); /** * Calculate and return the header CRC. diff --git a/firmware/lib/mocked_rollback_index.c b/firmware/lib/mocked_rollback_index.c index bb253d15..e8c1fdbb 100644 --- a/firmware/lib/mocked_rollback_index.c +++ b/firmware/lib/mocked_rollback_index.c @@ -14,25 +14,30 @@ #include "tss_constants.h" -uint32_t SetVirtualDevMode(int val) { - return TPM_SUCCESS; +uint32_t SetVirtualDevMode(int val) +{ + return TPM_SUCCESS; } -uint32_t TPMClearAndReenable(void) { - return TPM_SUCCESS; +uint32_t TPMClearAndReenable(void) +{ + return TPM_SUCCESS; } -uint32_t RollbackKernelRead(uint32_t* version) { - *version = 0; - 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 RollbackKernelWrite(uint32_t version) +{ + return TPM_SUCCESS; } -uint32_t RollbackKernelLock(int recovery_mode) { - return TPM_SUCCESS; +uint32_t RollbackKernelLock(int recovery_mode) +{ + return TPM_SUCCESS; } uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp) diff --git a/firmware/lib/tpm_lite/mocked_tlcl.c b/firmware/lib/tpm_lite/mocked_tlcl.c index 627ed667..38d0deac 100644 --- a/firmware/lib/tpm_lite/mocked_tlcl.c +++ b/firmware/lib/tpm_lite/mocked_tlcl.c @@ -10,159 +10,191 @@ #include "utility.h" #include "vboot_api.h" -uint32_t TlclLibInit(void) { - return VbExTpmInit(); +uint32_t TlclLibInit(void) +{ + return VbExTpmInit(); } -uint32_t TlclLibClose(void) { - return TPM_SUCCESS; +uint32_t TlclLibClose(void) +{ + return TPM_SUCCESS; } -uint32_t TlclStartup(void) { - return TPM_SUCCESS; +uint32_t TlclStartup(void) +{ + return TPM_SUCCESS; } -uint32_t TlclSaveState(void) { - return TPM_SUCCESS; +uint32_t TlclSaveState(void) +{ + return TPM_SUCCESS; } -uint32_t TlclResume(void) { - return TPM_SUCCESS; +uint32_t TlclResume(void) +{ + return TPM_SUCCESS; } -uint32_t TlclSelfTestFull(void) { - return TPM_SUCCESS; +uint32_t TlclSelfTestFull(void) +{ + return TPM_SUCCESS; } -uint32_t TlclContinueSelfTest(void) { - return TPM_SUCCESS; +uint32_t TlclContinueSelfTest(void) +{ + return TPM_SUCCESS; } -uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { - return TPM_SUCCESS; +uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) +{ + return TPM_SUCCESS; } -uint32_t TlclWrite(uint32_t index, const void* data, uint32_t length) { - return TPM_SUCCESS; +uint32_t TlclWrite(uint32_t index, const void* data, uint32_t length) +{ + return TPM_SUCCESS; } -uint32_t TlclRead(uint32_t index, void* data, uint32_t length) { - Memset(data, '\0', length); - return TPM_SUCCESS; +uint32_t TlclRead(uint32_t index, void* data, uint32_t length) +{ + Memset(data, '\0', length); + return TPM_SUCCESS; } -uint32_t TlclPCRRead(uint32_t index, void* data, uint32_t length) { - Memset(data, '\0', length); - return TPM_SUCCESS; +uint32_t TlclPCRRead(uint32_t index, void* data, uint32_t length) +{ + Memset(data, '\0', length); + return TPM_SUCCESS; } -uint32_t TlclWriteLock(uint32_t index) { - return TPM_SUCCESS; +uint32_t TlclWriteLock(uint32_t index) +{ + return TPM_SUCCESS; } -uint32_t TlclReadLock(uint32_t index) { - return TPM_SUCCESS; +uint32_t TlclReadLock(uint32_t index) +{ + return TPM_SUCCESS; } -uint32_t TlclAssertPhysicalPresence(void) { - return TPM_SUCCESS; +uint32_t TlclAssertPhysicalPresence(void) +{ + return TPM_SUCCESS; } -uint32_t TlclPhysicalPresenceCMDEnable(void) { - return TPM_SUCCESS; +uint32_t TlclPhysicalPresenceCMDEnable(void) +{ + return TPM_SUCCESS; } -uint32_t TlclFinalizePhysicalPresence(void) { - return TPM_SUCCESS; +uint32_t TlclFinalizePhysicalPresence(void) +{ + return TPM_SUCCESS; } -uint32_t TlclAssertPhysicalPresenceResult(void) { - return TPM_SUCCESS; +uint32_t TlclAssertPhysicalPresenceResult(void) +{ + return TPM_SUCCESS; } -uint32_t TlclLockPhysicalPresence(void) { - return TPM_SUCCESS; +uint32_t TlclLockPhysicalPresence(void) +{ + return TPM_SUCCESS; } -uint32_t TlclSetNvLocked(void) { - return TPM_SUCCESS; +uint32_t TlclSetNvLocked(void) +{ + return TPM_SUCCESS; } -int TlclIsOwned(void) { - return 0; +int TlclIsOwned(void) +{ + return 0; } -uint32_t TlclForceClear(void) { - return TPM_SUCCESS; +uint32_t TlclForceClear(void) +{ + return TPM_SUCCESS; } -uint32_t TlclSetEnable(void) { - return TPM_SUCCESS; +uint32_t TlclSetEnable(void) +{ + return TPM_SUCCESS; } -uint32_t TlclClearEnable(void) { - return TPM_SUCCESS; +uint32_t TlclClearEnable(void) +{ + return TPM_SUCCESS; } -uint32_t TlclSetDeactivated(uint8_t flag) { - return TPM_SUCCESS; +uint32_t TlclSetDeactivated(uint8_t flag) +{ + return TPM_SUCCESS; } -uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS* pflags) { - Memset(pflags, '\0', sizeof(*pflags)); - return TPM_SUCCESS; +uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS* pflags) +{ + Memset(pflags, '\0', sizeof(*pflags)); + return TPM_SUCCESS; } -uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS* vflags) { - Memset(vflags, '\0', sizeof(*vflags)); - return TPM_SUCCESS; +uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS* vflags) +{ + Memset(vflags, '\0', sizeof(*vflags)); + return TPM_SUCCESS; } uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated, - uint8_t *nvlocked) { - *disable = 0; - *deactivated = 0; - *nvlocked = 0; - return TPM_SUCCESS; + uint8_t *nvlocked) +{ + *disable = 0; + *deactivated = 0; + *nvlocked = 0; + return TPM_SUCCESS; } -uint32_t TlclSetGlobalLock(void) { - return TPM_SUCCESS; +uint32_t TlclSetGlobalLock(void) +{ + return TPM_SUCCESS; } uint32_t TlclExtend(int pcr_num, const uint8_t* in_digest, - uint8_t* out_digest) { - Memcpy(out_digest, in_digest, kPcrDigestLength); - return TPM_SUCCESS; + uint8_t* out_digest) +{ + Memcpy(out_digest, in_digest, kPcrDigestLength); + return TPM_SUCCESS; } -uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) { - *permissions = 0; - return TPM_SUCCESS; +uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) +{ + *permissions = 0; + return TPM_SUCCESS; } -uint32_t TlclGetOwnership(uint8_t* owned) { - *owned = 0; - return TPM_SUCCESS; +uint32_t TlclGetOwnership(uint8_t* owned) +{ + *owned = 0; + return TPM_SUCCESS; } -uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size) { - *size = length; - /* http://dilbert.com/strips/comic/2001-10-25/ */ - Memset(data, '\x9', *size); - return TPM_SUCCESS; +uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size) +{ + *size = length; + /* http://dilbert.com/strips/comic/2001-10-25/ */ + Memset(data, '\x9', *size); + return TPM_SUCCESS; } int TlclPacketSize(const uint8_t* packet) { - uint32_t size; - FromTpmUint32(packet + sizeof(uint16_t), &size); - return (int) size; + uint32_t size; + FromTpmUint32(packet + sizeof(uint16_t), &size); + return (int) size; } uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, int max_length) { - return TPM_SUCCESS; + return TPM_SUCCESS; } diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c index 78944314..7da5e14e 100644 --- a/firmware/lib/tpm_lite/tlcl.c +++ b/firmware/lib/tpm_lite/tlcl.c @@ -28,441 +28,485 @@ #endif /* 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 SetTpmCommandSize(uint8_t* buffer, uint32_t size) +{ + ToTpmUint32(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; +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); +int TlclPacketSize(const uint8_t* packet) +{ + return TpmCommandSize(packet); } /* 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 TpmCommandCode(const uint8_t* buffer) +{ + uint32_t code; + FromTpmUint32(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 TpmReturnCode(const uint8_t* buffer) +{ + return TpmCommandCode(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) { + uint8_t* response, int max_length) +{ - uint32_t response_length = max_length; - uint32_t result; + 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])); + 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 = 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 */ + 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])); + 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 - VBDEBUG(("TPM: command 0x%x returned 0x%x\n", - TpmCommandCode(request), result)); + VBDEBUG(("TPM: command 0x%x returned 0x%x\n", + TpmCommandCode(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. */ + 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; - } + /* 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; + } #if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE) - /* Retry only once */ - result = TlclSendReceiveNoRetry(request, response, max_length); + /* Retry only once */ + result = TlclSendReceiveNoRetry(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 = TlclSendReceiveNoRetry(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 TlclSendReceive(command, response, sizeof(response)); } /* Exported functions. */ -uint32_t TlclLibInit(void) { - return VbExTpmInit(); -} - -uint32_t TlclLibClose(void) { - return VbExTpmClose(); +uint32_t TlclLibInit(void) +{ + return VbExTpmInit(); } -uint32_t TlclStartup(void) { - VBDEBUG(("TPM: Startup\n")); - return Send(tpm_startup_cmd.buffer); +uint32_t TlclLibClose(void) +{ + return VbExTpmClose(); } -uint32_t TlclSaveState(void) { - VBDEBUG(("TPM: SaveState\n")); - return Send(tpm_savestate_cmd.buffer); +uint32_t TlclStartup(void) +{ + VBDEBUG(("TPM: Startup\n")); + return Send(tpm_startup_cmd.buffer); } -uint32_t TlclResume(void) { - VBDEBUG(("TPM: Resume\n")); - return Send(tpm_resume_cmd.buffer); +uint32_t TlclSaveState(void) +{ + VBDEBUG(("TPM: SaveState\n")); + return Send(tpm_savestate_cmd.buffer); } -uint32_t TlclSelfTestFull(void) { - VBDEBUG(("TPM: Self test full\n")); - return Send(tpm_selftestfull_cmd.buffer); +uint32_t TlclResume(void) +{ + VBDEBUG(("TPM: Resume\n")); + return Send(tpm_resume_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 TlclSelfTestFull(void) +{ + VBDEBUG(("TPM: Self test full\n")); + return Send(tpm_selftestfull_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 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 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 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 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; +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: 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); + 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); - 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); - if (result_length > length) - result_length = length; /* Truncate to fit buffer */ - nv_read_cursor += sizeof(uint32_t); - Memcpy(data, nv_read_cursor, result_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 result; + return TlclSendReceive(cmd.buffer, response, sizeof(response)); } -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); - } +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; - return result; -} - -uint32_t TlclWriteLock(uint32_t index) { - VBDEBUG(("TPM: Write lock 0x%x\n", index)); - return TlclWrite(index, NULL, 0); -} + 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); -uint32_t TlclReadLock(uint32_t index) { - VBDEBUG(("TPM: Read lock 0x%x\n", index)); - return TlclRead(index, NULL, 0); -} + 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); + if (result_length > length) + result_length = length; /* Truncate to fit buffer */ + nv_read_cursor += sizeof(uint32_t); + Memcpy(data, nv_read_cursor, result_length); + } -uint32_t TlclAssertPhysicalPresence(void) { - VBDEBUG(("TPM: Asserting physical presence\n")); - return Send(tpm_ppassert_cmd.buffer); + return result; } -uint32_t TlclPhysicalPresenceCMDEnable(void) { - VBDEBUG(("TPM: Enable the physical presence command\n")); - return Send(tpm_ppenable_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; -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: 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); -uint32_t TlclAssertPhysicalPresenceResult(void) { - uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; - return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response)); -} + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result == TPM_SUCCESS) { + uint8_t* pcr_read_cursor = response + kTpmResponseHeaderLength; + Memcpy(data, pcr_read_cursor, kPcrDigestLength); + } -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); +uint32_t TlclWriteLock(uint32_t index) +{ + VBDEBUG(("TPM: Write lock 0x%x\n", index)); + return TlclWrite(index, NULL, 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 TlclReadLock(uint32_t index) +{ + VBDEBUG(("TPM: Read lock 0x%x\n", index)); + return TlclRead(index, NULL, 0); +} + +uint32_t TlclAssertPhysicalPresence(void) +{ + VBDEBUG(("TPM: Asserting physical presence\n")); + return Send(tpm_ppassert_cmd.buffer); +} + +uint32_t TlclPhysicalPresenceCMDEnable(void) +{ + VBDEBUG(("TPM: Enable the physical presence command\n")); + return Send(tpm_ppenable_cmd.buffer); +} + +uint32_t TlclFinalizePhysicalPresence(void) +{ + VBDEBUG(("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n")); + return Send(tpm_finalizepp_cmd.buffer); +} + +uint32_t TlclAssertPhysicalPresenceResult(void) +{ + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + return TlclSendReceive(tpm_ppassert_cmd.buffer, response, + sizeof(response)); +} + +uint32_t TlclLockPhysicalPresence(void) +{ + VBDEBUG(("TPM: Lock physical presence\n")); + return Send(tpm_pplock_cmd.buffer); +} + +uint32_t TlclSetNvLocked(void) +{ + VBDEBUG(("TPM: Set NV locked\n")); + return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0); } -uint32_t TlclForceClear(void) { - VBDEBUG(("TPM: Force clear\n")); - return Send(tpm_forceclear_cmd.buffer); -} +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 TlclSetEnable(void) { - VBDEBUG(("TPM: Enabling TPM\n")); - return Send(tpm_physicalenable_cmd.buffer); +uint32_t TlclSetEnable(void) +{ + VBDEBUG(("TPM: Enabling TPM\n")); + return Send(tpm_physicalenable_cmd.buffer); } -uint32_t TlclClearEnable(void) { - VBDEBUG(("TPM: Disabling TPM\n")); - return Send(tpm_physicaldisable_cmd.buffer); +uint32_t TlclClearEnable(void) +{ + VBDEBUG(("TPM: Disabling TPM\n")); + return Send(tpm_physicaldisable_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 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 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 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 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 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 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 TlclSetGlobalLock(void) { - uint32_t x; - VBDEBUG(("TPM: Set global lock\n")); - return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); + 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 TlclSetGlobalLock(void) +{ + uint32_t x; + VBDEBUG(("TPM: Set global lock\n")); + return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); } 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); - - result = TlclSendReceive(cmd.buffer, response, sizeof(response)); - if (result != TPM_SUCCESS) - return 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; -} - -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; -} - -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; + 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); + + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) + return 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; +} + +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; +} + +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; } 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; } diff --git a/firmware/stub/vboot_api_stub_disk.c b/firmware/stub/vboot_api_stub_disk.c index 186cd97d..a7570c3b 100644 --- a/firmware/stub/vboot_api_stub_disk.c +++ b/firmware/stub/vboot_api_stub_disk.c @@ -19,26 +19,30 @@ VbError_t VbExDiskGetInfo(VbDiskInfo** infos_ptr, uint32_t* count, - uint32_t disk_flags) { - *infos_ptr = NULL; - *count = 0; - return VBERROR_SUCCESS; + uint32_t disk_flags) +{ + *infos_ptr = NULL; + *count = 0; + return VBERROR_SUCCESS; } VbError_t VbExDiskFreeInfo(VbDiskInfo* infos_ptr, - VbExDiskHandle_t preserve_handle) { - return VBERROR_SUCCESS; + VbExDiskHandle_t preserve_handle) +{ + return VBERROR_SUCCESS; } VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start, - uint64_t lba_count, void* buffer) { - return VBERROR_SUCCESS; + uint64_t lba_count, void* buffer) +{ + return VBERROR_SUCCESS; } VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start, - uint64_t lba_count, const void* buffer) { - return VBERROR_SUCCESS; + uint64_t lba_count, const void* buffer) +{ + return VBERROR_SUCCESS; } diff --git a/host/arch/arm/lib/crossystem_arch.c b/host/arch/arm/lib/crossystem_arch.c index f1feab2c..2f2a5437 100644 --- a/host/arch/arm/lib/crossystem_arch.c +++ b/host/arch/arm/lib/crossystem_arch.c @@ -48,410 +48,438 @@ #define SECTOR_SIZE 512 #define MAX_NMMCBLK 9 -static int FindEmmcDev(void) { - int mmcblk; - unsigned value; - char filename[FNAME_SIZE]; - for (mmcblk = 0; mmcblk < MAX_NMMCBLK; mmcblk++) { - /* Get first non-removable mmc block device */ - snprintf(filename, sizeof(filename), "/sys/block/mmcblk%d/removable", - mmcblk); - if (ReadFileInt(filename, &value) < 0) - continue; - if (value == 0) - return mmcblk; - } - /* eMMC not found */ - return E_FAIL; +static int FindEmmcDev(void) +{ + int mmcblk; + unsigned value; + char filename[FNAME_SIZE]; + for (mmcblk = 0; mmcblk < MAX_NMMCBLK; mmcblk++) { + /* Get first non-removable mmc block device */ + snprintf(filename, sizeof(filename), + "/sys/block/mmcblk%d/removable", mmcblk); + if (ReadFileInt(filename, &value) < 0) + continue; + if (value == 0) + return mmcblk; + } + /* eMMC not found */ + return E_FAIL; } -static int ReadFdtValue(const char *property, int *value) { - char filename[FNAME_SIZE]; - FILE *file; - int data = 0; - - snprintf(filename, sizeof(filename), FDT_BASE_PATH "/%s", property); - file = fopen(filename, "rb"); - if (!file) { - fprintf(stderr, "Unable to open FDT property %s\n", property); - return E_FILEOP; - } - - if (fread(&data, 1, sizeof(data), file) != sizeof(data)) { - fprintf(stderr, "Unable to read FDT property %s\n", property); - return E_FILEOP; - } - fclose(file); - - if (value) - *value = ntohl(data); /* FDT is network byte order */ - - return 0; +static int ReadFdtValue(const char *property, int *value) +{ + char filename[FNAME_SIZE]; + FILE *file; + int data = 0; + + snprintf(filename, sizeof(filename), FDT_BASE_PATH "/%s", property); + file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "Unable to open FDT property %s\n", property); + return E_FILEOP; + } + + if (fread(&data, 1, sizeof(data), file) != sizeof(data)) { + fprintf(stderr, "Unable to read FDT property %s\n", property); + return E_FILEOP; + } + fclose(file); + + if (value) + *value = ntohl(data); /* FDT is network byte order */ + + return 0; } -static int ReadFdtInt(const char *property) { - int value = 0; - if (ReadFdtValue(property, &value)) - return E_FAIL; - return value; +static int ReadFdtInt(const char *property) +{ + int value = 0; + if (ReadFdtValue(property, &value)) + return E_FAIL; + return value; } -static void GetFdtPropertyPath(const char *property, char *path, size_t size) { - if (property[0] == '/') - StrCopy(path, property, size); - else - snprintf(path, size, FDT_BASE_PATH "/%s", property); +static void GetFdtPropertyPath(const char *property, char *path, size_t size) +{ + if (property[0] == '/') + StrCopy(path, property, size); + else + snprintf(path, size, FDT_BASE_PATH "/%s", property); } -static int FdtPropertyExist(const char *property) { - char filename[FNAME_SIZE]; - struct stat file_status; - - GetFdtPropertyPath(property, filename, sizeof(filename)); - if (!stat(filename, &file_status)) - return 1; // It exists! - else - return 0; // It does not exist or some error happened. +static int FdtPropertyExist(const char *property) +{ + char filename[FNAME_SIZE]; + struct stat file_status; + + GetFdtPropertyPath(property, filename, sizeof(filename)); + if (!stat(filename, &file_status)) + return 1; // It exists! + else + return 0; // It does not exist or some error happened. } -static int ReadFdtBlock(const char *property, void **block, size_t *size) { - char filename[FNAME_SIZE]; - FILE *file; - size_t property_size; - char *data; - - if (!block) - return E_FAIL; - - GetFdtPropertyPath(property, filename, sizeof(filename)); - file = fopen(filename, "rb"); - if (!file) { - fprintf(stderr, "Unable to open FDT property %s\n", property); - return E_FILEOP; - } - - fseek(file, 0, SEEK_END); - property_size = ftell(file); - rewind(file); - - data = malloc(property_size +1); - if (!data) { - fclose(file); - return E_MEM; - } - data[property_size] = 0; - - if (1 != fread(data, property_size, 1, file)) { - fprintf(stderr, "Unable to read from property %s\n", property); - fclose(file); - free(data); - return E_FILEOP; - } - - fclose(file); - *block = data; - if (size) - *size = property_size; - - return 0; +static int ReadFdtBlock(const char *property, void **block, size_t *size) +{ + char filename[FNAME_SIZE]; + FILE *file; + size_t property_size; + char *data; + + if (!block) + return E_FAIL; + + GetFdtPropertyPath(property, filename, sizeof(filename)); + file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "Unable to open FDT property %s\n", property); + return E_FILEOP; + } + + fseek(file, 0, SEEK_END); + property_size = ftell(file); + rewind(file); + + data = malloc(property_size +1); + if (!data) { + fclose(file); + return E_MEM; + } + data[property_size] = 0; + + if (1 != fread(data, property_size, 1, file)) { + fprintf(stderr, "Unable to read from property %s\n", property); + fclose(file); + free(data); + return E_FILEOP; + } + + fclose(file); + *block = data; + if (size) + *size = property_size; + + return 0; } -static char * ReadFdtString(const char *property) { - void *str = NULL; - /* Do not need property size */ - ReadFdtBlock(property, &str, 0); - return (char *)str; +static char * ReadFdtString(const char *property) +{ + void *str = NULL; + /* Do not need property size */ + ReadFdtBlock(property, &str, 0); + return (char *)str; } -static int VbGetPlatformGpioStatus(const char* name) { - char gpio_name[FNAME_SIZE]; - unsigned value; +static int VbGetPlatformGpioStatus(const char* name) +{ + char gpio_name[FNAME_SIZE]; + unsigned value; - snprintf(gpio_name, sizeof(gpio_name), "%s/%s/value", - PLATFORM_DEV_PATH, name); - if (ReadFileInt(gpio_name, &value) < 0) - return -1; + snprintf(gpio_name, sizeof(gpio_name), "%s/%s/value", + PLATFORM_DEV_PATH, name); + if (ReadFileInt(gpio_name, &value) < 0) + return -1; - return (int)value; + return (int)value; } -static int VbGetGpioStatus(unsigned gpio_number) { - char gpio_name[FNAME_SIZE]; - unsigned value; - - snprintf(gpio_name, sizeof(gpio_name), "%s/gpio%d/value", - GPIO_BASE_PATH, gpio_number); - if (ReadFileInt(gpio_name, &value) < 0) { - /* Try exporting the GPIO */ - FILE* f = fopen(GPIO_EXPORT_PATH, "wt"); - if (!f) - return -1; - fprintf(f, "%d", gpio_number); - fclose(f); - - /* Try re-reading the GPIO value */ - if (ReadFileInt(gpio_name, &value) < 0) - return -1; - } - - return (int)value; +static int VbGetGpioStatus(unsigned gpio_number) +{ + char gpio_name[FNAME_SIZE]; + unsigned value; + + snprintf(gpio_name, sizeof(gpio_name), "%s/gpio%d/value", + GPIO_BASE_PATH, gpio_number); + if (ReadFileInt(gpio_name, &value) < 0) { + /* Try exporting the GPIO */ + FILE* f = fopen(GPIO_EXPORT_PATH, "wt"); + if (!f) + return -1; + fprintf(f, "%d", gpio_number); + fclose(f); + + /* Try re-reading the GPIO value */ + if (ReadFileInt(gpio_name, &value) < 0) + return -1; + } + + return (int)value; } -static int VbGetVarGpio(const char* name) { - int gpio_num; - void *pp = NULL; - int *prop; - size_t proplen = 0; - int ret = 0; - - /* TODO: This should at some point in the future use the phandle - * to find the gpio chip and thus the base number. Assume 0 now, - * which isn't 100% future-proof (i.e. if one of the switches gets - * moved to an offchip gpio controller. - */ - - ret = ReadFdtBlock(name, &pp, &proplen); - if (ret || !pp || proplen != 12) { - ret = 2; - goto out; - } - prop = pp; - gpio_num = ntohl(prop[1]); - - /* - * TODO(chrome-os-partner:11296): Use gpio_num == 0 to denote non-exist - * GPIO for now, at the risk that one day we might actually want to read - * from a GPIO port 0. We should figure out how to represent "non-exist" - * properly. - */ - if (gpio_num) - ret = VbGetGpioStatus(gpio_num); - else - ret = -1; +static int VbGetVarGpio(const char* name) +{ + int gpio_num; + void *pp = NULL; + int *prop; + size_t proplen = 0; + int ret = 0; + + /* TODO: This should at some point in the future use the phandle + * to find the gpio chip and thus the base number. Assume 0 now, + * which isn't 100% future-proof (i.e. if one of the switches gets + * moved to an offchip gpio controller. + */ + + ret = ReadFdtBlock(name, &pp, &proplen); + if (ret || !pp || proplen != 12) { + ret = 2; + goto out; + } + prop = pp; + gpio_num = ntohl(prop[1]); + + /* + * TODO(chrome-os-partner:11296): Use gpio_num == 0 to denote non-exist + * GPIO for now, at the risk that one day we might actually want to + * read from a GPIO port 0. We should figure out how to represent + * "non-exist" properly. + */ + if (gpio_num) + ret = VbGetGpioStatus(gpio_num); + else + ret = -1; out: - if (pp) - free(pp); + if (pp) + free(pp); - return ret; + return ret; } -static int VbReadNvStorage_disk(VbNvContext* vnc) { - int nvctx_fd = -1; - uint8_t sector[SECTOR_SIZE]; - int rv = -1; - char nvctx_path[FNAME_SIZE]; - int emmc_dev; - int lba = ReadFdtInt("nonvolatile-context-lba"); - int offset = ReadFdtInt("nonvolatile-context-offset"); - int size = ReadFdtInt("nonvolatile-context-size"); - - emmc_dev = FindEmmcDev(); - if (emmc_dev < 0) - return E_FAIL; - snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev); - - if (size != sizeof(vnc->raw) || (size + offset > SECTOR_SIZE)) - return E_FAIL; - - nvctx_fd = open(nvctx_path, O_RDONLY); - if (nvctx_fd == -1) { - fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, nvctx_path); - goto out; - } - lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET); - - rv = read(nvctx_fd, sector, SECTOR_SIZE); - if (size <= 0) { - fprintf(stderr, "%s: failed to read nvctx from device %s\n", - __FUNCTION__, nvctx_path); - goto out; - } - Memcpy(vnc->raw, sector+offset, size); - rv = 0; +static int VbReadNvStorage_disk(VbNvContext* vnc) +{ + int nvctx_fd = -1; + uint8_t sector[SECTOR_SIZE]; + int rv = -1; + char nvctx_path[FNAME_SIZE]; + int emmc_dev; + int lba = ReadFdtInt("nonvolatile-context-lba"); + int offset = ReadFdtInt("nonvolatile-context-offset"); + int size = ReadFdtInt("nonvolatile-context-size"); + + emmc_dev = FindEmmcDev(); + if (emmc_dev < 0) + return E_FAIL; + snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev); + + if (size != sizeof(vnc->raw) || (size + offset > SECTOR_SIZE)) + return E_FAIL; + + nvctx_fd = open(nvctx_path, O_RDONLY); + if (nvctx_fd == -1) { + fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, + nvctx_path); + goto out; + } + lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET); + + rv = read(nvctx_fd, sector, SECTOR_SIZE); + if (size <= 0) { + fprintf(stderr, "%s: failed to read nvctx from device %s\n", + __FUNCTION__, nvctx_path); + goto out; + } + Memcpy(vnc->raw, sector+offset, size); + rv = 0; out: - if (nvctx_fd > 0) - close(nvctx_fd); + if (nvctx_fd > 0) + close(nvctx_fd); - return rv; + return rv; } -static int VbWriteNvStorage_disk(VbNvContext* vnc) { - int nvctx_fd = -1; - uint8_t sector[SECTOR_SIZE]; - int rv = -1; - char nvctx_path[FNAME_SIZE]; - int emmc_dev; - int lba = ReadFdtInt("nonvolatile-context-lba"); - int offset = ReadFdtInt("nonvolatile-context-offset"); - int size = ReadFdtInt("nonvolatile-context-size"); - - emmc_dev = FindEmmcDev(); - if (emmc_dev < 0) - return E_FAIL; - snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev); - - if (size != sizeof(vnc->raw) || (size + offset > SECTOR_SIZE)) - return E_FAIL; - - do { - nvctx_fd = open(nvctx_path, O_RDWR); - if (nvctx_fd == -1) { - fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, nvctx_path); - break; - } - lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET); - rv = read(nvctx_fd, sector, SECTOR_SIZE); - if (rv <= 0) { - fprintf(stderr, "%s: failed to read nvctx from device %s\n", - __FUNCTION__, nvctx_path); - break; - } - Memcpy(sector+offset, vnc->raw, size); - lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET); - rv = write(nvctx_fd, sector, SECTOR_SIZE); - if (rv <= 0) { - fprintf(stderr, "%s: failed to write nvctx to device %s\n", - __FUNCTION__, nvctx_path); - break; - } +static int VbWriteNvStorage_disk(VbNvContext* vnc) +{ + int nvctx_fd = -1; + uint8_t sector[SECTOR_SIZE]; + int rv = -1; + char nvctx_path[FNAME_SIZE]; + int emmc_dev; + int lba = ReadFdtInt("nonvolatile-context-lba"); + int offset = ReadFdtInt("nonvolatile-context-offset"); + int size = ReadFdtInt("nonvolatile-context-size"); + + emmc_dev = FindEmmcDev(); + if (emmc_dev < 0) + return E_FAIL; + snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev); + + if (size != sizeof(vnc->raw) || (size + offset > SECTOR_SIZE)) + return E_FAIL; + + do { + nvctx_fd = open(nvctx_path, O_RDWR); + if (nvctx_fd == -1) { + fprintf(stderr, "%s: failed to open %s\n", + __FUNCTION__, nvctx_path); + break; + } + lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET); + rv = read(nvctx_fd, sector, SECTOR_SIZE); + if (rv <= 0) { + fprintf(stderr, + "%s: failed to read nvctx from device %s\n", + __FUNCTION__, nvctx_path); + break; + } + Memcpy(sector+offset, vnc->raw, size); + lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET); + rv = write(nvctx_fd, sector, SECTOR_SIZE); + if (rv <= 0) { + fprintf(stderr, + "%s: failed to write nvctx to device %s\n", + __FUNCTION__, nvctx_path); + break; + } #ifndef HAVE_MACOS - /* Must flush buffer cache here to make sure it goes to disk */ - rv = ioctl(nvctx_fd, BLKFLSBUF, 0); - if (rv < 0) { - fprintf(stderr, "%s: failed to flush nvctx to device %s\n", - __FUNCTION__, nvctx_path); - break; - } + /* Must flush buffer cache here to make sure it goes to disk */ + rv = ioctl(nvctx_fd, BLKFLSBUF, 0); + if (rv < 0) { + fprintf(stderr, + "%s: failed to flush nvctx to device %s\n", + __FUNCTION__, nvctx_path); + break; + } #endif - rv = 0; - } while (0); + rv = 0; + } while (0); - if (nvctx_fd > 0) - close(nvctx_fd); + if (nvctx_fd > 0) + close(nvctx_fd); - return rv; + return rv; } -int VbReadNvStorage(VbNvContext* vnc) { - /* Default to disk for older firmware which does not provide storage type */ - char *media; - if (!FdtPropertyExist(FDT_NVSTORAGE_TYPE_PROP)) - return VbReadNvStorage_disk(vnc); - media = ReadFdtString(FDT_NVSTORAGE_TYPE_PROP); - if (!strcmp(media, "disk")) - return VbReadNvStorage_disk(vnc); - if (!strcmp(media, "cros-ec") || !strcmp(media, "mkbp") || - !strcmp(media, "flash")) - return VbReadNvStorage_mosys(vnc); - return -1; +int VbReadNvStorage(VbNvContext* vnc) +{ + /* Default to disk for older firmware which does not provide storage + * type */ + char *media; + if (!FdtPropertyExist(FDT_NVSTORAGE_TYPE_PROP)) + return VbReadNvStorage_disk(vnc); + media = ReadFdtString(FDT_NVSTORAGE_TYPE_PROP); + if (!strcmp(media, "disk")) + return VbReadNvStorage_disk(vnc); + if (!strcmp(media, "cros-ec") || !strcmp(media, "mkbp") || + !strcmp(media, "flash")) + return VbReadNvStorage_mosys(vnc); + return -1; } -int VbWriteNvStorage(VbNvContext* vnc) { - /* Default to disk for older firmware which does not provide storage type */ - char *media; - if (!FdtPropertyExist(FDT_NVSTORAGE_TYPE_PROP)) - return VbWriteNvStorage_disk(vnc); - media = ReadFdtString(FDT_NVSTORAGE_TYPE_PROP); - if (!strcmp(media, "disk")) - return VbWriteNvStorage_disk(vnc); - if (!strcmp(media, "cros-ec") || !strcmp(media, "mkbp") || - !strcmp(media, "flash")) - return VbWriteNvStorage_mosys(vnc); - return -1; +int VbWriteNvStorage(VbNvContext* vnc) +{ + /* Default to disk for older firmware which does not provide storage + * type */ + char *media; + if (!FdtPropertyExist(FDT_NVSTORAGE_TYPE_PROP)) + return VbWriteNvStorage_disk(vnc); + media = ReadFdtString(FDT_NVSTORAGE_TYPE_PROP); + if (!strcmp(media, "disk")) + return VbWriteNvStorage_disk(vnc); + if (!strcmp(media, "cros-ec") || !strcmp(media, "mkbp") || + !strcmp(media, "flash")) + return VbWriteNvStorage_mosys(vnc); + return -1; } -VbSharedDataHeader *VbSharedDataRead(void) { - void *block = NULL; - size_t size = 0; - if (ReadFdtBlock("vboot-shared-data", &block, &size)) - return NULL; - VbSharedDataHeader *p = (VbSharedDataHeader *)block; - if (p->magic != VB_SHARED_DATA_MAGIC) { - fprintf(stderr, "%s: failed to validate magic in " - "VbSharedDataHeader (%x != %x)\n", - __FUNCTION__, p->magic, VB_SHARED_DATA_MAGIC); - return NULL; - } - return (VbSharedDataHeader *)block; +VbSharedDataHeader *VbSharedDataRead(void) +{ + void *block = NULL; + size_t size = 0; + if (ReadFdtBlock("vboot-shared-data", &block, &size)) + return NULL; + VbSharedDataHeader *p = (VbSharedDataHeader *)block; + if (p->magic != VB_SHARED_DATA_MAGIC) { + fprintf(stderr, "%s: failed to validate magic in " + "VbSharedDataHeader (%x != %x)\n", + __FUNCTION__, p->magic, VB_SHARED_DATA_MAGIC); + return NULL; + } + return (VbSharedDataHeader *)block; } -int VbGetArchPropertyInt(const char* name) { - if (!strcasecmp(name, "fmap_base")) { - return ReadFdtInt("fmap-offset"); - } else if (!strcasecmp(name, "devsw_cur")) { - /* Systems with virtual developer switches return at-boot value */ - int flags = VbGetSystemPropertyInt("vdat_flags"); - if ((flags != -1) && (flags & VBSD_HONOR_VIRT_DEV_SWITCH)) - return VbGetSystemPropertyInt("devsw_boot"); - - return VbGetVarGpio("developer-switch"); - } else if (!strcasecmp(name, "recoverysw_cur")) { - int value; - value = VbGetPlatformGpioStatus("recovery"); - if (value != -1) - return value; - - return VbGetVarGpio("recovery-switch"); - } else if (!strcasecmp(name, "wpsw_cur")) { - int value; - /* Try finding the GPIO through the chromeos_arm platform device first. */ - value = VbGetPlatformGpioStatus("write-protect"); - if (value != -1) - return value; - return VbGetVarGpio("write-protect-switch"); - } else if (!strcasecmp(name, "recoverysw_ec_boot")) { - /* TODO: read correct value using ectool */ - return 0; - } else { - return -1; - } +int VbGetArchPropertyInt(const char* name) +{ + if (!strcasecmp(name, "fmap_base")) { + return ReadFdtInt("fmap-offset"); + } else if (!strcasecmp(name, "devsw_cur")) { + /* Systems with virtual developer switches return at-boot + * value */ + int flags = VbGetSystemPropertyInt("vdat_flags"); + if ((flags != -1) && (flags & VBSD_HONOR_VIRT_DEV_SWITCH)) + return VbGetSystemPropertyInt("devsw_boot"); + + return VbGetVarGpio("developer-switch"); + } else if (!strcasecmp(name, "recoverysw_cur")) { + int value; + value = VbGetPlatformGpioStatus("recovery"); + if (value != -1) + return value; + + return VbGetVarGpio("recovery-switch"); + } else if (!strcasecmp(name, "wpsw_cur")) { + int value; + /* Try finding the GPIO through the chromeos_arm platform + * device first. */ + value = VbGetPlatformGpioStatus("write-protect"); + if (value != -1) + return value; + return VbGetVarGpio("write-protect-switch"); + } else if (!strcasecmp(name, "recoverysw_ec_boot")) { + /* TODO: read correct value using ectool */ + return 0; + } else { + return -1; + } } const char* VbGetArchPropertyString(const char* name, char* dest, - size_t size) { - char *str = NULL; - char *rv = NULL; - char *prop = NULL; - - if (!strcasecmp(name,"arch")) - return StrCopy(dest, "arm", size); - - /* Properties from fdt */ - if (!strcasecmp(name, "ro_fwid")) - prop = "readonly-firmware-version"; - else if (!strcasecmp(name, "hwid")) - prop = "hardware-id"; - else if (!strcasecmp(name, "fwid")) - prop = "firmware-version"; - else if (!strcasecmp(name, "mainfw_type")) - prop = "firmware-type"; - else if (!strcasecmp(name, "ecfw_act")) - prop = "active-ec-firmware"; - - if (prop) - str = ReadFdtString(prop); - - if (str) { - rv = StrCopy(dest, str, size); - free(str); - return rv; - } - return NULL; + size_t size) +{ + char *str = NULL; + char *rv = NULL; + char *prop = NULL; + + if (!strcasecmp(name,"arch")) + return StrCopy(dest, "arm", size); + + /* Properties from fdt */ + if (!strcasecmp(name, "ro_fwid")) + prop = "readonly-firmware-version"; + else if (!strcasecmp(name, "hwid")) + prop = "hardware-id"; + else if (!strcasecmp(name, "fwid")) + prop = "firmware-version"; + else if (!strcasecmp(name, "mainfw_type")) + prop = "firmware-type"; + else if (!strcasecmp(name, "ecfw_act")) + prop = "active-ec-firmware"; + + if (prop) + str = ReadFdtString(prop); + + if (str) { + rv = StrCopy(dest, str, size); + free(str); + return rv; + } + return NULL; } -int VbSetArchPropertyInt(const char* name, int value) { - /* All is handled in arch independent fashion */ - return -1; +int VbSetArchPropertyInt(const char* name, int value) +{ + /* All is handled in arch independent fashion */ + return -1; } -int VbSetArchPropertyString(const char* name, const char* value) { - /* All is handled in arch independent fashion */ - return -1; +int VbSetArchPropertyString(const char* name, const char* value) +{ + /* All is handled in arch independent fashion */ + return -1; } int VbArchInit(void) { - return 0; + return 0; } diff --git a/host/arch/mips/lib/crossystem_arch.c b/host/arch/mips/lib/crossystem_arch.c index 28a6b806..c0b25877 100644 --- a/host/arch/mips/lib/crossystem_arch.c +++ b/host/arch/mips/lib/crossystem_arch.c @@ -11,64 +11,71 @@ #include "crossystem.h" #include "crossystem_arch.h" -// TODO: Currently these are stub implementations providing reasonable defaults -// wherever possible. They will need real implementation as part of of MIPS -// firmware bringup. +/* TODO: Currently these are stub implementations providing reasonable defaults + * wherever possible. They will need real implementation as part of of MIPS + * firmware bringup. */ -int VbReadNvStorage(VbNvContext* vnc) { - return -1; +int VbReadNvStorage(VbNvContext* vnc) +{ + return -1; } -int VbWriteNvStorage(VbNvContext* vnc) { - return -1; +int VbWriteNvStorage(VbNvContext* vnc) +{ + return -1; } -VbSharedDataHeader *VbSharedDataRead(void) { - return NULL; +VbSharedDataHeader *VbSharedDataRead(void) +{ + return NULL; } -int VbGetArchPropertyInt(const char* name) { - if (!strcasecmp(name,"devsw_cur")) { - return 1; - } else if (!strcasecmp(name,"recoverysw_cur")) { - return 0; - } else if (!strcasecmp(name,"wpsw_cur")) { - return 1; - } else if (!strcasecmp(name,"devsw_boot")) { - return 1; - } else if (!strcasecmp(name,"recoverysw_boot")) { - return 0; - } else if (!strcasecmp(name,"recoverysw_ec_boot")) { - return 0; - } else if (!strcasecmp(name,"wpsw_boot")) { - return 1; - } - return -1; +int VbGetArchPropertyInt(const char* name) +{ + if (!strcasecmp(name,"devsw_cur")) { + return 1; + } else if (!strcasecmp(name,"recoverysw_cur")) { + return 0; + } else if (!strcasecmp(name,"wpsw_cur")) { + return 1; + } else if (!strcasecmp(name,"devsw_boot")) { + return 1; + } else if (!strcasecmp(name,"recoverysw_boot")) { + return 0; + } else if (!strcasecmp(name,"recoverysw_ec_boot")) { + return 0; + } else if (!strcasecmp(name,"wpsw_boot")) { + return 1; + } + return -1; } -const char* VbGetArchPropertyString(const char* name, char* dest, size_t size) { - if (!strcasecmp(name,"hwid")) { - return StrCopy(dest, "UnknownMipsHwid", size); - } else if (!strcasecmp(name,"fwid")) { - return StrCopy(dest, "UnknownMipsFwid", size); - } else if (!strcasecmp(name,"ro_fwid")) { - return StrCopy(dest, "UnknownMipsRoFwid", size); - } else if (!strcasecmp(name,"mainfw_act")) { - return StrCopy(dest, "A", size); - } else if (!strcasecmp(name,"mainfw_type")) { - return StrCopy(dest, "developer", size); - } else if (!strcasecmp(name,"ecfw_act")) { - return StrCopy(dest, "RO", size); - } - return NULL; +const char* VbGetArchPropertyString(const char* name, char* dest, size_t size) +{ + if (!strcasecmp(name,"hwid")) { + return StrCopy(dest, "UnknownMipsHwid", size); + } else if (!strcasecmp(name,"fwid")) { + return StrCopy(dest, "UnknownMipsFwid", size); + } else if (!strcasecmp(name,"ro_fwid")) { + return StrCopy(dest, "UnknownMipsRoFwid", size); + } else if (!strcasecmp(name,"mainfw_act")) { + return StrCopy(dest, "A", size); + } else if (!strcasecmp(name,"mainfw_type")) { + return StrCopy(dest, "developer", size); + } else if (!strcasecmp(name,"ecfw_act")) { + return StrCopy(dest, "RO", size); + } + return NULL; } -int VbSetArchPropertyInt(const char* name, int value) { - /* All is handled in arch independent fashion */ - return -1; +int VbSetArchPropertyInt(const char* name, int value) +{ + /* All is handled in arch independent fashion */ + return -1; } -int VbSetArchPropertyString(const char* name, const char* value) { - /* All is handled in arch independent fashion */ - return -1; +int VbSetArchPropertyString(const char* name, const char* value) +{ + /* All is handled in arch independent fashion */ + return -1; } diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c index 2b5d00aa..e17852be 100644 --- a/host/arch/x86/lib/crossystem_arch.c +++ b/host/arch/x86/lib/crossystem_arch.c @@ -94,109 +94,113 @@ #define PCI_DEVICE_ID_PATH "/sys/bus/pci/devices/0000:00:00.0/device" typedef struct { - unsigned int base; - unsigned int uid; + unsigned int base; + unsigned int uid; } Basemapping; -static void VbFixCmosChecksum(FILE* file) { - int fd = fileno(file); - ioctl(fd, NVRAM_SETCKS); +static void VbFixCmosChecksum(FILE* file) +{ + int fd = fileno(file); + ioctl(fd, NVRAM_SETCKS); } -static int VbCmosRead(unsigned offs, size_t size, void *ptr) { - size_t res; - FILE* f; - - f = fopen(NVRAM_PATH, "rb"); - if (!f) - return -1; - - if (0 != fseek(f, offs, SEEK_SET)) { - fclose(f); - return -1; - } - - res = fread(ptr, size, 1, f); - if (1 != res && errno == EIO && ferror(f)) { - VbFixCmosChecksum(f); - res = fread(ptr, size, 1, f); - } - - fclose(f); - return (1 == res) ? 0 : -1; +static int VbCmosRead(unsigned offs, size_t size, void *ptr) +{ + size_t res; + FILE* f; + + f = fopen(NVRAM_PATH, "rb"); + if (!f) + return -1; + + if (0 != fseek(f, offs, SEEK_SET)) { + fclose(f); + return -1; + } + + res = fread(ptr, size, 1, f); + if (1 != res && errno == EIO && ferror(f)) { + VbFixCmosChecksum(f); + res = fread(ptr, size, 1, f); + } + + fclose(f); + return (1 == res) ? 0 : -1; } -static int VbCmosWrite(unsigned offs, size_t size, const void *ptr) { - size_t res; - FILE* f; - - f = fopen(NVRAM_PATH, "w+b"); - if (!f) - return -1; - - if (0 != fseek(f, offs, SEEK_SET)) { - fclose(f); - return -1; - } - - res = fwrite(ptr, size, 1, f); - if (1 != res && errno == EIO && ferror(f)) { - VbFixCmosChecksum(f); - res = fwrite(ptr, size, 1, f); - } - - fclose(f); - return (1 == res) ? 0 : -1; +static int VbCmosWrite(unsigned offs, size_t size, const void *ptr) +{ + size_t res; + FILE* f; + + f = fopen(NVRAM_PATH, "w+b"); + if (!f) + return -1; + + if (0 != fseek(f, offs, SEEK_SET)) { + fclose(f); + return -1; + } + + res = fwrite(ptr, size, 1, f); + if (1 != res && errno == EIO && ferror(f)) { + VbFixCmosChecksum(f); + res = fwrite(ptr, size, 1, f); + } + + fclose(f); + return (1 == res) ? 0 : -1; } -int VbReadNvStorage(VbNvContext* vnc) { - unsigned offs, blksz; +int VbReadNvStorage(VbNvContext* vnc) +{ + unsigned offs, blksz; - /* Get the byte offset from VBNV */ - if (ReadFileInt(ACPI_VBNV_PATH ".0", &offs) < 0) - return -1; - if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0) - return -1; - if (VBNV_BLOCK_SIZE > blksz) - return -1; /* NV storage block is too small */ + /* Get the byte offset from VBNV */ + if (ReadFileInt(ACPI_VBNV_PATH ".0", &offs) < 0) + return -1; + if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0) + return -1; + if (VBNV_BLOCK_SIZE > blksz) + return -1; /* NV storage block is too small */ - if (0 != VbCmosRead(offs, VBNV_BLOCK_SIZE, vnc->raw)) - return -1; + if (0 != VbCmosRead(offs, VBNV_BLOCK_SIZE, vnc->raw)) + return -1; - return 0; + return 0; } int VbWriteNvStorage(VbNvContext* vnc) { - unsigned offs, blksz; - - if (!vnc->raw_changed) - return 0; /* Nothing changed, so no need to write */ - - /* Get the byte offset from VBNV */ - if (ReadFileInt(ACPI_VBNV_PATH ".0", &offs) < 0) - return -1; - if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0) - return -1; - if (VBNV_BLOCK_SIZE > blksz) - return -1; /* NV storage block is too small */ - - if (0 != VbCmosWrite(offs, VBNV_BLOCK_SIZE, vnc->raw)) - return -1; - - /* Also attempt to write using mosys if using vboot2 */ - VbSharedDataHeader *sh = VbSharedDataRead(); - if (sh) { - if (sh->flags & VBSD_BOOT_FIRMWARE_VBOOT2) - VbWriteNvStorage_mosys(vnc); - free(sh); - } - - return 0; + unsigned offs, blksz; + + if (!vnc->raw_changed) + return 0; /* Nothing changed, so no need to write */ + + /* Get the byte offset from VBNV */ + if (ReadFileInt(ACPI_VBNV_PATH ".0", &offs) < 0) + return -1; + if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0) + return -1; + if (VBNV_BLOCK_SIZE > blksz) + return -1; /* NV storage block is too small */ + + if (0 != VbCmosWrite(offs, VBNV_BLOCK_SIZE, vnc->raw)) + return -1; + + /* Also attempt to write using mosys if using vboot2 */ + VbSharedDataHeader *sh = VbSharedDataRead(); + if (sh) { + if (sh->flags & VBSD_BOOT_FIRMWARE_VBOOT2) + VbWriteNvStorage_mosys(vnc); + free(sh); + } + + return 0; } @@ -217,132 +221,137 @@ int VbWriteNvStorage(VbNvContext* vnc) * deallocating the pointer, this will take care of both the structure * and the buffer. Null in case of error. */ -static uint8_t* VbGetBuffer(const char* filename, int* buffer_size) { - FILE* f = NULL; - char* file_buffer = NULL; - uint8_t* output_buffer = NULL; - uint8_t* return_value = NULL; - - /* Assume error until proven otherwise */ - if (buffer_size) - *buffer_size = 0; - - do { - struct stat fs; - uint8_t* output_ptr; - int rv, i, real_size; - int parsed_size = 0; - - rv = stat(filename, &fs); - if (rv || !S_ISREG(fs.st_mode)) - break; - - f = fopen(filename, "r"); - if (!f) - break; - - file_buffer = malloc(fs.st_size + 1); - if (!file_buffer) - break; - - real_size = fread(file_buffer, 1, fs.st_size, f); - if (!real_size) - break; - file_buffer[real_size] = '\0'; - - /* Each byte in the output will replace two characters and a space - * in the input, so the output size does not exceed input side/3 - * (a little less if account for newline characters). */ - output_buffer = malloc(real_size/3); - if (!output_buffer) - break; - output_ptr = output_buffer; - - /* process the file contents */ - for (i = 0; i < real_size; i++) { - char* base, *end; - - base = file_buffer + i; - - if (!isxdigit(*base)) - continue; - - output_ptr[parsed_size++] = strtol(base, &end, 16) & 0xff; - - if ((end - base) != 2) - /* Input file format error */ - break; - - i += 2; /* skip the second character and the following space */ - } - - if (i == real_size) { - /* all is well */ - return_value = output_buffer; - output_buffer = NULL; /* prevent it from deallocating */ - if (buffer_size) - *buffer_size = parsed_size; - } - } while(0); - - /* wrap up */ - if (f) - fclose(f); - - if (file_buffer) - free(file_buffer); - - if (output_buffer) - free(output_buffer); - - return return_value; +static uint8_t* VbGetBuffer(const char* filename, int* buffer_size) +{ + FILE* f = NULL; + char* file_buffer = NULL; + uint8_t* output_buffer = NULL; + uint8_t* return_value = NULL; + + /* Assume error until proven otherwise */ + if (buffer_size) + *buffer_size = 0; + + do { + struct stat fs; + uint8_t* output_ptr; + int rv, i, real_size; + int parsed_size = 0; + + rv = stat(filename, &fs); + if (rv || !S_ISREG(fs.st_mode)) + break; + + f = fopen(filename, "r"); + if (!f) + break; + + file_buffer = malloc(fs.st_size + 1); + if (!file_buffer) + break; + + real_size = fread(file_buffer, 1, fs.st_size, f); + if (!real_size) + break; + file_buffer[real_size] = '\0'; + + /* Each byte in the output will replace two characters and a + * space in the input, so the output size does not exceed input + * side/3 (a little less if account for newline characters). */ + output_buffer = malloc(real_size/3); + if (!output_buffer) + break; + output_ptr = output_buffer; + + /* process the file contents */ + for (i = 0; i < real_size; i++) { + char* base, *end; + + base = file_buffer + i; + + if (!isxdigit(*base)) + continue; + + output_ptr[parsed_size++] = + strtol(base, &end, 16) & 0xff; + + if ((end - base) != 2) + /* Input file format error */ + break; + + /* skip the second character and the following space */ + i += 2; + } + + if (i == real_size) { + /* all is well */ + return_value = output_buffer; + output_buffer = NULL; /* prevent it from deallocating */ + if (buffer_size) + *buffer_size = parsed_size; + } + } while(0); + + /* wrap up */ + if (f) + fclose(f); + + if (file_buffer) + free(file_buffer); + + if (output_buffer) + free(output_buffer); + + return return_value; } -VbSharedDataHeader* VbSharedDataRead(void) { - VbSharedDataHeader* sh; - int got_size = 0; - int expect_size; - - sh = (VbSharedDataHeader*)VbGetBuffer(ACPI_VDAT_PATH, &got_size); - if (!sh) - return NULL; - - /* Make sure the size is sufficient for the struct version we got. - * Check supported old versions first. */ - if (1 == sh->struct_version) - expect_size = VB_SHARED_DATA_HEADER_SIZE_V1; - else { - /* There'd better be enough data for the current header size. */ - expect_size = sizeof(VbSharedDataHeader); - } - - if (got_size < expect_size) { - free(sh); - return NULL; - } - if (sh->data_size > got_size) - sh->data_size = got_size; /* Truncated read */ - - return sh; +VbSharedDataHeader* VbSharedDataRead(void) +{ + VbSharedDataHeader* sh; + int got_size = 0; + int expect_size; + + sh = (VbSharedDataHeader*)VbGetBuffer(ACPI_VDAT_PATH, &got_size); + if (!sh) + return NULL; + + /* Make sure the size is sufficient for the struct version we got. + * Check supported old versions first. */ + if (1 == sh->struct_version) + expect_size = VB_SHARED_DATA_HEADER_SIZE_V1; + else { + /* There'd better be enough data for the current header size. */ + expect_size = sizeof(VbSharedDataHeader); + } + + if (got_size < expect_size) { + free(sh); + return NULL; + } + if (sh->data_size > got_size) + sh->data_size = got_size; /* Truncated read */ + + return sh; } /* Read the CMOS reboot field in NVRAM. * * Returns 0 if the mask is clear in the field, 1 if set, or -1 if error. */ -static int VbGetCmosRebootField(uint8_t mask) { - unsigned chnv; - uint8_t nvbyte; +static int VbGetCmosRebootField(uint8_t mask) +{ + unsigned chnv; + uint8_t nvbyte; - /* Get the byte offset from CHNV */ - if (ReadFileInt(ACPI_CHNV_PATH, &chnv) < 0) - return -1; + /* Get the byte offset from CHNV */ + if (ReadFileInt(ACPI_CHNV_PATH, &chnv) < 0) + return -1; - if (0 != VbCmosRead(chnv, 1, &nvbyte)) - return -1; + if (0 != VbCmosRead(chnv, 1, &nvbyte)) + return -1; - return (nvbyte & mask ? 1 : 0); + return (nvbyte & mask ? 1 : 0); } @@ -351,112 +360,115 @@ static int VbGetCmosRebootField(uint8_t mask) { * Sets (value=0) or clears (value!=0) the mask in the byte. * * Returns 0 if success, or -1 if error. */ -static int VbSetCmosRebootField(uint8_t mask, int value) { - unsigned chnv; - uint8_t nvbyte; +static int VbSetCmosRebootField(uint8_t mask, int value) +{ + unsigned chnv; + uint8_t nvbyte; - /* Get the byte offset from CHNV */ - if (ReadFileInt(ACPI_CHNV_PATH, &chnv) < 0) - return -1; + /* Get the byte offset from CHNV */ + if (ReadFileInt(ACPI_CHNV_PATH, &chnv) < 0) + return -1; - if (0 != VbCmosRead(chnv, 1, &nvbyte)) - return -1; + if (0 != VbCmosRead(chnv, 1, &nvbyte)) + return -1; - /* Set/clear the mask */ - if (value) - nvbyte |= mask; - else - nvbyte &= ~mask; + /* Set/clear the mask */ + if (value) + nvbyte |= mask; + else + nvbyte &= ~mask; - /* Write the byte back */ - if (0 != VbCmosWrite(chnv, 1, &nvbyte)) - return -1; + /* Write the byte back */ + if (0 != VbCmosWrite(chnv, 1, &nvbyte)) + return -1; - /* Success */ - return 0; + /* Success */ + return 0; } /* Read the active main firmware type into the destination buffer. * Passed the destination and its size. Returns the destination, or * NULL if error. */ -static const char* VbReadMainFwType(char* dest, int size) { - unsigned value; - - /* Try reading type from BINF.3 */ - if (ReadFileInt(ACPI_BINF_PATH ".3", &value) == 0) { - switch(value) { - case BINF3_NETBOOT: - return StrCopy(dest, "netboot", size); - case BINF3_RECOVERY: - return StrCopy(dest, "recovery", size); - case BINF3_NORMAL: - return StrCopy(dest, "normal", size); - case BINF3_DEVELOPER: - return StrCopy(dest, "developer", size); - default: - break; /* Fall through to legacy handling */ - } - } - - /* Fall back to BINF.0 for legacy systems like Mario. */ - if (ReadFileInt(ACPI_BINF_PATH ".0", &value) < 0) - /* Both BINF.0 and BINF.3 are missing, so this isn't Chrome OS - * firmware. */ - return StrCopy(dest, "nonchrome", size); - - switch(value) { - case BINF0_NORMAL: - return StrCopy(dest, "normal", size); - case BINF0_DEVELOPER: - return StrCopy(dest, "developer", size); - case BINF0_RECOVERY_BUTTON: - case BINF0_RECOVERY_DEV_SCREEN_KEY: - case BINF0_RECOVERY_RW_FW_BAD: - case BINF0_RECOVERY_NO_OS: - case BINF0_RECOVERY_BAD_OS: - case BINF0_RECOVERY_OS_INITIATED: - case BINF0_RECOVERY_TPM_ERROR: - /* Assorted flavors of recovery boot reason. */ - return StrCopy(dest, "recovery", size); - default: - /* Other values don't map cleanly to firmware type. */ - return NULL; - } +static const char* VbReadMainFwType(char* dest, int size) +{ + unsigned value; + + /* Try reading type from BINF.3 */ + if (ReadFileInt(ACPI_BINF_PATH ".3", &value) == 0) { + switch(value) { + case BINF3_NETBOOT: + return StrCopy(dest, "netboot", size); + case BINF3_RECOVERY: + return StrCopy(dest, "recovery", size); + case BINF3_NORMAL: + return StrCopy(dest, "normal", size); + case BINF3_DEVELOPER: + return StrCopy(dest, "developer", size); + default: + break; /* Fall through to legacy handling */ + } + } + + /* Fall back to BINF.0 for legacy systems like Mario. */ + if (ReadFileInt(ACPI_BINF_PATH ".0", &value) < 0) + /* Both BINF.0 and BINF.3 are missing, so this isn't Chrome OS + * firmware. */ + return StrCopy(dest, "nonchrome", size); + + switch(value) { + case BINF0_NORMAL: + return StrCopy(dest, "normal", size); + case BINF0_DEVELOPER: + return StrCopy(dest, "developer", size); + case BINF0_RECOVERY_BUTTON: + case BINF0_RECOVERY_DEV_SCREEN_KEY: + case BINF0_RECOVERY_RW_FW_BAD: + case BINF0_RECOVERY_NO_OS: + case BINF0_RECOVERY_BAD_OS: + case BINF0_RECOVERY_OS_INITIATED: + case BINF0_RECOVERY_TPM_ERROR: + /* Assorted flavors of recovery boot reason. */ + return StrCopy(dest, "recovery", size); + default: + /* Other values don't map cleanly to firmware type. */ + return NULL; + } } /* Read the recovery reason. Returns the reason code or -1 if error. */ -static int VbGetRecoveryReason(void) { - unsigned value; - - /* Try reading type from BINF.4 */ - if (ReadFileInt(ACPI_BINF_PATH ".4", &value) == 0) - return value; - - /* Fall back to BINF.0 for legacy systems like Mario. */ - if (ReadFileInt(ACPI_BINF_PATH ".0", &value) < 0) - return -1; - switch(value) { - case BINF0_NORMAL: - case BINF0_DEVELOPER: - return VBNV_RECOVERY_NOT_REQUESTED; - case BINF0_RECOVERY_BUTTON: - return VBNV_RECOVERY_RO_MANUAL; - case BINF0_RECOVERY_DEV_SCREEN_KEY: - return VBNV_RECOVERY_RW_DEV_SCREEN; - case BINF0_RECOVERY_RW_FW_BAD: - return VBNV_RECOVERY_RO_INVALID_RW; - case BINF0_RECOVERY_NO_OS: - return VBNV_RECOVERY_RW_NO_OS; - case BINF0_RECOVERY_BAD_OS: - return VBNV_RECOVERY_RW_INVALID_OS; - case BINF0_RECOVERY_OS_INITIATED: - return VBNV_RECOVERY_LEGACY; - default: - /* Other values don't map cleanly to firmware type. */ - return -1; - } +static int VbGetRecoveryReason(void) +{ + unsigned value; + + /* Try reading type from BINF.4 */ + if (ReadFileInt(ACPI_BINF_PATH ".4", &value) == 0) + return value; + + /* Fall back to BINF.0 for legacy systems like Mario. */ + if (ReadFileInt(ACPI_BINF_PATH ".0", &value) < 0) + return -1; + switch(value) { + case BINF0_NORMAL: + case BINF0_DEVELOPER: + return VBNV_RECOVERY_NOT_REQUESTED; + case BINF0_RECOVERY_BUTTON: + return VBNV_RECOVERY_RO_MANUAL; + case BINF0_RECOVERY_DEV_SCREEN_KEY: + return VBNV_RECOVERY_RW_DEV_SCREEN; + case BINF0_RECOVERY_RW_FW_BAD: + return VBNV_RECOVERY_RO_INVALID_RW; + case BINF0_RECOVERY_NO_OS: + return VBNV_RECOVERY_RW_NO_OS; + case BINF0_RECOVERY_BAD_OS: + return VBNV_RECOVERY_RW_INVALID_OS; + case BINF0_RECOVERY_OS_INITIATED: + return VBNV_RECOVERY_LEGACY; + default: + /* Other values don't map cleanly to firmware type. */ + return -1; + } } /* Physical GPIO number <N> may be accessed through /sys/class/gpio/gpio<M>/, @@ -465,24 +477,25 @@ static int VbGetRecoveryReason(void) { * exactly one match for that, we're SOL. */ static int FindGpioChipOffset(unsigned *gpio_num, unsigned *offset, - const char *name) { - DIR *dir; - struct dirent *ent; - int match = 0; - - dir = opendir(GPIO_BASE_PATH); - if (!dir) { - return 0; - } - - while(0 != (ent = readdir(dir))) { - if (1 == sscanf(ent->d_name, "gpiochip%u", offset)) { - match++; - } - } - - closedir(dir); - return (1 == match); + const char *name) +{ + DIR *dir; + struct dirent *ent; + int match = 0; + + dir = opendir(GPIO_BASE_PATH); + if (!dir) { + return 0; + } + + while(0 != (ent = readdir(dir))) { + if (1 == sscanf(ent->d_name, "gpiochip%u", offset)) { + match++; + } + } + + closedir(dir); + return (1 == match); } /* Physical GPIO number <N> may be accessed through /sys/class/gpio/gpio<M>/, @@ -491,100 +504,108 @@ static int FindGpioChipOffset(unsigned *gpio_num, unsigned *offset, * a 'label' file inside of it to find the expected the controller name. */ static int FindGpioChipOffsetByLabel(unsigned *gpio_num, unsigned *offset, - const char *name) { - DIR *dir; - struct dirent *ent; - char filename[128]; - char chiplabel[128]; - int match = 0; - unsigned controller_offset = 0; - - dir = opendir(GPIO_BASE_PATH); - if (!dir) { - return 0; - } - - while(0 != (ent = readdir(dir))) { - if (1 == sscanf(ent->d_name, "gpiochip%u", &controller_offset)) { - /* - * Read the file at gpiochip<O>/label to get the identifier - * for this bank of GPIOs. - */ - snprintf(filename, sizeof(filename), "%s/gpiochip%u/label", - GPIO_BASE_PATH, controller_offset); - if (ReadFileString(chiplabel, sizeof(chiplabel), filename)) { - if (!strncasecmp(chiplabel, name, strlen(name))) { - /* - * Store offset when chip label is matched. - */ - *offset = controller_offset; - match++; - } - } - } - } - - closedir(dir); - return (1 == match); + const char *name) +{ + DIR *dir; + struct dirent *ent; + char filename[128]; + char chiplabel[128]; + int match = 0; + unsigned controller_offset = 0; + + dir = opendir(GPIO_BASE_PATH); + if (!dir) { + return 0; + } + + while(0 != (ent = readdir(dir))) { + if (1 == sscanf(ent->d_name, "gpiochip%u", + &controller_offset)) { + /* + * Read the file at gpiochip<O>/label to get the + * identifier for this bank of GPIOs. + */ + snprintf(filename, sizeof(filename), + "%s/gpiochip%u/label", + GPIO_BASE_PATH, controller_offset); + if (ReadFileString(chiplabel, sizeof(chiplabel), + filename)) { + if (!strncasecmp(chiplabel, name, + strlen(name))) { + /* + * Store offset when chip label is + * matched. + */ + *offset = controller_offset; + match++; + } + } + } + } + + closedir(dir); + return (1 == match); } static int FindGpioChipOffsetByNumber(unsigned *gpio_num, unsigned *offset, - Basemapping *data) { - DIR *dir; - struct dirent *ent; - int match = 0; - - /* Obtain relative GPIO number. - * The assumption here is the Basemapping - * table is arranged in decreasing order of - * base address and ends with 0. - * A UID with value 0 indicates an invalid range - * and causes an early return to avoid the directory - * opening code below. - */ - do { - if (*gpio_num >= data->base) { - *gpio_num -= data->base; - break; - } - data++; - } while(1); - - if (data->uid == 0) { - return 0; - } - - dir = opendir(GPIO_BASE_PATH); - if (!dir) { - return 0; - } - - while(0 != (ent = readdir(dir))) { - /* For every gpiochip entry determine uid. */ - if (1 == sscanf(ent->d_name, "gpiochip%u", offset)) { - char uid_file[128]; - unsigned uid_value; - snprintf(uid_file, sizeof(uid_file), - "%s/gpiochip%u/device/firmware_node/uid", GPIO_BASE_PATH, - *offset); - if (ReadFileInt(uid_file, &uid_value) < 0) - continue; - if (data->uid == uid_value) { - match++; - break; - } - } - } - - closedir(dir); - return (1 == match); + Basemapping *data) +{ + DIR *dir; + struct dirent *ent; + int match = 0; + + /* Obtain relative GPIO number. + * The assumption here is the Basemapping + * table is arranged in decreasing order of + * base address and ends with 0. + * A UID with value 0 indicates an invalid range + * and causes an early return to avoid the directory + * opening code below. + */ + do { + if (*gpio_num >= data->base) { + *gpio_num -= data->base; + break; + } + data++; + } while(1); + + if (data->uid == 0) { + return 0; + } + + dir = opendir(GPIO_BASE_PATH); + if (!dir) { + return 0; + } + + while(0 != (ent = readdir(dir))) { + /* For every gpiochip entry determine uid. */ + if (1 == sscanf(ent->d_name, "gpiochip%u", offset)) { + char uid_file[128]; + unsigned uid_value; + snprintf(uid_file, sizeof(uid_file), + "%s/gpiochip%u/device/firmware_node/uid", + GPIO_BASE_PATH, *offset); + if (ReadFileInt(uid_file, &uid_value) < 0) + continue; + if (data->uid == uid_value) { + match++; + break; + } + } + } + + closedir(dir); + return (1 == match); } -/* Braswell has 4 sets of GPIO banks. It is expected the firmware exposes - * each bank of gpios using a UID in ACPI. Furthermore the gpio number exposed - * is relative to the bank. e.g. gpio MF_ISH_GPIO_4 in the bank specified by UID 3 +/* Braswell has 4 sets of GPIO banks. It is expected the firmware exposes each + * bank of gpios using a UID in ACPI. Furthermore the gpio number exposed is + * relative to the bank. e.g. gpio MF_ISH_GPIO_4 in the bank specified by UID 3 * would be encoded as 0x10016. + * * UID | Bank Offset * ----+------------ * 1 | 0x0000 @@ -593,15 +614,16 @@ static int FindGpioChipOffsetByNumber(unsigned *gpio_num, unsigned *offset, * 4 | 0x18000 */ static int BraswellFindGpioChipOffset(unsigned *gpio_num, unsigned *offset, - const char *name) { - static Basemapping data[]={ - {0x20000, 0}, - {0x18000, 4}, - {0x10000, 3}, - {0x08000, 2}, - {0x00000, 1}}; - - return FindGpioChipOffsetByNumber(gpio_num, offset, data); + const char *name) +{ + static Basemapping data[]={ + {0x20000, 0}, + {0x18000, 4}, + {0x10000, 3}, + {0x08000, 2}, + {0x00000, 1}}; + + return FindGpioChipOffsetByNumber(gpio_num, offset, data); } /* BayTrail has 3 sets of GPIO banks. It is expected the firmware exposes @@ -615,287 +637,303 @@ static int BraswellFindGpioChipOffset(unsigned *gpio_num, unsigned *offset, * 3 | 0x2000 */ static int BayTrailFindGpioChipOffset(unsigned *gpio_num, unsigned *offset, - const char *name) { - static Basemapping data[]={ - {0x3000, 0}, - {0x2000, 3}, - {0x1000, 2}, - {0x0000, 1}}; - - return FindGpioChipOffsetByNumber(gpio_num, offset, data); + const char *name) +{ + static Basemapping data[]={ + {0x3000, 0}, + {0x2000, 3}, + {0x1000, 2}, + {0x0000, 1}}; + + return FindGpioChipOffsetByNumber(gpio_num, offset, data); } struct GpioChipset { - const char *name; - int (*ChipOffsetAndGpioNumber)(unsigned *gpio_num, unsigned *chip_offset, - const char *name); + const char *name; + int (*ChipOffsetAndGpioNumber)(unsigned *gpio_num, + unsigned *chip_offset, + const char *name); }; static const struct GpioChipset chipsets_supported[] = { - { "NM10", FindGpioChipOffset }, - { "CougarPoint", FindGpioChipOffset }, - { "PantherPoint", FindGpioChipOffset }, - { "LynxPoint", FindGpioChipOffset }, - { "PCH-LP", FindGpioChipOffset }, - { "INT3437:00", FindGpioChipOffsetByLabel }, - { "INT344B:00", FindGpioChipOffsetByLabel }, - { "INT3452:00", FindGpioChipOffsetByLabel }, /* INT3452 are for Apollolake */ - { "INT3452:01", FindGpioChipOffsetByLabel }, - { "INT3452:02", FindGpioChipOffsetByLabel }, - { "INT3452:03", FindGpioChipOffsetByLabel }, - { "BayTrail", BayTrailFindGpioChipOffset }, - { "Braswell", BraswellFindGpioChipOffset }, - { NULL }, + { "NM10", FindGpioChipOffset }, + { "CougarPoint", FindGpioChipOffset }, + { "PantherPoint", FindGpioChipOffset }, + { "LynxPoint", FindGpioChipOffset }, + { "PCH-LP", FindGpioChipOffset }, + { "INT3437:00", FindGpioChipOffsetByLabel }, + { "INT344B:00", FindGpioChipOffsetByLabel }, + /* INT3452 are for Apollolake */ + { "INT3452:00", FindGpioChipOffsetByLabel }, + { "INT3452:01", FindGpioChipOffsetByLabel }, + { "INT3452:02", FindGpioChipOffsetByLabel }, + { "INT3452:03", FindGpioChipOffsetByLabel }, + { "BayTrail", BayTrailFindGpioChipOffset }, + { "Braswell", BraswellFindGpioChipOffset }, + { NULL }, }; -static const struct GpioChipset *FindChipset(const char *name) { - const struct GpioChipset *chipset = &chipsets_supported[0]; - - while (chipset->name != NULL) { - if (!strcmp(name, chipset->name)) - return chipset; - chipset++; - } - return NULL; +static const struct GpioChipset *FindChipset(const char *name) +{ + const struct GpioChipset *chipset = &chipsets_supported[0]; + + while (chipset->name != NULL) { + if (!strcmp(name, chipset->name)) + return chipset; + chipset++; + } + return NULL; } /* Read a GPIO of the specified signal type (see ACPI GPIO SignalType). * * Returns 1 if the signal is asserted, 0 if not asserted, or -1 if error. */ -static int ReadGpio(unsigned signal_type) { - char name[128]; - int index = 0; - unsigned gpio_type; - unsigned active_high; - unsigned controller_num; - unsigned controller_offset = 0; - char controller_name[128]; - unsigned value; - const struct GpioChipset *chipset; - - /* Scan GPIO.* to find a matching signal type */ - for (index = 0; ; index++) { - snprintf(name, sizeof(name), "%s.%d/GPIO.0", ACPI_GPIO_PATH, index); - if (ReadFileInt(name, &gpio_type) < 0) - return -1; /* Ran out of GPIOs before finding a match */ - if (gpio_type == signal_type) - break; - } - - /* Read attributes and controller info for the GPIO */ - snprintf(name, sizeof(name), "%s.%d/GPIO.1", ACPI_GPIO_PATH, index); - if (ReadFileInt(name, &active_high) < 0) - return -1; - snprintf(name, sizeof(name), "%s.%d/GPIO.2", ACPI_GPIO_PATH, index); - if (ReadFileInt(name, &controller_num) < 0) - return -1; - /* Do not attempt to read GPIO that is set to -1 in ACPI */ - if (controller_num == 0xFFFFFFFF) - return -1; - - /* Check for chipsets we recognize. */ - snprintf(name, sizeof(name), "%s.%d/GPIO.3", ACPI_GPIO_PATH, index); - if (!ReadFileString(controller_name, sizeof(controller_name), name)) - return -1; - chipset = FindChipset(controller_name); - if (chipset == NULL) - return -1; - - /* Modify GPIO number by driver's offset */ - if (!chipset->ChipOffsetAndGpioNumber(&controller_num, &controller_offset, - chipset->name)) - return -1; - controller_offset += controller_num; - - /* Try reading the GPIO value */ - snprintf(name, sizeof(name), "%s/gpio%d/value", - GPIO_BASE_PATH, controller_offset); - if (ReadFileInt(name, &value) < 0) { - /* Try exporting the GPIO */ - FILE* f = fopen(GPIO_EXPORT_PATH, "wt"); - if (!f) - return -1; - fprintf(f, "%u", controller_offset); - fclose(f); - - /* Try re-reading the GPIO value */ - if (ReadFileInt(name, &value) < 0) - return -1; - } - - /* Normalize the value read from the kernel in case it is not always 1. */ - value = value ? 1 : 0; - - /* Compare the GPIO value with the active value and return 1 if match. */ - return (value == active_high ? 1 : 0); +static int ReadGpio(unsigned signal_type) +{ + char name[128]; + int index = 0; + unsigned gpio_type; + unsigned active_high; + unsigned controller_num; + unsigned controller_offset = 0; + char controller_name[128]; + unsigned value; + const struct GpioChipset *chipset; + + /* Scan GPIO.* to find a matching signal type */ + for (index = 0; ; index++) { + snprintf(name, sizeof(name), "%s.%d/GPIO.0", ACPI_GPIO_PATH, + index); + if (ReadFileInt(name, &gpio_type) < 0) + return -1; /* Ran out of GPIOs before finding a match */ + if (gpio_type == signal_type) + break; + } + + /* Read attributes and controller info for the GPIO */ + snprintf(name, sizeof(name), "%s.%d/GPIO.1", ACPI_GPIO_PATH, index); + if (ReadFileInt(name, &active_high) < 0) + return -1; + snprintf(name, sizeof(name), "%s.%d/GPIO.2", ACPI_GPIO_PATH, index); + if (ReadFileInt(name, &controller_num) < 0) + return -1; + /* Do not attempt to read GPIO that is set to -1 in ACPI */ + if (controller_num == 0xFFFFFFFF) + return -1; + + /* Check for chipsets we recognize. */ + snprintf(name, sizeof(name), "%s.%d/GPIO.3", ACPI_GPIO_PATH, index); + if (!ReadFileString(controller_name, sizeof(controller_name), name)) + return -1; + chipset = FindChipset(controller_name); + if (chipset == NULL) + return -1; + + /* Modify GPIO number by driver's offset */ + if (!chipset->ChipOffsetAndGpioNumber(&controller_num, + &controller_offset, + chipset->name)) + return -1; + controller_offset += controller_num; + + /* Try reading the GPIO value */ + snprintf(name, sizeof(name), "%s/gpio%d/value", + GPIO_BASE_PATH, controller_offset); + if (ReadFileInt(name, &value) < 0) { + /* Try exporting the GPIO */ + FILE* f = fopen(GPIO_EXPORT_PATH, "wt"); + if (!f) + return -1; + fprintf(f, "%u", controller_offset); + fclose(f); + + /* Try re-reading the GPIO value */ + if (ReadFileInt(name, &value) < 0) + return -1; + } + + /* Normalize the value read from the kernel in case it is not always + * 1. */ + value = value ? 1 : 0; + + /* Compare the GPIO value with the active value and return 1 if + * match. */ + return (value == active_high ? 1 : 0); } -int VbGetArchPropertyInt(const char* name) { - int value = -1; - - /* Values from ACPI */ - if (!strcasecmp(name,"fmap_base")) { - unsigned fmap_base; - if (ReadFileInt(ACPI_FMAP_PATH, &fmap_base) < 0) - return -1; - else - value = (int)fmap_base; - } - - /* Switch positions */ - if (!strcasecmp(name,"devsw_cur")) { - /* Systems with virtual developer switches return at-boot value */ - int flags = VbGetSystemPropertyInt("vdat_flags"); - if ((flags != -1) && (flags & VBSD_HONOR_VIRT_DEV_SWITCH)) - value = VbGetSystemPropertyInt("devsw_boot"); - else - value = ReadGpio(GPIO_SIGNAL_TYPE_DEV); - } else if (!strcasecmp(name,"recoverysw_cur")) { - value = ReadGpio(GPIO_SIGNAL_TYPE_RECOVERY); - } else if (!strcasecmp(name,"wpsw_cur")) { - value = ReadGpio(GPIO_SIGNAL_TYPE_WP); - if (-1 != value && FwidStartsWith("Mario.")) - value = 1 - value; /* Mario reports this backwards */ - } else if (!strcasecmp(name,"recoverysw_ec_boot")) { - value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_EC_BOOT); - } - - /* Fields for old systems which don't have VbSharedData */ - if (VbSharedDataVersion() < 2) { - if (!strcasecmp(name,"recovery_reason")) { - value = VbGetRecoveryReason(); - } else if (!strcasecmp(name,"devsw_boot")) { - value = ReadFileBit(ACPI_CHSW_PATH, CHSW_DEV_BOOT); - } else if (!strcasecmp(name,"recoverysw_boot")) { - value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_BOOT); - } else if (!strcasecmp(name,"wpsw_boot")) { - value = ReadFileBit(ACPI_CHSW_PATH, CHSW_WP_BOOT); - if (-1 != value && FwidStartsWith("Mario.")) - value = 1 - value; /* Mario reports this backwards */ - } - } - - /* NV storage values. If unable to get from NV storage, fall back to the - * CMOS reboot field used by older BIOS (e.g. Mario). */ - if (!strcasecmp(name,"recovery_request")) { - value = VbGetNvStorage(VBNV_RECOVERY_REQUEST); - if (-1 == value) - value = VbGetCmosRebootField(CMOSRF_RECOVERY); - } else if (!strcasecmp(name,"dbg_reset")) { - value = VbGetNvStorage(VBNV_DEBUG_RESET_MODE); - if (-1 == value) - value = VbGetCmosRebootField(CMOSRF_DEBUG_RESET); - } else if (!strcasecmp(name,"fwb_tries")) { - value = VbGetNvStorage(VBNV_TRY_B_COUNT); - if (-1 == value) - value = VbGetCmosRebootField(CMOSRF_TRY_B); - } - - /* Firmware update tries is now stored in the kernel field. On - * older systems where it's not, it was stored in a file in the - * stateful partition. */ - if (!strcasecmp(name,"fwupdate_tries")) { - unsigned fwupdate_value; - if (-1 != VbGetNvStorage(VBNV_KERNEL_FIELD)) - return -1; /* NvStorage supported; fail through arch-specific - * implementation to normal implementation. */ - /* Read value from file; missing file means value=0. */ - if (ReadFileInt(NEED_FWUPDATE_PATH, &fwupdate_value) < 0) - value = 0; - else - value = (int)fwupdate_value; - } - - return value; +int VbGetArchPropertyInt(const char* name) +{ + int value = -1; + + /* Values from ACPI */ + if (!strcasecmp(name,"fmap_base")) { + unsigned fmap_base; + if (ReadFileInt(ACPI_FMAP_PATH, &fmap_base) < 0) + return -1; + else + value = (int)fmap_base; + } + + /* Switch positions */ + if (!strcasecmp(name,"devsw_cur")) { + /* Systems with virtual developer switches return at-boot + * value */ + int flags = VbGetSystemPropertyInt("vdat_flags"); + if ((flags != -1) && (flags & VBSD_HONOR_VIRT_DEV_SWITCH)) + value = VbGetSystemPropertyInt("devsw_boot"); + else + value = ReadGpio(GPIO_SIGNAL_TYPE_DEV); + } else if (!strcasecmp(name,"recoverysw_cur")) { + value = ReadGpio(GPIO_SIGNAL_TYPE_RECOVERY); + } else if (!strcasecmp(name,"wpsw_cur")) { + value = ReadGpio(GPIO_SIGNAL_TYPE_WP); + if (-1 != value && FwidStartsWith("Mario.")) + value = 1 - value; /* Mario reports this backwards */ + } else if (!strcasecmp(name,"recoverysw_ec_boot")) { + value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_EC_BOOT); + } + + /* Fields for old systems which don't have VbSharedData */ + if (VbSharedDataVersion() < 2) { + if (!strcasecmp(name,"recovery_reason")) { + value = VbGetRecoveryReason(); + } else if (!strcasecmp(name,"devsw_boot")) { + value = ReadFileBit(ACPI_CHSW_PATH, CHSW_DEV_BOOT); + } else if (!strcasecmp(name,"recoverysw_boot")) { + value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_BOOT); + } else if (!strcasecmp(name,"wpsw_boot")) { + value = ReadFileBit(ACPI_CHSW_PATH, CHSW_WP_BOOT); + if (-1 != value && FwidStartsWith("Mario.")) + value = 1 - value; /* Mario reports this + * backwards */ + } + } + + /* NV storage values. If unable to get from NV storage, fall back to + * the CMOS reboot field used by older BIOS (e.g. Mario). */ + if (!strcasecmp(name,"recovery_request")) { + value = VbGetNvStorage(VBNV_RECOVERY_REQUEST); + if (-1 == value) + value = VbGetCmosRebootField(CMOSRF_RECOVERY); + } else if (!strcasecmp(name,"dbg_reset")) { + value = VbGetNvStorage(VBNV_DEBUG_RESET_MODE); + if (-1 == value) + value = VbGetCmosRebootField(CMOSRF_DEBUG_RESET); + } else if (!strcasecmp(name,"fwb_tries")) { + value = VbGetNvStorage(VBNV_TRY_B_COUNT); + if (-1 == value) + value = VbGetCmosRebootField(CMOSRF_TRY_B); + } + + /* Firmware update tries is now stored in the kernel field. On + * older systems where it's not, it was stored in a file in the + * stateful partition. */ + if (!strcasecmp(name,"fwupdate_tries")) { + unsigned fwupdate_value; + if (-1 != VbGetNvStorage(VBNV_KERNEL_FIELD)) + return -1; /* NvStorage supported; fail through + * arch-specific implementation to normal + * implementation. */ + /* Read value from file; missing file means value=0. */ + if (ReadFileInt(NEED_FWUPDATE_PATH, &fwupdate_value) < 0) + value = 0; + else + value = (int)fwupdate_value; + } + + return value; } const char* VbGetArchPropertyString(const char* name, char* dest, - size_t size) { - unsigned value; - - if (!strcasecmp(name,"arch")) { - return StrCopy(dest, "x86", size); - } else if (!strcasecmp(name,"hwid")) { - return ReadFileString(dest, size, ACPI_BASE_PATH "/HWID"); - } else if (!strcasecmp(name,"fwid")) { - return ReadFileString(dest, size, ACPI_BASE_PATH "/FWID"); - } else if (!strcasecmp(name,"ro_fwid")) { - return ReadFileString(dest, size, ACPI_BASE_PATH "/FRID"); - } else if (!strcasecmp(name,"mainfw_act")) { - if (ReadFileInt(ACPI_BINF_PATH ".1", &value) < 0) - return NULL; - switch(value) { - case 0: - return StrCopy(dest, "recovery", size); - case 1: - return StrCopy(dest, "A", size); - case 2: - return StrCopy(dest, "B", size); - default: - return NULL; - } - } else if (!strcasecmp(name,"mainfw_type")) { - return VbReadMainFwType(dest, size); - } else if (!strcasecmp(name,"ecfw_act")) { - if (ReadFileInt(ACPI_BINF_PATH ".2", &value) < 0) - return NULL; - switch(value) { - case 0: - return StrCopy(dest, "RO", size); - case 1: - return StrCopy(dest, "RW", size); - default: - return NULL; - } - } - - return NULL; + size_t size) +{ + unsigned value; + + if (!strcasecmp(name,"arch")) { + return StrCopy(dest, "x86", size); + } else if (!strcasecmp(name,"hwid")) { + return ReadFileString(dest, size, ACPI_BASE_PATH "/HWID"); + } else if (!strcasecmp(name,"fwid")) { + return ReadFileString(dest, size, ACPI_BASE_PATH "/FWID"); + } else if (!strcasecmp(name,"ro_fwid")) { + return ReadFileString(dest, size, ACPI_BASE_PATH "/FRID"); + } else if (!strcasecmp(name,"mainfw_act")) { + if (ReadFileInt(ACPI_BINF_PATH ".1", &value) < 0) + return NULL; + switch(value) { + case 0: + return StrCopy(dest, "recovery", size); + case 1: + return StrCopy(dest, "A", size); + case 2: + return StrCopy(dest, "B", size); + default: + return NULL; + } + } else if (!strcasecmp(name,"mainfw_type")) { + return VbReadMainFwType(dest, size); + } else if (!strcasecmp(name,"ecfw_act")) { + if (ReadFileInt(ACPI_BINF_PATH ".2", &value) < 0) + return NULL; + switch(value) { + case 0: + return StrCopy(dest, "RO", size); + case 1: + return StrCopy(dest, "RW", size); + default: + return NULL; + } + } + + return NULL; } -int VbSetArchPropertyInt(const char* name, int value) { - /* NV storage values. If unable to get from NV storage, fall back to the - * CMOS reboot field used by older BIOS. */ - if (!strcasecmp(name,"recovery_request")) { - if (0 == VbSetNvStorage(VBNV_RECOVERY_REQUEST, value)) - return 0; - return VbSetCmosRebootField(CMOSRF_RECOVERY, value); - } else if (!strcasecmp(name,"dbg_reset")) { - if (0 == VbSetNvStorage(VBNV_DEBUG_RESET_MODE, value)) - return 0; - return VbSetCmosRebootField(CMOSRF_DEBUG_RESET, value); - } else if (!strcasecmp(name,"fwb_tries")) { - if (0 == VbSetNvStorage(VBNV_TRY_B_COUNT, value)) - return 0; - return VbSetCmosRebootField(CMOSRF_TRY_B, value); - } - /* Firmware update tries is now stored in the kernel field. On - * older systems where it's not, it was stored in a file in the - * stateful partition. */ - else if (!strcasecmp(name,"fwupdate_tries")) { - if (-1 != VbGetNvStorage(VBNV_KERNEL_FIELD)) - return -1; /* NvStorage supported; fail through arch-specific - * implementation to normal implementation */ - - if (value) { - char buf[32]; - snprintf(buf, sizeof(buf), "%d", value); - return WriteFile(NEED_FWUPDATE_PATH, buf, strlen(buf)); - } else { - /* No update tries, so remove file if it exists. */ - unlink(NEED_FWUPDATE_PATH); - return 0; - } - } - - return -1; +int VbSetArchPropertyInt(const char* name, int value) +{ + /* NV storage values. If unable to get from NV storage, fall back to + * the CMOS reboot field used by older BIOS. */ + if (!strcasecmp(name,"recovery_request")) { + if (0 == VbSetNvStorage(VBNV_RECOVERY_REQUEST, value)) + return 0; + return VbSetCmosRebootField(CMOSRF_RECOVERY, value); + } else if (!strcasecmp(name,"dbg_reset")) { + if (0 == VbSetNvStorage(VBNV_DEBUG_RESET_MODE, value)) + return 0; + return VbSetCmosRebootField(CMOSRF_DEBUG_RESET, value); + } else if (!strcasecmp(name,"fwb_tries")) { + if (0 == VbSetNvStorage(VBNV_TRY_B_COUNT, value)) + return 0; + return VbSetCmosRebootField(CMOSRF_TRY_B, value); + } + /* Firmware update tries is now stored in the kernel field. On + * older systems where it's not, it was stored in a file in the + * stateful partition. */ + else if (!strcasecmp(name,"fwupdate_tries")) { + if (-1 != VbGetNvStorage(VBNV_KERNEL_FIELD)) + return -1; /* NvStorage supported; fail through + * arch-specific implementation to normal + * implementation */ + + if (value) { + char buf[32]; + snprintf(buf, sizeof(buf), "%d", value); + return WriteFile(NEED_FWUPDATE_PATH, buf, strlen(buf)); + } else { + /* No update tries, so remove file if it exists. */ + unlink(NEED_FWUPDATE_PATH); + return 0; + } + } + + return -1; } - -int VbSetArchPropertyString(const char* name, const char* value) { - /* If there were settable architecture-dependent string properties, - * they'd be here. */ - return -1; +int VbSetArchPropertyString(const char* name, const char* value) +{ + /* If there were settable architecture-dependent string properties, + * they'd be here. */ + return -1; } diff --git a/host/include/cgpt_params.h b/host/include/cgpt_params.h index 92f0d3a4..10fc7fed 100644 --- a/host/include/cgpt_params.h +++ b/host/include/cgpt_params.h @@ -1,6 +1,7 @@ -// Copyright (c) 2013 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. +/* Copyright (c) 2013 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. + */ #ifndef VBOOT_REFERENCE_CGPT_CGPT_PARAMS_H_ #define VBOOT_REFERENCE_CGPT_CGPT_PARAMS_H_ @@ -9,114 +10,114 @@ #include "gpt.h" enum { - CGPT_OK = 0, - CGPT_FAILED, + CGPT_OK = 0, + CGPT_FAILED, }; typedef struct CgptCreateParams { - char *drive_name; - uint64_t drive_size; - int zap; - uint64_t padding; + char *drive_name; + uint64_t drive_size; + int zap; + uint64_t padding; } CgptCreateParams; typedef struct CgptAddParams { - char *drive_name; - uint64_t drive_size; - uint32_t partition; - uint64_t begin; - uint64_t size; - Guid type_guid; - Guid unique_guid; - char *label; - int successful; - int tries; - int priority; - int legacy_boot; - uint32_t raw_value; - int set_begin; - int set_size; - int set_type; - int set_unique; - int set_successful; - int set_tries; - int set_priority; - int set_legacy_boot; - int set_raw; + char *drive_name; + uint64_t drive_size; + uint32_t partition; + uint64_t begin; + uint64_t size; + Guid type_guid; + Guid unique_guid; + char *label; + int successful; + int tries; + int priority; + int legacy_boot; + uint32_t raw_value; + int set_begin; + int set_size; + int set_type; + int set_unique; + int set_successful; + int set_tries; + int set_priority; + int set_legacy_boot; + int set_raw; } CgptAddParams; typedef struct CgptShowParams { - char *drive_name; - uint64_t drive_size; - int numeric; - int verbose; - int quick; - uint32_t partition; - int single_item; - int debug; - int num_partitions; + char *drive_name; + uint64_t drive_size; + int numeric; + int verbose; + int quick; + uint32_t partition; + int single_item; + int debug; + int num_partitions; } CgptShowParams; typedef struct CgptRepairParams { - char *drive_name; - uint64_t drive_size; - int verbose; + char *drive_name; + uint64_t drive_size; + int verbose; } CgptRepairParams; typedef struct CgptBootParams { - char *drive_name; - uint64_t drive_size; - uint32_t partition; - char *bootfile; - int create_pmbr; + char *drive_name; + uint64_t drive_size; + uint32_t partition; + char *bootfile; + int create_pmbr; } CgptBootParams; typedef struct CgptPrioritizeParams { - char *drive_name; - uint64_t drive_size; - uint32_t set_partition; - int set_friends; - int max_priority; - int orig_priority; + char *drive_name; + uint64_t drive_size; + uint32_t set_partition; + int set_friends; + int max_priority; + int orig_priority; } CgptPrioritizeParams; struct CgptFindParams; typedef void (*CgptFindShowFn)(struct CgptFindParams *params, char *filename, int partnum, GptEntry *entry); typedef struct CgptFindParams { - char *drive_name; - uint64_t drive_size; - int verbose; - int set_unique; - int set_type; - int set_label; - int oneonly; - int numeric; - uint8_t *matchbuf; - uint64_t matchlen; - uint64_t matchoffset; - uint8_t *comparebuf; - Guid unique_guid; - Guid type_guid; - char *label; - int hits; - int match_partnum; /* 1-based; 0 means no match */ - /* when working with MTD, we actually work on a temp file, but we still need - * to print the device name. so this parameter is here to properly show the - * correct device name in that special case. */ - CgptFindShowFn show_fn; + char *drive_name; + uint64_t drive_size; + int verbose; + int set_unique; + int set_type; + int set_label; + int oneonly; + int numeric; + uint8_t *matchbuf; + uint64_t matchlen; + uint64_t matchoffset; + uint8_t *comparebuf; + Guid unique_guid; + Guid type_guid; + char *label; + int hits; + int match_partnum; /* 1-based; 0 means no match */ + /* when working with MTD, we actually work on a temp file, but we still + * need to print the device name. so this parameter is here to properly + * show the correct device name in that special case. */ + CgptFindShowFn show_fn; } CgptFindParams; enum { - CGPT_LEGACY_MODE_LEGACY = 0, - CGPT_LEGACY_MODE_EFIPART, - CGPT_LEGACY_MODE_IGNORE_PRIMARY, + CGPT_LEGACY_MODE_LEGACY = 0, + CGPT_LEGACY_MODE_EFIPART, + CGPT_LEGACY_MODE_IGNORE_PRIMARY, }; typedef struct CgptLegacyParams { - char *drive_name; - uint64_t drive_size; - int mode; + char *drive_name; + uint64_t drive_size; + int mode; } CgptLegacyParams; -#endif // VBOOT_REFERENCE_CGPT_CGPT_PARAMS_H_ +#endif /* VBOOT_REFERENCE_CGPT_CGPT_PARAMS_H_ */ diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c index 6d70d6aa..05126214 100644 --- a/host/lib/crossystem.c +++ b/host/lib/crossystem.c @@ -34,39 +34,39 @@ /* Fields that GetVdatString() can get */ typedef enum VdatStringField { - VDAT_STRING_TIMERS = 0, /* Timer values */ - VDAT_STRING_LOAD_FIRMWARE_DEBUG, /* LoadFirmware() debug information */ - VDAT_STRING_LOAD_KERNEL_DEBUG, /* LoadKernel() debug information */ - VDAT_STRING_MAINFW_ACT /* Active main firmware */ + VDAT_STRING_TIMERS = 0, /* Timer values */ + VDAT_STRING_LOAD_FIRMWARE_DEBUG, /* LoadFirmware() debug information */ + VDAT_STRING_LOAD_KERNEL_DEBUG, /* LoadKernel() debug information */ + VDAT_STRING_MAINFW_ACT /* Active main firmware */ } VdatStringField; /* Fields that GetVdatInt() can get */ typedef enum VdatIntField { - VDAT_INT_FLAGS = 0, /* Flags */ - VDAT_INT_HEADER_VERSION, /* Header version for VbSharedData */ - VDAT_INT_DEVSW_BOOT, /* Dev switch position at boot */ - VDAT_INT_DEVSW_VIRTUAL, /* Dev switch is virtual */ - VDAT_INT_RECSW_BOOT, /* Recovery switch position at boot */ - VDAT_INT_HW_WPSW_BOOT, /* Hardware WP switch position at boot */ - VDAT_INT_SW_WPSW_BOOT, /* Flash chip's WP setting at boot */ - - VDAT_INT_FW_VERSION_TPM, /* Current firmware version in TPM */ - VDAT_INT_KERNEL_VERSION_TPM, /* Current kernel version in TPM */ - VDAT_INT_TRIED_FIRMWARE_B, /* Tried firmware B due to fwb_tries */ - VDAT_INT_KERNEL_KEY_VERIFIED, /* Kernel key verified using - * signature, not just hash */ - VDAT_INT_RECOVERY_REASON, /* Recovery reason for current boot */ - VDAT_INT_FW_BOOT2 /* Firmware selection by vboot2 */ + VDAT_INT_FLAGS = 0, /* Flags */ + VDAT_INT_HEADER_VERSION, /* Header version for VbSharedData */ + VDAT_INT_DEVSW_BOOT, /* Dev switch position at boot */ + VDAT_INT_DEVSW_VIRTUAL, /* Dev switch is virtual */ + VDAT_INT_RECSW_BOOT, /* Recovery switch position at boot */ + VDAT_INT_HW_WPSW_BOOT, /* Hardware WP switch position at boot */ + VDAT_INT_SW_WPSW_BOOT, /* Flash chip's WP setting at boot */ + + VDAT_INT_FW_VERSION_TPM, /* Current firmware version in TPM */ + VDAT_INT_KERNEL_VERSION_TPM, /* Current kernel version in TPM */ + VDAT_INT_TRIED_FIRMWARE_B, /* Tried firmware B due to fwb_tries */ + VDAT_INT_KERNEL_KEY_VERIFIED, /* Kernel key verified using + * signature, not just hash */ + VDAT_INT_RECOVERY_REASON, /* Recovery reason for current boot */ + VDAT_INT_FW_BOOT2 /* Firmware selection by vboot2 */ } VdatIntField; /* Description of build options that may be specified on the * kernel command line. */ typedef enum VbBuildOption { - VB_BUILD_OPTION_UNKNOWN, - VB_BUILD_OPTION_DEBUG, - VB_BUILD_OPTION_NODEBUG + VB_BUILD_OPTION_UNKNOWN, + VB_BUILD_OPTION_DEBUG, + VB_BUILD_OPTION_NODEBUG } VbBuildOption; static const char *fw_results[] = {"unknown", "trying", "success", "failure"}; @@ -83,72 +83,74 @@ static const char *default_boot[] = {"disk", "usb", "legacy"}; #define KERN_NV_CURRENTLY_UNUSED 0xFFFFFFC0 /* Return true if the FWID starts with the specified string. */ -int FwidStartsWith(const char *start) { - char fwid[VB_MAX_STRING_PROPERTY]; - if (!VbGetSystemPropertyString("fwid", fwid, sizeof(fwid))) - return 0; +int FwidStartsWith(const char *start) +{ + char fwid[VB_MAX_STRING_PROPERTY]; + if (!VbGetSystemPropertyString("fwid", fwid, sizeof(fwid))) + return 0; - return 0 == strncmp(fwid, start, strlen(start)); + return 0 == strncmp(fwid, start, strlen(start)); } static int vnc_read; -int VbGetNvStorage(VbNvParam param) { - uint32_t value; - int retval; - static VbNvContext cached_vnc; - - /* TODO: locking around NV access */ - if (!vnc_read) { - if (0 != VbReadNvStorage(&cached_vnc)) - return -1; - vnc_read = 1; - } - - if (0 != VbNvSetup(&cached_vnc)) - return -1; - retval = VbNvGet(&cached_vnc, param, &value); - if (0 != VbNvTeardown(&cached_vnc)) - return -1; - if (0 != retval) - return -1; - - /* TODO: If vnc.raw_changed, attempt to reopen NVRAM for write and - * save the new defaults. If we're able to, log. */ - /* TODO: release lock */ - - return (int)value; -} - +int VbGetNvStorage(VbNvParam param) +{ + uint32_t value; + int retval; + static VbNvContext cached_vnc; + + /* TODO: locking around NV access */ + if (!vnc_read) { + if (0 != VbReadNvStorage(&cached_vnc)) + return -1; + vnc_read = 1; + } -int VbSetNvStorage(VbNvParam param, int value) { - VbNvContext vnc; - int retval = -1; - int i; + if (0 != VbNvSetup(&cached_vnc)) + return -1; + retval = VbNvGet(&cached_vnc, param, &value); + if (0 != VbNvTeardown(&cached_vnc)) + return -1; + if (0 != retval) + return -1; - if (0 != VbReadNvStorage(&vnc)) - return -1; + /* TODO: If vnc.raw_changed, attempt to reopen NVRAM for write and + * save the new defaults. If we're able to, log. */ + /* TODO: release lock */ - if (0 != VbNvSetup(&vnc)) - goto VbSetNvCleanup; - i = VbNvSet(&vnc, param, (uint32_t)value); - if (0 != VbNvTeardown(&vnc)) - goto VbSetNvCleanup; - if (0 != i) - goto VbSetNvCleanup; + return (int)value; +} - if (vnc.raw_changed) { - vnc_read = 0; - if (0 != VbWriteNvStorage(&vnc)) - goto VbSetNvCleanup; - } +int VbSetNvStorage(VbNvParam param, int value) +{ + VbNvContext vnc; + int retval = -1; + int i; + + if (0 != VbReadNvStorage(&vnc)) + return -1; + + if (0 != VbNvSetup(&vnc)) + goto VbSetNvCleanup; + i = VbNvSet(&vnc, param, (uint32_t)value); + if (0 != VbNvTeardown(&vnc)) + goto VbSetNvCleanup; + if (0 != i) + goto VbSetNvCleanup; + + if (vnc.raw_changed) { + vnc_read = 0; + if (0 != VbWriteNvStorage(&vnc)) + goto VbSetNvCleanup; + } - /* Success */ - retval = 0; + /* Success */ + retval = 0; VbSetNvCleanup: - /* TODO: release lock */ - return retval; + /* TODO: release lock */ + return retval; } /* @@ -157,596 +159,611 @@ VbSetNvCleanup: */ static int VbSetNvStorage_WithBackup(VbNvParam param, int value) { - int retval; - retval = VbSetNvStorage(param, value); - if (!retval) - VbSetNvStorage(VBNV_BACKUP_NVRAM_REQUEST, 1); - return retval; + int retval; + retval = VbSetNvStorage(param, value); + if (!retval) + VbSetNvStorage(VBNV_BACKUP_NVRAM_REQUEST, 1); + return retval; } /* Find what build/debug status is specified on the kernel command * line, if any. */ -static VbBuildOption VbScanBuildOption(void) { - FILE* f = NULL; - char buf[4096] = ""; - char *t, *saveptr; - const char *delimiters = " \r\n"; - - f = fopen(KERNEL_CMDLINE_PATH, "r"); - if (NULL != f) { - if (NULL == fgets(buf, sizeof(buf), f)) - buf[0] = 0; - fclose(f); - } - for (t = strtok_r(buf, delimiters, &saveptr); t; - t = strtok_r(NULL, delimiters, &saveptr)) { - if (0 == strcmp(t, "cros_debug")) - return VB_BUILD_OPTION_DEBUG; - else if (0 == strcmp(t, "cros_nodebug")) - return VB_BUILD_OPTION_NODEBUG; - } - - return VB_BUILD_OPTION_UNKNOWN; -} +static VbBuildOption VbScanBuildOption(void) +{ + FILE* f = NULL; + char buf[4096] = ""; + char *t, *saveptr; + const char *delimiters = " \r\n"; + + f = fopen(KERNEL_CMDLINE_PATH, "r"); + if (NULL != f) { + if (NULL == fgets(buf, sizeof(buf), f)) + buf[0] = 0; + fclose(f); + } + for (t = strtok_r(buf, delimiters, &saveptr); t; + t = strtok_r(NULL, delimiters, &saveptr)) { + if (0 == strcmp(t, "cros_debug")) + return VB_BUILD_OPTION_DEBUG; + else if (0 == strcmp(t, "cros_nodebug")) + return VB_BUILD_OPTION_NODEBUG; + } + return VB_BUILD_OPTION_UNKNOWN; +} /* Determine whether the running OS image was built for debugging. * Returns 1 if yes, 0 if no or indeterminate. */ -int VbGetDebugBuild(void) { - return VB_BUILD_OPTION_DEBUG == VbScanBuildOption(); +int VbGetDebugBuild(void) +{ + return VB_BUILD_OPTION_DEBUG == VbScanBuildOption(); } - /* Determine whether OS-level debugging should be allowed. * Returns 1 if yes, 0 if no or indeterminate. */ -int VbGetCrosDebug(void) { - /* If the currently running system specifies its debug status, use - * that in preference to other indicators. */ - VbBuildOption option = VbScanBuildOption(); - if (VB_BUILD_OPTION_DEBUG == option) { - return 1; - } else if (VB_BUILD_OPTION_NODEBUG == option) { - return 0; - } - - /* Command line is silent; allow debug if the dev switch is on. */ - if (1 == VbGetSystemPropertyInt("devsw_boot")) - return 1; - - /* All other cases disallow debug. */ - return 0; -} +int VbGetCrosDebug(void) +{ + /* If the currently running system specifies its debug status, use + * that in preference to other indicators. */ + VbBuildOption option = VbScanBuildOption(); + if (VB_BUILD_OPTION_DEBUG == option) { + return 1; + } else if (VB_BUILD_OPTION_NODEBUG == option) { + return 0; + } + /* Command line is silent; allow debug if the dev switch is on. */ + if (1 == VbGetSystemPropertyInt("devsw_boot")) + return 1; -char* GetVdatLoadFirmwareDebug(char* dest, int size, - const VbSharedDataHeader* sh) { - snprintf(dest, size, - "Check A result=%d\n" - "Check B result=%d\n" - "Firmware index booted=0x%02x\n" - "TPM combined version at start=0x%08x\n" - "Lowest combined version from firmware=0x%08x\n", - sh->check_fw_a_result, - sh->check_fw_b_result, - sh->firmware_index, - sh->fw_version_tpm_start, - sh->fw_version_lowest); - return dest; + /* All other cases disallow debug. */ + return 0; } +char *GetVdatLoadFirmwareDebug(char *dest, int size, + const VbSharedDataHeader *sh) +{ + snprintf(dest, size, + "Check A result=%d\n" + "Check B result=%d\n" + "Firmware index booted=0x%02x\n" + "TPM combined version at start=0x%08x\n" + "Lowest combined version from firmware=0x%08x\n", + sh->check_fw_a_result, + sh->check_fw_b_result, + sh->firmware_index, + sh->fw_version_tpm_start, + sh->fw_version_lowest); + return dest; +} #define TRUNCATED "\n(truncated)\n" -char* GetVdatLoadKernelDebug(char* dest, int size, - const VbSharedDataHeader* sh) { - int used = 0; - int first_call_tracked = 0; - int call; - - /* Make sure we have space for truncation warning */ - if (size < strlen(TRUNCATED) + 1) - return NULL; - size -= strlen(TRUNCATED) + 1; - - used += snprintf( - dest + used, size - used, - "Calls to LoadKernel()=%d\n", - sh->lk_call_count); - if (used > size) - goto LoadKernelDebugExit; - - /* Report on the last calls */ - if (sh->lk_call_count > VBSD_MAX_KERNEL_CALLS) - first_call_tracked = sh->lk_call_count - VBSD_MAX_KERNEL_CALLS; - for (call = first_call_tracked; call < sh->lk_call_count; call++) { - const VbSharedDataKernelCall* shc = - sh->lk_calls + (call & (VBSD_MAX_KERNEL_CALLS - 1)); - int first_part_tracked = 0; - int part; - - used += snprintf( - dest + used, size - used, - "Call %d:\n" - " Boot flags=0x%02x\n" - " Boot mode=%d\n" - " Test error=%d\n" - " Return code=%d\n" - " Debug flags=0x%02x\n" - " Drive sectors=%" PRIu64 "\n" - " Sector size=%d\n" - " Check result=%d\n" - " Kernel partitions found=%d\n", - call + 1, - shc->boot_flags, - shc->boot_mode, - shc->test_error_num, - shc->return_code, - shc->flags, - shc->sector_count, - shc->sector_size, - shc->check_result, - shc->kernel_parts_found); - if (used > size) - goto LoadKernelDebugExit; - - /* If we found too many partitions, only prints ones where the - * structure has info. */ - if (shc->kernel_parts_found > VBSD_MAX_KERNEL_PARTS) - first_part_tracked = shc->kernel_parts_found - VBSD_MAX_KERNEL_PARTS; - - /* Report on the partitions checked */ - for (part = first_part_tracked; part < shc->kernel_parts_found; part++) { - const VbSharedDataKernelPart* shp = - shc->parts + (part & (VBSD_MAX_KERNEL_PARTS - 1)); - - used += snprintf( - dest + used, size - used, - " Kernel %d:\n" - " GPT index=%d\n" - " Start sector=%" PRIu64 "\n" - " Sector count=%" PRIu64 "\n" - " Combined version=0x%08x\n" - " Check result=%d\n" - " Debug flags=0x%02x\n", - part + 1, - shp->gpt_index, - shp->sector_start, - shp->sector_count, - shp->combined_version, - shp->check_result, - shp->flags); - if (used > size) - goto LoadKernelDebugExit; - } - } +char *GetVdatLoadKernelDebug(char *dest, int size, + const VbSharedDataHeader *sh) +{ + int used = 0; + int first_call_tracked = 0; + int call; + + /* Make sure we have space for truncation warning */ + if (size < strlen(TRUNCATED) + 1) + return NULL; + size -= strlen(TRUNCATED) + 1; + + used += snprintf( + dest + used, size - used, + "Calls to LoadKernel()=%d\n", + sh->lk_call_count); + if (used > size) + goto LoadKernelDebugExit; + + /* Report on the last calls */ + if (sh->lk_call_count > VBSD_MAX_KERNEL_CALLS) + first_call_tracked = sh->lk_call_count - VBSD_MAX_KERNEL_CALLS; + for (call = first_call_tracked; call < sh->lk_call_count; call++) { + const VbSharedDataKernelCall* shc = sh->lk_calls + + (call & (VBSD_MAX_KERNEL_CALLS - 1)); + int first_part_tracked = 0; + int part; + + used += snprintf(dest + used, size - used, + "Call %d:\n" + " Boot flags=0x%02x\n" + " Boot mode=%d\n" + " Test error=%d\n" + " Return code=%d\n" + " Debug flags=0x%02x\n" + " Drive sectors=%" PRIu64 "\n" + " Sector size=%d\n" + " Check result=%d\n" + " Kernel partitions found=%d\n", + call + 1, + shc->boot_flags, + shc->boot_mode, + shc->test_error_num, + shc->return_code, + shc->flags, + shc->sector_count, + shc->sector_size, + shc->check_result, + shc->kernel_parts_found); + if (used > size) + goto LoadKernelDebugExit; + + /* If we found too many partitions, only prints ones where the + * structure has info. */ + if (shc->kernel_parts_found > VBSD_MAX_KERNEL_PARTS) + first_part_tracked = shc->kernel_parts_found - + VBSD_MAX_KERNEL_PARTS; + + /* Report on the partitions checked */ + for (part = first_part_tracked; part < shc->kernel_parts_found; + part++) { + const VbSharedDataKernelPart* shp = shc->parts + + (part & (VBSD_MAX_KERNEL_PARTS - 1)); + + used += snprintf(dest + used, size - used, + " Kernel %d:\n" + " GPT index=%d\n" + " Start sector=%" PRIu64 "\n" + " Sector count=%" PRIu64 "\n" + " Combined version=0x%08x\n" + " Check result=%d\n" + " Debug flags=0x%02x\n", + part + 1, + shp->gpt_index, + shp->sector_start, + shp->sector_count, + shp->combined_version, + shp->check_result, + shp->flags); + if (used > size) + goto LoadKernelDebugExit; + } + } LoadKernelDebugExit: - /* Warn if data was truncated; we left space for this above. */ - if (used > size) - strcat(dest, TRUNCATED); + /* Warn if data was truncated; we left space for this above. */ + if (used > size) + strcat(dest, TRUNCATED); - return dest; + return dest; } - -char* GetVdatString(char* dest, int size, VdatStringField field) +char *GetVdatString(char *dest, int size, VdatStringField field) { - VbSharedDataHeader* sh = VbSharedDataRead(); - char* value = dest; - - if (!sh) - return NULL; - - switch (field) { - case VDAT_STRING_TIMERS: - snprintf(dest, size, - "LFS=%" PRIu64 ",%" PRIu64 - " LF=%" PRIu64 ",%" PRIu64 - " LK=%" PRIu64 ",%" PRIu64, - sh->timer_vb_init_enter, - sh->timer_vb_init_exit, - sh->timer_vb_select_firmware_enter, - sh->timer_vb_select_firmware_exit, - sh->timer_vb_select_and_load_kernel_enter, - sh->timer_vb_select_and_load_kernel_exit); - break; - - case VDAT_STRING_LOAD_FIRMWARE_DEBUG: - value = GetVdatLoadFirmwareDebug(dest, size, sh); - break; - - case VDAT_STRING_LOAD_KERNEL_DEBUG: - value = GetVdatLoadKernelDebug(dest, size, sh); - break; - - case VDAT_STRING_MAINFW_ACT: - switch(sh->firmware_index) { - case 0: - StrCopy(dest, "A", size); - break; - case 1: - StrCopy(dest, "B", size); - break; - case 0xFF: - StrCopy(dest, "recovery", size); - break; - default: - value = NULL; - } - break; - - default: - value = NULL; - break; - } - - free(sh); - return value; + VbSharedDataHeader *sh = VbSharedDataRead(); + char *value = dest; + + if (!sh) + return NULL; + + switch (field) { + case VDAT_STRING_TIMERS: + snprintf(dest, size, + "LFS=%" PRIu64 ",%" PRIu64 + " LF=%" PRIu64 ",%" PRIu64 + " LK=%" PRIu64 ",%" PRIu64, + sh->timer_vb_init_enter, + sh->timer_vb_init_exit, + sh->timer_vb_select_firmware_enter, + sh->timer_vb_select_firmware_exit, + sh->timer_vb_select_and_load_kernel_enter, + sh->timer_vb_select_and_load_kernel_exit); + break; + + case VDAT_STRING_LOAD_FIRMWARE_DEBUG: + value = GetVdatLoadFirmwareDebug(dest, size, sh); + break; + + case VDAT_STRING_LOAD_KERNEL_DEBUG: + value = GetVdatLoadKernelDebug(dest, size, sh); + break; + + case VDAT_STRING_MAINFW_ACT: + switch(sh->firmware_index) { + case 0: + StrCopy(dest, "A", size); + break; + case 1: + StrCopy(dest, "B", size); + break; + case 0xFF: + StrCopy(dest, "recovery", size); + break; + default: + value = NULL; + } + break; + + default: + value = NULL; + break; + } + + free(sh); + return value; } +int GetVdatInt(VdatIntField field) +{ + VbSharedDataHeader* sh = VbSharedDataRead(); + int value = -1; + + if (!sh) + return -1; + + /* Fields supported in version 1 */ + switch (field) { + case VDAT_INT_FLAGS: + value = (int)sh->flags; + break; + case VDAT_INT_HEADER_VERSION: + value = sh->struct_version; + break; + case VDAT_INT_TRIED_FIRMWARE_B: + value = (sh->flags & VBSD_FWB_TRIED ? 1 : 0); + break; + case VDAT_INT_KERNEL_KEY_VERIFIED: + value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0); + break; + case VDAT_INT_FW_VERSION_TPM: + value = (int)sh->fw_version_tpm; + break; + case VDAT_INT_KERNEL_VERSION_TPM: + value = (int)sh->kernel_version_tpm; + break; + case VDAT_INT_FW_BOOT2: + value = (sh->flags & VBSD_BOOT_FIRMWARE_VBOOT2 ? 1 : 0); + default: + break; + } + + /* Fields added in struct version 2 */ + if (sh->struct_version >= 2) { + switch(field) { + case VDAT_INT_DEVSW_BOOT: + value = (sh->flags & + VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0); + break; + case VDAT_INT_DEVSW_VIRTUAL: + value = (sh->flags & + VBSD_HONOR_VIRT_DEV_SWITCH ? 1 : 0); + break; + case VDAT_INT_RECSW_BOOT: + value = (sh->flags & + VBSD_BOOT_REC_SWITCH_ON ? 1 : 0); + break; + case VDAT_INT_HW_WPSW_BOOT: + value = (sh->flags & + VBSD_BOOT_FIRMWARE_WP_ENABLED ? 1 : 0); + break; + case VDAT_INT_SW_WPSW_BOOT: + value = (sh->flags & + VBSD_BOOT_FIRMWARE_SW_WP_ENABLED ? + 1 : 0); + break; + case VDAT_INT_RECOVERY_REASON: + value = sh->recovery_reason; + break; + default: + break; + } + } -int GetVdatInt(VdatIntField field) { - VbSharedDataHeader* sh = VbSharedDataRead(); - int value = -1; - - if (!sh) - return -1; - - /* Fields supported in version 1 */ - switch (field) { - case VDAT_INT_FLAGS: - value = (int)sh->flags; - break; - case VDAT_INT_HEADER_VERSION: - value = sh->struct_version; - break; - case VDAT_INT_TRIED_FIRMWARE_B: - value = (sh->flags & VBSD_FWB_TRIED ? 1 : 0); - break; - case VDAT_INT_KERNEL_KEY_VERIFIED: - value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0); - break; - case VDAT_INT_FW_VERSION_TPM: - value = (int)sh->fw_version_tpm; - break; - case VDAT_INT_KERNEL_VERSION_TPM: - value = (int)sh->kernel_version_tpm; - break; - case VDAT_INT_FW_BOOT2: - value = (sh->flags & VBSD_BOOT_FIRMWARE_VBOOT2 ? 1 : 0); - default: - break; - } - - /* Fields added in struct version 2 */ - if (sh->struct_version >= 2) { - switch(field) { - case VDAT_INT_DEVSW_BOOT: - value = (sh->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0); - break; - case VDAT_INT_DEVSW_VIRTUAL: - value = (sh->flags & VBSD_HONOR_VIRT_DEV_SWITCH ? 1 : 0); - break; - case VDAT_INT_RECSW_BOOT: - value = (sh->flags & VBSD_BOOT_REC_SWITCH_ON ? 1 : 0); - break; - case VDAT_INT_HW_WPSW_BOOT: - value = (sh->flags & VBSD_BOOT_FIRMWARE_WP_ENABLED ? 1 : 0); - break; - case VDAT_INT_SW_WPSW_BOOT: - value = (sh->flags & VBSD_BOOT_FIRMWARE_SW_WP_ENABLED ? 1 : 0); - break; - case VDAT_INT_RECOVERY_REASON: - value = sh->recovery_reason; - break; - default: - break; - } - } - - free(sh); - return value; + free(sh); + return value; } /* Return version of VbSharedData struct or -1 if not found. */ -int VbSharedDataVersion(void) { - return GetVdatInt(VDAT_INT_HEADER_VERSION); +int VbSharedDataVersion(void) +{ + return GetVdatInt(VDAT_INT_HEADER_VERSION); } -int VbGetSystemPropertyInt(const char* name) { - int value = -1; - - /* Check architecture-dependent properties first */ - value = VbGetArchPropertyInt(name); - if (-1 != value) - return value; - - /* NV storage values */ - else if (!strcasecmp(name,"kern_nv")) { - value = VbGetNvStorage(VBNV_KERNEL_FIELD); - } else if (!strcasecmp(name,"nvram_cleared")) { - value = VbGetNvStorage(VBNV_KERNEL_SETTINGS_RESET); - } else if (!strcasecmp(name,"recovery_request")) { - value = VbGetNvStorage(VBNV_RECOVERY_REQUEST); - } else if (!strcasecmp(name,"dbg_reset")) { - value = VbGetNvStorage(VBNV_DEBUG_RESET_MODE); - } else if (!strcasecmp(name,"disable_dev_request")) { - value = VbGetNvStorage(VBNV_DISABLE_DEV_REQUEST); - } else if (!strcasecmp(name,"clear_tpm_owner_request")) { - value = VbGetNvStorage(VBNV_CLEAR_TPM_OWNER_REQUEST); - } else if (!strcasecmp(name,"clear_tpm_owner_done")) { - value = VbGetNvStorage(VBNV_CLEAR_TPM_OWNER_DONE); - } else if (!strcasecmp(name,"tpm_rebooted")) { - value = VbGetNvStorage(VBNV_TPM_REQUESTED_REBOOT); - } else if (!strcasecmp(name,"fwb_tries")) { - value = VbGetNvStorage(VBNV_TRY_B_COUNT); - } else if (!strcasecmp(name,"fw_vboot2")) { - value = GetVdatInt(VDAT_INT_FW_BOOT2); - } else if (!strcasecmp(name,"fw_try_count")) { - value = VbGetNvStorage(VBNV_FW_TRY_COUNT); - } else if (!strcasecmp(name,"fwupdate_tries")) { - value = VbGetNvStorage(VBNV_KERNEL_FIELD); - if (value != -1) - value &= KERN_NV_FWUPDATE_TRIES_MASK; - } else if (!strcasecmp(name,"block_devmode")) { - value = VbGetNvStorage(VBNV_KERNEL_FIELD); - if (value != -1) { - value &= KERN_NV_BLOCK_DEVMODE_FLAG; - value = !!value; - } - } else if (!strcasecmp(name,"tpm_attack")) { - value = VbGetNvStorage(VBNV_KERNEL_FIELD); - if (value != -1) { - value &= KERN_NV_TPM_ATTACK_FLAG; - value = !!value; - } - } else if (!strcasecmp(name,"loc_idx")) { - value = VbGetNvStorage(VBNV_LOCALIZATION_INDEX); - } else if (!strcasecmp(name,"backup_nvram_request")) { - value = VbGetNvStorage(VBNV_BACKUP_NVRAM_REQUEST); - } else if (!strcasecmp(name,"dev_boot_usb")) { - value = VbGetNvStorage(VBNV_DEV_BOOT_USB); - } else if (!strcasecmp(name,"dev_boot_legacy")) { - value = VbGetNvStorage(VBNV_DEV_BOOT_LEGACY); - } else if (!strcasecmp(name,"dev_boot_signed_only")) { - value = VbGetNvStorage(VBNV_DEV_BOOT_SIGNED_ONLY); - } else if (!strcasecmp(name,"dev_boot_fastboot_full_cap")) { - value = VbGetNvStorage(VBNV_DEV_BOOT_FASTBOOT_FULL_CAP); - } else if (!strcasecmp(name,"oprom_needed")) { - value = VbGetNvStorage(VBNV_OPROM_NEEDED); - } else if (!strcasecmp(name,"recovery_subcode")) { - value = VbGetNvStorage(VBNV_RECOVERY_SUBCODE); - } else if (!strcasecmp(name,"wipeout_request")) { - value = VbGetNvStorage(VBNV_FW_REQ_WIPEOUT); - } - /* Other parameters */ - else if (!strcasecmp(name,"cros_debug")) { - value = VbGetCrosDebug(); - } else if (!strcasecmp(name,"debug_build")) { - value = VbGetDebugBuild(); - } else if (!strcasecmp(name,"devsw_boot")) { - value = GetVdatInt(VDAT_INT_DEVSW_BOOT); - } else if (!strcasecmp(name,"devsw_virtual")) { - value = GetVdatInt(VDAT_INT_DEVSW_VIRTUAL); - } else if (!strcasecmp(name, "recoverysw_boot")) { - value = GetVdatInt(VDAT_INT_RECSW_BOOT); - } else if (!strcasecmp(name, "wpsw_boot")) { - value = GetVdatInt(VDAT_INT_HW_WPSW_BOOT); - } else if (!strcasecmp(name, "sw_wpsw_boot")) { - value = GetVdatInt(VDAT_INT_SW_WPSW_BOOT); - } else if (!strcasecmp(name,"vdat_flags")) { - value = GetVdatInt(VDAT_INT_FLAGS); - } else if (!strcasecmp(name,"tpm_fwver")) { - value = GetVdatInt(VDAT_INT_FW_VERSION_TPM); - } else if (!strcasecmp(name,"tpm_kernver")) { - value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM); - } else if (!strcasecmp(name,"tried_fwb")) { - value = GetVdatInt(VDAT_INT_TRIED_FIRMWARE_B); - } else if (!strcasecmp(name,"recovery_reason")) { - value = GetVdatInt(VDAT_INT_RECOVERY_REASON); - } else if (!strcasecmp(name, "fastboot_unlock_in_fw")) { - value = VbGetNvStorage(VBNV_FASTBOOT_UNLOCK_IN_FW); - } else if (!strcasecmp(name, "boot_on_ac_detect")) { - value = VbGetNvStorage(VBNV_BOOT_ON_AC_DETECT); - } else if (!strcasecmp(name, "try_ro_sync")) { - value = VbGetNvStorage(VBNV_TRY_RO_SYNC); - } else if (!strcasecmp(name, "battery_cutoff_request")) { - value = VbGetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST); - } else if (!strcasecmp(name, "inside_vm")) { - /* Detect if the host is a VM. If there is no HWID and the firmware type - * is "nonchrome", then assume it is a VM. If HWID is present, it is a - * baremetal Chrome OS machine. Other cases are errors. */ - char hwid[VB_MAX_STRING_PROPERTY]; - if (!VbGetSystemPropertyString("hwid", hwid, sizeof(hwid))) { - char fwtype_buf[VB_MAX_STRING_PROPERTY]; - const char *fwtype = VbGetSystemPropertyString("mainfw_type", fwtype_buf, - sizeof(fwtype_buf)); - if (fwtype && !strcasecmp(fwtype, "nonchrome")) { - value = 1; - } - } else { - value = 0; - } - } - - return value; +int VbGetSystemPropertyInt(const char *name) +{ + int value = -1; + + /* Check architecture-dependent properties first */ + value = VbGetArchPropertyInt(name); + if (-1 != value) + return value; + + /* NV storage values */ + else if (!strcasecmp(name,"kern_nv")) { + value = VbGetNvStorage(VBNV_KERNEL_FIELD); + } else if (!strcasecmp(name,"nvram_cleared")) { + value = VbGetNvStorage(VBNV_KERNEL_SETTINGS_RESET); + } else if (!strcasecmp(name,"recovery_request")) { + value = VbGetNvStorage(VBNV_RECOVERY_REQUEST); + } else if (!strcasecmp(name,"dbg_reset")) { + value = VbGetNvStorage(VBNV_DEBUG_RESET_MODE); + } else if (!strcasecmp(name,"disable_dev_request")) { + value = VbGetNvStorage(VBNV_DISABLE_DEV_REQUEST); + } else if (!strcasecmp(name,"clear_tpm_owner_request")) { + value = VbGetNvStorage(VBNV_CLEAR_TPM_OWNER_REQUEST); + } else if (!strcasecmp(name,"clear_tpm_owner_done")) { + value = VbGetNvStorage(VBNV_CLEAR_TPM_OWNER_DONE); + } else if (!strcasecmp(name,"tpm_rebooted")) { + value = VbGetNvStorage(VBNV_TPM_REQUESTED_REBOOT); + } else if (!strcasecmp(name,"fwb_tries")) { + value = VbGetNvStorage(VBNV_TRY_B_COUNT); + } else if (!strcasecmp(name,"fw_vboot2")) { + value = GetVdatInt(VDAT_INT_FW_BOOT2); + } else if (!strcasecmp(name,"fw_try_count")) { + value = VbGetNvStorage(VBNV_FW_TRY_COUNT); + } else if (!strcasecmp(name,"fwupdate_tries")) { + value = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (value != -1) + value &= KERN_NV_FWUPDATE_TRIES_MASK; + } else if (!strcasecmp(name,"block_devmode")) { + value = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (value != -1) { + value &= KERN_NV_BLOCK_DEVMODE_FLAG; + value = !!value; + } + } else if (!strcasecmp(name,"tpm_attack")) { + value = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (value != -1) { + value &= KERN_NV_TPM_ATTACK_FLAG; + value = !!value; + } + } else if (!strcasecmp(name,"loc_idx")) { + value = VbGetNvStorage(VBNV_LOCALIZATION_INDEX); + } else if (!strcasecmp(name,"backup_nvram_request")) { + value = VbGetNvStorage(VBNV_BACKUP_NVRAM_REQUEST); + } else if (!strcasecmp(name,"dev_boot_usb")) { + value = VbGetNvStorage(VBNV_DEV_BOOT_USB); + } else if (!strcasecmp(name,"dev_boot_legacy")) { + value = VbGetNvStorage(VBNV_DEV_BOOT_LEGACY); + } else if (!strcasecmp(name,"dev_boot_signed_only")) { + value = VbGetNvStorage(VBNV_DEV_BOOT_SIGNED_ONLY); + } else if (!strcasecmp(name,"dev_boot_fastboot_full_cap")) { + value = VbGetNvStorage(VBNV_DEV_BOOT_FASTBOOT_FULL_CAP); + } else if (!strcasecmp(name,"oprom_needed")) { + value = VbGetNvStorage(VBNV_OPROM_NEEDED); + } else if (!strcasecmp(name,"recovery_subcode")) { + value = VbGetNvStorage(VBNV_RECOVERY_SUBCODE); + } else if (!strcasecmp(name,"wipeout_request")) { + value = VbGetNvStorage(VBNV_FW_REQ_WIPEOUT); + } + /* Other parameters */ + else if (!strcasecmp(name,"cros_debug")) { + value = VbGetCrosDebug(); + } else if (!strcasecmp(name,"debug_build")) { + value = VbGetDebugBuild(); + } else if (!strcasecmp(name,"devsw_boot")) { + value = GetVdatInt(VDAT_INT_DEVSW_BOOT); + } else if (!strcasecmp(name,"devsw_virtual")) { + value = GetVdatInt(VDAT_INT_DEVSW_VIRTUAL); + } else if (!strcasecmp(name, "recoverysw_boot")) { + value = GetVdatInt(VDAT_INT_RECSW_BOOT); + } else if (!strcasecmp(name, "wpsw_boot")) { + value = GetVdatInt(VDAT_INT_HW_WPSW_BOOT); + } else if (!strcasecmp(name, "sw_wpsw_boot")) { + value = GetVdatInt(VDAT_INT_SW_WPSW_BOOT); + } else if (!strcasecmp(name,"vdat_flags")) { + value = GetVdatInt(VDAT_INT_FLAGS); + } else if (!strcasecmp(name,"tpm_fwver")) { + value = GetVdatInt(VDAT_INT_FW_VERSION_TPM); + } else if (!strcasecmp(name,"tpm_kernver")) { + value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM); + } else if (!strcasecmp(name,"tried_fwb")) { + value = GetVdatInt(VDAT_INT_TRIED_FIRMWARE_B); + } else if (!strcasecmp(name,"recovery_reason")) { + value = GetVdatInt(VDAT_INT_RECOVERY_REASON); + } else if (!strcasecmp(name, "fastboot_unlock_in_fw")) { + value = VbGetNvStorage(VBNV_FASTBOOT_UNLOCK_IN_FW); + } else if (!strcasecmp(name, "boot_on_ac_detect")) { + value = VbGetNvStorage(VBNV_BOOT_ON_AC_DETECT); + } else if (!strcasecmp(name, "try_ro_sync")) { + value = VbGetNvStorage(VBNV_TRY_RO_SYNC); + } else if (!strcasecmp(name, "battery_cutoff_request")) { + value = VbGetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST); + } else if (!strcasecmp(name, "inside_vm")) { + /* Detect if the host is a VM. If there is no HWID and the + * firmware type is "nonchrome", then assume it is a VM. If + * HWID is present, it is a baremetal Chrome OS machine. Other + * cases are errors. */ + char hwid[VB_MAX_STRING_PROPERTY]; + if (!VbGetSystemPropertyString("hwid", hwid, sizeof(hwid))) { + char fwtype_buf[VB_MAX_STRING_PROPERTY]; + const char *fwtype = VbGetSystemPropertyString( + "mainfw_type", fwtype_buf, sizeof(fwtype_buf)); + if (fwtype && !strcasecmp(fwtype, "nonchrome")) { + value = 1; + } + } else { + value = 0; + } + } + + return value; } +const char *VbGetSystemPropertyString(const char *name, char *dest, + size_t size) +{ + /* Check architecture-dependent properties first */ + if (VbGetArchPropertyString(name, dest, size)) + return dest; + + if (!strcasecmp(name,"kernkey_vfy")) { + switch(GetVdatInt(VDAT_INT_KERNEL_KEY_VERIFIED)) { + case 0: + return "hash"; + case 1: + return "sig"; + default: + return NULL; + } + } else if (!strcasecmp(name, "mainfw_act")) { + return GetVdatString(dest, size, VDAT_STRING_MAINFW_ACT); + } else if (!strcasecmp(name, "vdat_timers")) { + return GetVdatString(dest, size, VDAT_STRING_TIMERS); + } else if (!strcasecmp(name, "vdat_lfdebug")) { + return GetVdatString(dest, size, + VDAT_STRING_LOAD_FIRMWARE_DEBUG); + } else if (!strcasecmp(name, "vdat_lkdebug")) { + return GetVdatString(dest, size, VDAT_STRING_LOAD_KERNEL_DEBUG); + } else if (!strcasecmp(name, "fw_try_next")) { + return VbGetNvStorage(VBNV_FW_TRY_NEXT) ? "B" : "A"; + } else if (!strcasecmp(name, "fw_tried")) { + return VbGetNvStorage(VBNV_FW_TRIED) ? "B" : "A"; + } else if (!strcasecmp(name, "fw_result")) { + int v = VbGetNvStorage(VBNV_FW_RESULT); + if (v < ARRAY_SIZE(fw_results)) + return fw_results[v]; + else + return "unknown"; + } else if (!strcasecmp(name, "fw_prev_tried")) { + return VbGetNvStorage(VBNV_FW_PREV_TRIED) ? "B" : "A"; + } else if (!strcasecmp(name, "fw_prev_result")) { + int v = VbGetNvStorage(VBNV_FW_PREV_RESULT); + if (v < ARRAY_SIZE(fw_results)) + return fw_results[v]; + else + return "unknown"; + } else if (!strcasecmp(name,"dev_default_boot")) { + int v = VbGetNvStorage(VBNV_DEV_DEFAULT_BOOT); + if (v < ARRAY_SIZE(default_boot)) + return default_boot[v]; + else + return "unknown"; + } -const char* VbGetSystemPropertyString(const char* name, char* dest, - size_t size) { - /* Check architecture-dependent properties first */ - if (VbGetArchPropertyString(name, dest, size)) - return dest; - - if (!strcasecmp(name,"kernkey_vfy")) { - switch(GetVdatInt(VDAT_INT_KERNEL_KEY_VERIFIED)) { - case 0: - return "hash"; - case 1: - return "sig"; - default: - return NULL; - } - } else if (!strcasecmp(name, "mainfw_act")) { - return GetVdatString(dest, size, VDAT_STRING_MAINFW_ACT); - } else if (!strcasecmp(name, "vdat_timers")) { - return GetVdatString(dest, size, VDAT_STRING_TIMERS); - } else if (!strcasecmp(name, "vdat_lfdebug")) { - return GetVdatString(dest, size, VDAT_STRING_LOAD_FIRMWARE_DEBUG); - } else if (!strcasecmp(name, "vdat_lkdebug")) { - return GetVdatString(dest, size, VDAT_STRING_LOAD_KERNEL_DEBUG); - } else if (!strcasecmp(name, "fw_try_next")) { - return VbGetNvStorage(VBNV_FW_TRY_NEXT) ? "B" : "A"; - } else if (!strcasecmp(name, "fw_tried")) { - return VbGetNvStorage(VBNV_FW_TRIED) ? "B" : "A"; - } else if (!strcasecmp(name, "fw_result")) { - int v = VbGetNvStorage(VBNV_FW_RESULT); - if (v < ARRAY_SIZE(fw_results)) - return fw_results[v]; - else - return "unknown"; - } else if (!strcasecmp(name, "fw_prev_tried")) { - return VbGetNvStorage(VBNV_FW_PREV_TRIED) ? "B" : "A"; - } else if (!strcasecmp(name, "fw_prev_result")) { - int v = VbGetNvStorage(VBNV_FW_PREV_RESULT); - if (v < ARRAY_SIZE(fw_results)) - return fw_results[v]; - else - return "unknown"; - } else if (!strcasecmp(name,"dev_default_boot")) { - int v = VbGetNvStorage(VBNV_DEV_DEFAULT_BOOT); - if (v < ARRAY_SIZE(default_boot)) - return default_boot[v]; - else - return "unknown"; - } - - return NULL; + return NULL; } -int VbSetSystemPropertyInt(const char* name, int value) { - /* Check architecture-dependent properties first */ - - if (0 == VbSetArchPropertyInt(name, value)) - return 0; - - /* NV storage values */ - if (!strcasecmp(name,"nvram_cleared")) { - /* Can only clear this flag; it's set inside the NV storage library. */ - return VbSetNvStorage(VBNV_KERNEL_SETTINGS_RESET, 0); - } else if (!strcasecmp(name,"recovery_request")) { - return VbSetNvStorage(VBNV_RECOVERY_REQUEST, value); - } else if (!strcasecmp(name,"recovery_subcode")) { - return VbSetNvStorage(VBNV_RECOVERY_SUBCODE, value); - } else if (!strcasecmp(name,"dbg_reset")) { - return VbSetNvStorage(VBNV_DEBUG_RESET_MODE, value); - } else if (!strcasecmp(name,"disable_dev_request")) { - return VbSetNvStorage(VBNV_DISABLE_DEV_REQUEST, value); - } else if (!strcasecmp(name,"clear_tpm_owner_request")) { - return VbSetNvStorage(VBNV_CLEAR_TPM_OWNER_REQUEST, value); - } else if (!strcasecmp(name,"clear_tpm_owner_done")) { - /* Can only clear this flag; it's set by firmware. */ - return VbSetNvStorage(VBNV_CLEAR_TPM_OWNER_DONE, 0); - } else if (!strcasecmp(name,"fwb_tries")) { - return VbSetNvStorage(VBNV_TRY_B_COUNT, value); - } else if (!strcasecmp(name,"fw_try_count")) { - return VbSetNvStorage(VBNV_FW_TRY_COUNT, value); - } else if (!strcasecmp(name,"oprom_needed")) { - return VbSetNvStorage(VBNV_OPROM_NEEDED, value); - } else if (!strcasecmp(name,"wipeout_request")) { - /* Can only clear this flag, set only by firmware. */ - return VbSetNvStorage(VBNV_FW_REQ_WIPEOUT, 0); - } else if (!strcasecmp(name,"backup_nvram_request")) { - /* Best-effort only, since it requires firmware and TPM support. */ - return VbSetNvStorage(VBNV_BACKUP_NVRAM_REQUEST, value); - } else if (!strcasecmp(name,"fwupdate_tries")) { - int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD); - if (kern_nv == -1) - return -1; - kern_nv &= ~KERN_NV_FWUPDATE_TRIES_MASK; - kern_nv |= (value & KERN_NV_FWUPDATE_TRIES_MASK); - return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); - } else if (!strcasecmp(name,"block_devmode")) { - int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD); - if (kern_nv == -1) - return -1; - kern_nv &= ~KERN_NV_BLOCK_DEVMODE_FLAG; - if (value) - kern_nv |= KERN_NV_BLOCK_DEVMODE_FLAG; - return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); - } else if (!strcasecmp(name,"tpm_attack")) { - /* This value should only be read and cleared, but we allow setting it to 1 - * for testing. - */ - int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD); - if (kern_nv == -1) - return -1; - kern_nv &= ~KERN_NV_TPM_ATTACK_FLAG; - if (value) - kern_nv |= KERN_NV_TPM_ATTACK_FLAG; - return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); - } else if (!strcasecmp(name,"loc_idx")) { - return VbSetNvStorage_WithBackup(VBNV_LOCALIZATION_INDEX, value); - } else if (!strcasecmp(name,"dev_boot_usb")) { - return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_USB, value); - } else if (!strcasecmp(name,"dev_boot_legacy")) { - return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_LEGACY, value); - } else if (!strcasecmp(name,"dev_boot_signed_only")) { - return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_SIGNED_ONLY, value); - } else if (!strcasecmp(name,"dev_boot_fastboot_full_cap")) { - return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, value); - } else if (!strcasecmp(name, "fastboot_unlock_in_fw")) { - return VbSetNvStorage_WithBackup(VBNV_FASTBOOT_UNLOCK_IN_FW, value); - } else if (!strcasecmp(name, "boot_on_ac_detect")) { - return VbSetNvStorage_WithBackup(VBNV_BOOT_ON_AC_DETECT, value); - } else if (!strcasecmp(name, "try_ro_sync")) { - return VbSetNvStorage_WithBackup(VBNV_TRY_RO_SYNC, value); - } else if (!strcasecmp(name, "battery_cutoff_request")) { - return VbSetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST, value); - } - - return -1; +int VbSetSystemPropertyInt(const char *name, int value) +{ + /* Check architecture-dependent properties first */ + + if (0 == VbSetArchPropertyInt(name, value)) + return 0; + + /* NV storage values */ + if (!strcasecmp(name,"nvram_cleared")) { + /* Can only clear this flag; it's set inside the NV storage + * library. */ + return VbSetNvStorage(VBNV_KERNEL_SETTINGS_RESET, 0); + } else if (!strcasecmp(name,"recovery_request")) { + return VbSetNvStorage(VBNV_RECOVERY_REQUEST, value); + } else if (!strcasecmp(name,"recovery_subcode")) { + return VbSetNvStorage(VBNV_RECOVERY_SUBCODE, value); + } else if (!strcasecmp(name,"dbg_reset")) { + return VbSetNvStorage(VBNV_DEBUG_RESET_MODE, value); + } else if (!strcasecmp(name,"disable_dev_request")) { + return VbSetNvStorage(VBNV_DISABLE_DEV_REQUEST, value); + } else if (!strcasecmp(name,"clear_tpm_owner_request")) { + return VbSetNvStorage(VBNV_CLEAR_TPM_OWNER_REQUEST, value); + } else if (!strcasecmp(name,"clear_tpm_owner_done")) { + /* Can only clear this flag; it's set by firmware. */ + return VbSetNvStorage(VBNV_CLEAR_TPM_OWNER_DONE, 0); + } else if (!strcasecmp(name,"fwb_tries")) { + return VbSetNvStorage(VBNV_TRY_B_COUNT, value); + } else if (!strcasecmp(name,"fw_try_count")) { + return VbSetNvStorage(VBNV_FW_TRY_COUNT, value); + } else if (!strcasecmp(name,"oprom_needed")) { + return VbSetNvStorage(VBNV_OPROM_NEEDED, value); + } else if (!strcasecmp(name,"wipeout_request")) { + /* Can only clear this flag, set only by firmware. */ + return VbSetNvStorage(VBNV_FW_REQ_WIPEOUT, 0); + } else if (!strcasecmp(name,"backup_nvram_request")) { + /* Best-effort only, since it requires firmware and TPM + * support. */ + return VbSetNvStorage(VBNV_BACKUP_NVRAM_REQUEST, value); + } else if (!strcasecmp(name,"fwupdate_tries")) { + int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (kern_nv == -1) + return -1; + kern_nv &= ~KERN_NV_FWUPDATE_TRIES_MASK; + kern_nv |= (value & KERN_NV_FWUPDATE_TRIES_MASK); + return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); + } else if (!strcasecmp(name,"block_devmode")) { + int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (kern_nv == -1) + return -1; + kern_nv &= ~KERN_NV_BLOCK_DEVMODE_FLAG; + if (value) + kern_nv |= KERN_NV_BLOCK_DEVMODE_FLAG; + return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); + } else if (!strcasecmp(name,"tpm_attack")) { + /* This value should only be read and cleared, but we allow + * setting it to 1 for testing. */ + int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (kern_nv == -1) + return -1; + kern_nv &= ~KERN_NV_TPM_ATTACK_FLAG; + if (value) + kern_nv |= KERN_NV_TPM_ATTACK_FLAG; + return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); + } else if (!strcasecmp(name,"loc_idx")) { + return VbSetNvStorage_WithBackup(VBNV_LOCALIZATION_INDEX, + value); + } else if (!strcasecmp(name,"dev_boot_usb")) { + return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_USB, value); + } else if (!strcasecmp(name,"dev_boot_legacy")) { + return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_LEGACY, value); + } else if (!strcasecmp(name,"dev_boot_signed_only")) { + return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_SIGNED_ONLY, + value); + } else if (!strcasecmp(name,"dev_boot_fastboot_full_cap")) { + return VbSetNvStorage_WithBackup( + VBNV_DEV_BOOT_FASTBOOT_FULL_CAP, value); + } else if (!strcasecmp(name, "fastboot_unlock_in_fw")) { + return VbSetNvStorage_WithBackup(VBNV_FASTBOOT_UNLOCK_IN_FW, + value); + } else if (!strcasecmp(name, "boot_on_ac_detect")) { + return VbSetNvStorage_WithBackup(VBNV_BOOT_ON_AC_DETECT, value); + } else if (!strcasecmp(name, "try_ro_sync")) { + return VbSetNvStorage_WithBackup(VBNV_TRY_RO_SYNC, value); + } else if (!strcasecmp(name, "battery_cutoff_request")) { + return VbSetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST, value); + } + + return -1; } +int VbSetSystemPropertyString(const char* name, const char* value) +{ + /* Chain to architecture-dependent properties */ + if (0 == VbSetArchPropertyString(name, value)) + return 0; + + if (!strcasecmp(name, "fw_try_next")) { + if (!strcasecmp(value, "A")) + return VbSetNvStorage(VBNV_FW_TRY_NEXT, 0); + else if (!strcasecmp(value, "B")) + return VbSetNvStorage(VBNV_FW_TRY_NEXT, 1); + else + return -1; + + } else if (!strcasecmp(name, "fw_result")) { + int i; + + for (i = 0; i < ARRAY_SIZE(fw_results); i++) { + if (!strcasecmp(value, fw_results[i])) + return VbSetNvStorage(VBNV_FW_RESULT, i); + } + return -1; + } else if (!strcasecmp(name, "dev_default_boot")) { + int i; + + for (i = 0; i < ARRAY_SIZE(default_boot); i++) { + if (!strcasecmp(value, default_boot[i])) + return VbSetNvStorage(VBNV_DEV_DEFAULT_BOOT, i); + } + return -1; + } -int VbSetSystemPropertyString(const char* name, const char* value) { - /* Chain to architecture-dependent properties */ - if (0 == VbSetArchPropertyString(name, value)) - return 0; - - if (!strcasecmp(name, "fw_try_next")) { - if (!strcasecmp(value, "A")) - return VbSetNvStorage(VBNV_FW_TRY_NEXT, 0); - else if (!strcasecmp(value, "B")) - return VbSetNvStorage(VBNV_FW_TRY_NEXT, 1); - else - return -1; - - } else if (!strcasecmp(name, "fw_result")) { - int i; - - for (i = 0; i < ARRAY_SIZE(fw_results); i++) { - if (!strcasecmp(value, fw_results[i])) - return VbSetNvStorage(VBNV_FW_RESULT, i); - } - return -1; - } else if (!strcasecmp(name, "dev_default_boot")) { - int i; - - for (i = 0; i < ARRAY_SIZE(default_boot); i++) { - if (!strcasecmp(value, default_boot[i])) - return VbSetNvStorage(VBNV_DEV_DEFAULT_BOOT, i); - } - return -1; - } - - return -1; + return -1; } - static int InAndroid(void) { int fd; @@ -767,98 +784,100 @@ static int InAndroid(void) return retval; } +static int ExecuteMosys(char * const argv[], char *buf, size_t bufsize) +{ + int status, mosys_to_crossystem[2]; + pid_t pid; + ssize_t n; -static int ExecuteMosys(char * const argv[], char *buf, size_t bufsize) { - int status, mosys_to_crossystem[2]; - pid_t pid; - ssize_t n; - - if (pipe(mosys_to_crossystem) < 0) { - VBDEBUG(("pipe() error\n")); - return -1; - } - - if ((pid = fork()) < 0) { - VBDEBUG(("fork() error\n")); - close(mosys_to_crossystem[0]); - close(mosys_to_crossystem[1]); - return -1; - } else if (!pid) { /* Child */ - close(mosys_to_crossystem[0]); - /* Redirect pipe's write-end to mosys' stdout */ - if (STDOUT_FILENO != mosys_to_crossystem[1]) { - if (dup2(mosys_to_crossystem[1], STDOUT_FILENO) != STDOUT_FILENO) { - VBDEBUG(("stdout dup2() failed (mosys)\n")); - close(mosys_to_crossystem[1]); - exit(1); - } - } - /* Execute mosys */ - execv(InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, argv); - /* We shouldn't be here; exit now! */ - VBDEBUG(("execv() of mosys failed\n")); - close(mosys_to_crossystem[1]); - exit(1); - } else { /* Parent */ - close(mosys_to_crossystem[1]); - if (bufsize) { - bufsize--; /* Reserve 1 byte for '\0' */ - while ((n = read(mosys_to_crossystem[0], buf, bufsize)) > 0) { - buf += n; - bufsize -= n; - } - *buf = '\0'; - } else { - n = 0; - } - close(mosys_to_crossystem[0]); - if (n < 0) - VBDEBUG(("read() error while reading output from mosys\n")); - if (waitpid(pid, &status, 0) < 0 || status) { - VBDEBUG(("waitpid() or mosys error\n")); - fprintf(stderr, "waitpid() or mosys error\n"); - return -1; - } - if (n < 0) - return -1; - } - return 0; -} - + if (pipe(mosys_to_crossystem) < 0) { + VBDEBUG(("pipe() error\n")); + return -1; + } -int VbReadNvStorage_mosys(VbNvContext* vnc) { - char hexstring[VBNV_BLOCK_SIZE * 2 + 32]; /* Reserve extra 32 bytes */ - char * const argv[] = { - InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, - "nvram", "vboot", "read", NULL - }; - char hexdigit[3]; - int i; - - if (ExecuteMosys(argv, hexstring, sizeof(hexstring))) - return -1; - hexdigit[2] = '\0'; - for (i = 0; i < VBNV_BLOCK_SIZE; i++) { - hexdigit[0] = hexstring[i * 2]; - hexdigit[1] = hexstring[i * 2 + 1]; - vnc->raw[i] = strtol(hexdigit, NULL, 16); - } - return 0; + if ((pid = fork()) < 0) { + VBDEBUG(("fork() error\n")); + close(mosys_to_crossystem[0]); + close(mosys_to_crossystem[1]); + return -1; + } else if (!pid) { /* Child */ + close(mosys_to_crossystem[0]); + /* Redirect pipe's write-end to mosys' stdout */ + if (STDOUT_FILENO != mosys_to_crossystem[1]) { + if (dup2(mosys_to_crossystem[1], STDOUT_FILENO) + != STDOUT_FILENO) { + VBDEBUG(("stdout dup2() failed (mosys)\n")); + close(mosys_to_crossystem[1]); + exit(1); + } + } + /* Execute mosys */ + execv(InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, argv); + /* We shouldn't be here; exit now! */ + VBDEBUG(("execv() of mosys failed\n")); + close(mosys_to_crossystem[1]); + exit(1); + } else { /* Parent */ + close(mosys_to_crossystem[1]); + if (bufsize) { + bufsize--; /* Reserve 1 byte for '\0' */ + while ((n = read(mosys_to_crossystem[0], + buf, bufsize)) > 0) { + buf += n; + bufsize -= n; + } + *buf = '\0'; + } else { + n = 0; + } + close(mosys_to_crossystem[0]); + if (n < 0) + VBDEBUG(("read() error reading output from mosys\n")); + if (waitpid(pid, &status, 0) < 0 || status) { + VBDEBUG(("waitpid() or mosys error\n")); + fprintf(stderr, "waitpid() or mosys error\n"); + return -1; + } + if (n < 0) + return -1; + } + return 0; } +int VbReadNvStorage_mosys(VbNvContext *vnc) +{ + char hexstring[VBNV_BLOCK_SIZE * 2 + 32]; /* Reserve extra 32 bytes */ + char * const argv[] = { + InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, + "nvram", "vboot", "read", NULL + }; + char hexdigit[3]; + int i; + + if (ExecuteMosys(argv, hexstring, sizeof(hexstring))) + return -1; + hexdigit[2] = '\0'; + for (i = 0; i < VBNV_BLOCK_SIZE; i++) { + hexdigit[0] = hexstring[i * 2]; + hexdigit[1] = hexstring[i * 2 + 1]; + vnc->raw[i] = strtol(hexdigit, NULL, 16); + } + return 0; +} -int VbWriteNvStorage_mosys(VbNvContext* vnc) { - char hexstring[VBNV_BLOCK_SIZE * 2 + 1]; - char * const argv[] = { - InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, - "nvram", "vboot", "write", hexstring, NULL - }; - int i; - - for (i = 0; i < VBNV_BLOCK_SIZE; i++) - snprintf(hexstring + i * 2, 3, "%02x", vnc->raw[i]); - hexstring[sizeof(hexstring) - 1] = '\0'; - if (ExecuteMosys(argv, NULL, 0)) - return -1; - return 0; +int VbWriteNvStorage_mosys(VbNvContext* vnc) +{ + char hexstring[VBNV_BLOCK_SIZE * 2 + 1]; + char * const argv[] = { + InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH, + "nvram", "vboot", "write", hexstring, NULL + }; + int i; + + for (i = 0; i < VBNV_BLOCK_SIZE; i++) + snprintf(hexstring + i * 2, 3, "%02x", vnc->raw[i]); + hexstring[sizeof(hexstring) - 1] = '\0'; + if (ExecuteMosys(argv, NULL, 0)) + return -1; + return 0; } diff --git a/host/lib/file_keys.c b/host/lib/file_keys.c index a774ba22..00fbe6f5 100644 --- a/host/lib/file_keys.c +++ b/host/lib/file_keys.c @@ -59,7 +59,8 @@ uint8_t *BufferFromFile(const char* input_file, uint64_t* len) return buf; } -RSAPublicKey *RSAPublicKeyFromFile(const char *input_file) { +RSAPublicKey *RSAPublicKeyFromFile(const char *input_file) +{ uint64_t len; RSAPublicKey* key = NULL; @@ -71,7 +72,8 @@ RSAPublicKey *RSAPublicKeyFromFile(const char *input_file) { } int DigestFile(char *input_file, enum vb2_hash_algorithm alg, - uint8_t *digest, uint32_t digest_size) { + uint8_t *digest, uint32_t digest_size) +{ int input_fd, len; uint8_t data[VB2_SHA1_BLOCK_SIZE]; struct vb2_digest_context ctx; diff --git a/host/lib/host_misc.c b/host/lib/host_misc.c index dde05d07..03d05664 100644 --- a/host/lib/host_misc.c +++ b/host/lib/host_misc.c @@ -16,105 +16,105 @@ #include "host_common.h" #include "vboot_common.h" - -char* StrCopy(char* dest, const char* src, int dest_size) { - strncpy(dest, src, dest_size); - dest[dest_size - 1] = '\0'; - return dest; +char* StrCopy(char* dest, const char* src, int dest_size) +{ + strncpy(dest, src, dest_size); + dest[dest_size - 1] = '\0'; + return dest; } - -uint8_t* ReadFile(const char* filename, uint64_t* sizeptr) { - FILE* f; - uint8_t* buf; - long size; - - f = fopen(filename, "rb"); - if (!f) { - VBDEBUG(("Unable to open file %s\n", filename)); - return NULL; - } - - fseek(f, 0, SEEK_END); - size = ftell(f); - if (size < 0) { - fclose(f); - return NULL; - } - rewind(f); - - buf = malloc(size); - if (!buf) { - fclose(f); - return NULL; - } - - if(1 != fread(buf, size, 1, f)) { - VBDEBUG(("Unable to read from file %s\n", filename)); - fclose(f); - free(buf); - return NULL; - } - - fclose(f); - if (sizeptr) - *sizeptr = size; - return buf; +uint8_t* ReadFile(const char* filename, uint64_t* sizeptr) +{ + FILE* f; + uint8_t* buf; + long size; + + f = fopen(filename, "rb"); + if (!f) { + VBDEBUG(("Unable to open file %s\n", filename)); + return NULL; + } + + fseek(f, 0, SEEK_END); + size = ftell(f); + if (size < 0) { + fclose(f); + return NULL; + } + rewind(f); + + buf = malloc(size); + if (!buf) { + fclose(f); + return NULL; + } + + if(1 != fread(buf, size, 1, f)) { + VBDEBUG(("Unable to read from file %s\n", filename)); + fclose(f); + free(buf); + return NULL; + } + + fclose(f); + if (sizeptr) + *sizeptr = size; + return buf; } +char* ReadFileString(char* dest, int size, const char* filename) +{ + char* got; + FILE* f; -char* ReadFileString(char* dest, int size, const char* filename) { - char* got; - FILE* f; + f = fopen(filename, "rt"); + if (!f) + return NULL; - f = fopen(filename, "rt"); - if (!f) - return NULL; - - got = fgets(dest, size, f); - fclose(f); - return got; + got = fgets(dest, size, f); + fclose(f); + return got; } +int ReadFileInt(const char* filename, unsigned* value) +{ + char buf[64]; + char* e = NULL; -int ReadFileInt(const char* filename, unsigned* value) { - char buf[64]; - char* e = NULL; - - if (!ReadFileString(buf, sizeof(buf), filename)) - return -1; + if (!ReadFileString(buf, sizeof(buf), filename)) + return -1; - /* Convert to integer. Allow characters after the int ("123 blah"). */ - *value = (unsigned)strtoul(buf, &e, 0); - if (e == buf) - return -1; /* No characters consumed, so conversion failed */ + /* Convert to integer. Allow characters after the int ("123 blah"). */ + *value = (unsigned)strtoul(buf, &e, 0); + if (e == buf) + return -1; /* No characters consumed, so conversion failed */ - return 0; + return 0; } - -int ReadFileBit(const char* filename, int bitmask) { - unsigned value; - if (ReadFileInt(filename, &value) < 0) - return -1; - else return (value & bitmask ? 1 : 0); +int ReadFileBit(const char* filename, int bitmask) +{ + unsigned value; + if (ReadFileInt(filename, &value) < 0) + return -1; + else return (value & bitmask ? 1 : 0); } - -int WriteFile(const char* filename, const void *data, uint64_t size) { - FILE *f = fopen(filename, "wb"); - if (!f) { - VBDEBUG(("Unable to open file %s\n", filename)); - return 1; - } - - if (1 != fwrite(data, size, 1, f)) { - VBDEBUG(("Unable to write to file %s\n", filename)); - fclose(f); - unlink(filename); /* Delete any partial file */ - return 1; - } - - fclose(f); - return 0; +int WriteFile(const char* filename, const void *data, uint64_t size) +{ + FILE *f = fopen(filename, "wb"); + if (!f) { + VBDEBUG(("Unable to open file %s\n", filename)); + return 1; + } + + if (1 != fwrite(data, size, 1, f)) { + VBDEBUG(("Unable to write to file %s\n", filename)); + fclose(f); + unlink(filename); /* Delete any partial file */ + return 1; + } + + fclose(f); + return 0; } diff --git a/host/lib/include/fmap.h b/host/lib/include/fmap.h index 7e627050..d6c33c65 100644 --- a/host/lib/include/fmap.h +++ b/host/lib/include/fmap.h @@ -17,20 +17,21 @@ #define FMAP_SEARCH_STRIDE 4 #define FMAP_VER_MAJOR 1 typedef struct _FmapHeader { - char fmap_signature[FMAP_SIGNATURE_SIZE]; /* avoiding endian issues */ - uint8_t fmap_ver_major; - uint8_t fmap_ver_minor; - uint64_t fmap_base; - uint32_t fmap_size; - char fmap_name[FMAP_NAMELEN]; - uint16_t fmap_nareas; + /* Avoid endian issues in signature... */ + char fmap_signature[FMAP_SIGNATURE_SIZE]; + uint8_t fmap_ver_major; + uint8_t fmap_ver_minor; + uint64_t fmap_base; + uint32_t fmap_size; + char fmap_name[FMAP_NAMELEN]; + uint16_t fmap_nareas; } __attribute__((packed)) FmapHeader; typedef struct _FmapAreaHeader { - uint32_t area_offset; - uint32_t area_size; - char area_name[FMAP_NAMELEN]; - uint16_t area_flags; + uint32_t area_offset; + uint32_t area_size; + char area_name[FMAP_NAMELEN]; + uint16_t area_flags; } __attribute__((packed)) FmapAreaHeader; diff --git a/host/lib/signature_digest.c b/host/lib/signature_digest.c index b56233a0..ca560c94 100644 --- a/host/lib/signature_digest.c +++ b/host/lib/signature_digest.c @@ -17,63 +17,68 @@ #include "host_common.h" #include "signature_digest.h" - -uint8_t* PrependDigestInfo(unsigned int algorithm, uint8_t* digest) { - const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); - const int digestinfo_size = digestinfo_size_map[algorithm]; - const uint8_t* digestinfo = hash_digestinfo_map[algorithm]; - uint8_t* p = malloc(digestinfo_size + digest_size); - Memcpy(p, digestinfo, digestinfo_size); - Memcpy(p + digestinfo_size, digest, digest_size); - return p; +uint8_t* PrependDigestInfo(unsigned int algorithm, uint8_t* digest) +{ + const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); + const int digestinfo_size = digestinfo_size_map[algorithm]; + const uint8_t* digestinfo = hash_digestinfo_map[algorithm]; + uint8_t* p = malloc(digestinfo_size + digest_size); + Memcpy(p, digestinfo, digestinfo_size); + Memcpy(p + digestinfo_size, digest, digest_size); + return p; } uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len, - unsigned int algorithm) { - uint8_t* info_digest = NULL; + unsigned int algorithm) +{ + uint8_t* info_digest = NULL; - uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */ + uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */ - if (algorithm >= kNumAlgorithms) { - VBDEBUG(("SignatureDigest() called with invalid algorithm!\n")); - } else if (VB2_SUCCESS == vb2_digest_buffer(buf, len, - vb2_crypto_to_hash(algorithm), - digest, sizeof(digest))) { - info_digest = PrependDigestInfo(algorithm, digest); - } - return info_digest; + if (algorithm >= kNumAlgorithms) { + VBDEBUG(("SignatureDigest() called with invalid algorithm!\n")); + } else if (VB2_SUCCESS == + vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm), + digest, sizeof(digest))) { + info_digest = PrependDigestInfo(algorithm, digest); + } + return info_digest; } uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file, - unsigned int algorithm) { - FILE* key_fp = NULL; - RSA* key = NULL; - uint8_t* signature = NULL; - uint8_t* signature_digest = SignatureDigest(buf, len, algorithm); - const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); - int signature_digest_len = (digest_size + digestinfo_size_map[algorithm]); - key_fp = fopen(key_file, "r"); - if (!key_fp) { - VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n", key_file)); - free(signature_digest); - return NULL; - } - if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL))) - signature = (uint8_t*) malloc(siglen_map[algorithm]); - else - VBDEBUG(("SignatureBuf(): Couldn't read private key from file: %s\n", - key_file)); - if (signature) { - if (-1 == RSA_private_encrypt(signature_digest_len, /* Input length. */ - signature_digest, /* Input data. */ - signature, /* Output signature. */ - key, /* Key to use. */ - RSA_PKCS1_PADDING)) /* Padding to use. */ - VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n")); - } - fclose(key_fp); - if (key) - RSA_free(key); - free(signature_digest); - return signature; + unsigned int algorithm) +{ + FILE* key_fp = NULL; + RSA* key = NULL; + uint8_t* signature = NULL; + uint8_t* signature_digest = SignatureDigest(buf, len, algorithm); + const int digest_size = vb2_digest_size(vb2_crypto_to_hash(algorithm)); + int signature_digest_len = digest_size + digestinfo_size_map[algorithm]; + key_fp = fopen(key_file, "r"); + if (!key_fp) { + VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n", + key_file)); + free(signature_digest); + return NULL; + } + if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL))) + signature = (uint8_t*) malloc(siglen_map[algorithm]); + else + VBDEBUG(("SignatureBuf(): Couldn't read private key from: %s\n", + key_file)); + if (signature) { + if (-1 == RSA_private_encrypt( + signature_digest_len, /* Input length. */ + signature_digest, /* Input data. */ + signature, /* Output signature. */ + key, /* Key to use. */ + RSA_PKCS1_PADDING)) /* Padding to use. */ + VBDEBUG(("SignatureBuf(): " + "RSA_private_encrypt() failed.\n")); + } + fclose(key_fp); + if (key) + RSA_free(key); + free(signature_digest); + return signature; } diff --git a/host/linktest/main.c b/host/linktest/main.c index 8db150b8..3e132115 100644 --- a/host/linktest/main.c +++ b/host/linktest/main.c @@ -15,19 +15,19 @@ int main(void) { - /* host_misc.h */ - ReadFile(0, 0); - WriteFile(0, 0, 0); + /* host_misc.h */ + ReadFile(0, 0); + WriteFile(0, 0, 0); - /* file_keys.h */ - BufferFromFile(0, 0); - RSAPublicKeyFromFile(0); - DigestFile(0, 0, 0, 0); + /* file_keys.h */ + BufferFromFile(0, 0); + RSAPublicKeyFromFile(0); + DigestFile(0, 0, 0, 0); - /* signature_digest.h */ - PrependDigestInfo(0, 0); - SignatureDigest(0, 0, 0); - SignatureBuf(0, 0, 0, 0); + /* signature_digest.h */ + PrependDigestInfo(0, 0); + SignatureDigest(0, 0, 0); + SignatureBuf(0, 0, 0, 0); - return 0; + return 0; } |