summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorJoel Kitching <kitching@google.com>2019-09-11 14:15:45 +0800
committerCommit Bot <commit-bot@chromium.org>2019-09-23 05:18:07 +0000
commitaaf394335cc4e287a1ffb6332311559b2b29c41f (patch)
tree3d552e3e22f530ba564654b6979a4009fbd53d68 /firmware
parentd3efd73cbb1fb5cf133739622fe0bd49653fad2e (diff)
downloadvboot-aaf394335cc4e287a1ffb6332311559b2b29c41f.tar.gz
vboot: add VB2_ASSERT and VB2_DIE macros
Sometimes vboot needs to make assertions to work sanely without always having to return VB2_ERROR_* values. Add VB2_ASSERT and VB2_DIE macros to deal with these cases. Convert existing VbAssert macro to use either VB2_ASSERT or TEST_* macros depending on the case. Implement testing infrastructure to check that aborts are being triggered correctly. The TEST_ASSERT macro should be used. BUG=b:124141368, chromium:1005700 TEST=make clean && make runtests BRANCH=none Change-Id: I298384ba50842a94a311df7f868f807bf2109cff Signed-off-by: Joel Kitching <kitching@google.com> Cq-Depend: chromium:1813277 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1800112 Tested-by: Joel Kitching <kitching@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Commit-Queue: Joel Kitching <kitching@chromium.org>
Diffstat (limited to 'firmware')
-rw-r--r--firmware/2lib/2stub.c7
-rw-r--r--firmware/2lib/include/2api.h10
-rw-r--r--firmware/2lib/include/2common.h24
-rw-r--r--firmware/lib/include/utility.h9
-rw-r--r--firmware/lib/tpm2_lite/tlcl.c10
-rw-r--r--firmware/lib/tpm_lite/tlcl.c16
6 files changed, 51 insertions, 25 deletions
diff --git a/firmware/2lib/2stub.c b/firmware/2lib/2stub.c
index 0818ed8e..00c5d9b2 100644
--- a/firmware/2lib/2stub.c
+++ b/firmware/2lib/2stub.c
@@ -66,3 +66,10 @@ vb2_error_t vb2ex_tpm_set_mode(enum vb2_tpm_mode mode_val)
fprintf(stderr, "%s: function not implemented\n", __func__);
return VB2_ERROR_EX_UNIMPLEMENTED;
}
+
+__attribute__((weak))
+void vb2ex_abort(void)
+{
+ /* Stub simply exits. */
+ exit(1);
+}
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index 8a127317..24d85da0 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -751,4 +751,14 @@ vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
*/
vb2_error_t vb2ex_tpm_set_mode(enum vb2_tpm_mode mode_val);
+/*
+ * Abort vboot flow due to a failed assertion or broken assumption.
+ *
+ * Likely due to caller misusing vboot (e.g. calling API functions
+ * out-of-order, filling in vb2_context fields inappropriately).
+ * Implementation should reboot or halt the machine, or fall back to some
+ * alternative boot flow. Retrying vboot is unlikely to succeed.
+ */
+void vb2ex_abort(void);
+
#endif /* VBOOT_REFERENCE_2API_H_ */
diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h
index 600dffbe..e15b59fd 100644
--- a/firmware/2lib/include/2common.h
+++ b/firmware/2lib/include/2common.h
@@ -37,9 +37,27 @@ struct vb2_public_key;
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
-/* Platform-dependent debug output macros. */
-#define VB2_DEBUG(format, args...) vb2ex_printf(__func__, format, ## args)
-#define VB2_DEBUG_RAW(format, args...) vb2ex_printf(NULL, format, ## args)
+/* Platform-dependent debug/assert output macros. */
+#define VB2_DEBUG(format, args...) \
+ vb2ex_printf(__func__, format, ## args)
+
+#define VB2_DEBUG_RAW(format, args...) \
+ vb2ex_printf(NULL, format, ## args)
+
+#define VB2_ASSERT(expr) do { \
+ if (!(expr)) { \
+ VB2_DEBUG("assertion failed: %s at %s:%d\n", \
+ #expr, __FILE__, __LINE__); \
+ vb2ex_abort(); \
+ for (;;); \
+ } \
+} while (0)
+
+#define VB2_DIE(format, args...) do { \
+ VB2_DEBUG(format, ## args); \
+ vb2ex_abort(); \
+ for (;;); \
+} while (0)
/*
* Define test_mockable and for mocking functions when compiled for Chrome OS
diff --git a/firmware/lib/include/utility.h b/firmware/lib/include/utility.h
index cf39f16a..bca49828 100644
--- a/firmware/lib/include/utility.h
+++ b/firmware/lib/include/utility.h
@@ -13,15 +13,6 @@
#include "2sysincludes.h"
#include "vboot_api.h"
-#ifdef VBOOT_DEBUG
-#define VbAssert(expr) do { if (!(expr)) { \
- VB2_DEBUG("assert fail: %s at %s:%d\n", \
- #expr, __FILE__, __LINE__); \
- exit(1); }} while(0)
-#else
-#define VbAssert(expr)
-#endif
-
/*
* Buffer size required to hold the longest possible output of Uint64ToString()
* - that is, Uint64ToString(~0, 2).
diff --git a/firmware/lib/tpm2_lite/tlcl.c b/firmware/lib/tpm2_lite/tlcl.c
index 37034c99..70cc3e0e 100644
--- a/firmware/lib/tpm2_lite/tlcl.c
+++ b/firmware/lib/tpm2_lite/tlcl.c
@@ -209,7 +209,7 @@ uint32_t TlclUndefineSpaceEx(const uint8_t* owner_auth,
uint32_t rv;
/* Authentication support is not implemented. */
- VbAssert(owner_auth == NULL && owner_auth_size == 0);
+ VB2_ASSERT(owner_auth == NULL && owner_auth_size == 0);
/* get the publicInfo of index */
rv = TlclGetPermissions(index, &permissions);
@@ -231,7 +231,7 @@ uint32_t TlclDefineSpaceEx(const uint8_t* owner_auth, uint32_t owner_auth_size,
struct tpm2_nv_define_space_cmd define_space;
/* Authentication support is not implemented. */
- VbAssert(owner_auth == NULL && owner_auth_size == 0);
+ VB2_ASSERT(owner_auth == NULL && owner_auth_size == 0);
/* For backwards-compatibility, if no READ or WRITE permissions are set,
* assume readable/writeable with empty auth value.
@@ -260,7 +260,7 @@ uint32_t TlclInitNvAuthPolicy(uint32_t pcr_selection_bitmap,
void* auth_policy, uint32_t* auth_policy_size)
{
/* Actual PCR selection isn't implemented. */
- VbAssert(pcr_selection_bitmap == 0);
+ VB2_ASSERT(pcr_selection_bitmap == 0);
*auth_policy_size = 0;
return TPM_SUCCESS;
}
@@ -649,8 +649,8 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
size_t prop_len = tlcl_vendor_string_parse(
prop_value, prop_string + total_size);
- VbAssert(prop_len <= 4 &&
- total_size + prop_len <= sizeof(prop_string));
+ VB2_ASSERT(prop_len <= 4 &&
+ total_size + prop_len <= sizeof(prop_string));
total_size += prop_len;
if (prop_len < 4)
break;
diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c
index d102f9b8..b5cb44fc 100644
--- a/firmware/lib/tpm_lite/tlcl.c
+++ b/firmware/lib/tpm_lite/tlcl.c
@@ -183,7 +183,7 @@ static uint32_t StartOIAPSession(struct auth_session* session,
session->handle = ReadTpmUint32(&cursor);
memcpy(session->nonce_even.nonce, cursor, sizeof(TPM_NONCE));
cursor += sizeof(TPM_NONCE);
- VbAssert(cursor - response <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ VB2_ASSERT(cursor - response <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
memcpy(session->shared_secret, secret, TPM_AUTH_DATA_LEN);
session->valid = 1;
@@ -231,7 +231,7 @@ static uint32_t StartOSAPSession(
cursor += sizeof(TPM_NONCE);
const uint8_t* nonce_even_osap = cursor;
cursor += sizeof(TPM_NONCE);
- VbAssert(cursor - response <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ VB2_ASSERT(cursor - response <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
/* Compute shared secret */
uint8_t hmac_input[2 * sizeof(TPM_NONCE)];
@@ -544,7 +544,7 @@ uint32_t TlclInitNvAuthPolicy(uint32_t pcr_selection_bitmap,
select->pcrSelect[0] = (pcr_selection_bitmap >> 0) & 0xff;
select->pcrSelect[1] = (pcr_selection_bitmap >> 8) & 0xff;
select->pcrSelect[2] = (pcr_selection_bitmap >> 16) & 0xff;
- VbAssert((pcr_selection_bitmap & 0xff000000) == 0);
+ VB2_ASSERT((pcr_selection_bitmap & 0xff000000) == 0);
/* Allow all localities except locality 3. Rationale:
*
@@ -624,7 +624,7 @@ uint32_t TlclWrite(uint32_t index, const void* data, uint32_t length)
VB2_DEBUG("TPM: TlclWrite(0x%x, %d)\n", index, length);
memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd));
- VbAssert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ VB2_ASSERT(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
SetTpmCommandSize(cmd.buffer, total_length);
ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.index, index);
@@ -776,7 +776,7 @@ uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS* pflags)
return result;
FromTpmUint32(response + kTpmResponseHeaderLength, &size);
/* TODO(crbug.com/379255): This fails. Find out why.
- * VbAssert(size == sizeof(TPM_PERMANENT_FLAGS));
+ * VB2_ASSERT(size == sizeof(TPM_PERMANENT_FLAGS));
*/
memcpy(pflags,
response + kTpmResponseHeaderLength + sizeof(size),
@@ -795,7 +795,7 @@ uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS* vflags)
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);
+ * VB2_ASSERT(size == 7 && sizeof(TPM_STCLEAR_FLAGS) - 1 == 7);
*/
memcpy(vflags,
response + kTpmResponseHeaderLength + sizeof(size),
@@ -968,7 +968,7 @@ uint32_t TlclGetOwnership(uint8_t* owned)
return result;
FromTpmUint32(response + kTpmResponseHeaderLength, &size);
/* TODO(crbug.com/379255): This fails. Find out why.
- * VbAssert(size == sizeof(*owned));
+ * VB2_ASSERT(size == sizeof(*owned));
*/
memcpy(owned,
response + kTpmResponseHeaderLength + sizeof(size),
@@ -1113,7 +1113,7 @@ uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO* info)
info->wFieldUpgradeCounter = ReadTpmUint16(&cursor);
uint32_t parsed_bytes = cursor - response;
- VbAssert(parsed_bytes <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ VB2_ASSERT(parsed_bytes <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
if (parsed_bytes > kTpmResponseHeaderLength + sizeof(size) + size) {
return TPM_E_INVALID_RESPONSE;
}