summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu-Ping Wu <yupingso@chromium.org>2020-03-03 09:42:31 +0800
committerCommit Bot <commit-bot@chromium.org>2020-03-31 07:15:06 +0000
commite3f71c97d05f5c659a0c2a2186dc62dd0586407f (patch)
treedd1658ebb32f324996e05e1c2751266a7b139c50
parentbf8c99df0ce9e086e9a48dd89e81d0dd5aa6f1a9 (diff)
downloadvboot-e3f71c97d05f5c659a0c2a2186dc62dd0586407f.tar.gz
firmware: Add VB2_TRY() helper macro
Add variadic macro VB2_TRY() to vboot2 APIs, which supports the following usage: - VB2_TRY(func_call()) - VB2_TRY(func_call(), ctx, recovery_reason) and will return the error code if func_call() failed. Also utilize the macro whenever possible throughout vboot. BRANCH=none BUG=chromium:1049032 TEST=make runtests TEST=emerge-nami coreboot coreboot-utils depthcharge -j Cq-Depend: chromium:2115423, chromium:2125616, chrome-internal:2817320 Change-Id: Ie5532a8beaa9372fa6fde0a68bda5ecb640087c4 Signed-off-by: Yu-Ping Wu <yupingso@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2084062 Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r--firmware/2lib/2api.c63
-rw-r--r--firmware/2lib/2auxfw_sync.c9
-rw-r--r--firmware/2lib/2common.c19
-rw-r--r--firmware/2lib/2ec_sync.c9
-rw-r--r--firmware/2lib/2gbb.c24
-rw-r--r--firmware/2lib/2misc.c15
-rw-r--r--firmware/2lib/2secdata_firmware.c5
-rw-r--r--firmware/2lib/2secdata_fwmp.c8
-rw-r--r--firmware/2lib/2secdata_kernel.c5
-rw-r--r--firmware/2lib/2sha_utility.c16
-rw-r--r--firmware/2lib/include/2api.h33
-rw-r--r--firmware/lib/vboot_api_kernel.c65
-rw-r--r--firmware/lib20/api_kernel.c32
-rw-r--r--firmware/lib20/kernel.c62
-rw-r--r--firmware/lib20/misc.c61
-rw-r--r--firmware/lib20/packed_key.c5
-rw-r--r--tests/vb2_api_tests.c42
17 files changed, 189 insertions, 284 deletions
diff --git a/firmware/2lib/2api.c b/firmware/2lib/2api.c
index 0f57d78b..4492cf93 100644
--- a/firmware/2lib/2api.c
+++ b/firmware/2lib/2api.c
@@ -107,8 +107,6 @@ vb2_error_t vb2api_fw_phase1(struct vb2_context *ctx)
vb2_error_t vb2api_fw_phase2(struct vb2_context *ctx)
{
- vb2_error_t rv;
-
/*
* Use the slot from the last boot if this is a resume. Do not set
* VB2_SD_STATUS_CHOSE_SLOT so the try counter is not decremented on
@@ -132,18 +130,10 @@ vb2_error_t vb2api_fw_phase2(struct vb2_context *ctx)
ctx->flags |= VB2_CONTEXT_CLEAR_RAM;
/* Check for explicit request to clear TPM */
- rv = vb2_check_tpm_clear(ctx);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_TPM_CLEAR_OWNER, rv);
- return rv;
- }
+ VB2_TRY(vb2_check_tpm_clear(ctx), ctx, VB2_RECOVERY_TPM_CLEAR_OWNER);
/* Decide which firmware slot to try this boot */
- rv = vb2_select_fw_slot(ctx);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_FW_SLOT, rv);
- return rv;
- }
+ VB2_TRY(vb2_select_fw_slot(ctx), ctx, VB2_RECOVERY_FW_SLOT);
return VB2_SUCCESS;
}
@@ -207,21 +197,11 @@ vb2_error_t vb2api_get_pcr_digest(struct vb2_context *ctx,
vb2_error_t vb2api_fw_phase3(struct vb2_context *ctx)
{
- vb2_error_t rv;
-
/* Verify firmware keyblock */
- rv = vb2_load_fw_keyblock(ctx);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
- return rv;
- }
+ VB2_TRY(vb2_load_fw_keyblock(ctx), ctx, VB2_RECOVERY_RO_INVALID_RW);
/* Verify firmware preamble */
- rv = vb2_load_fw_preamble(ctx);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
- return rv;
- }
+ VB2_TRY(vb2_load_fw_preamble(ctx), ctx, VB2_RECOVERY_RO_INVALID_RW);
return VB2_SUCCESS;
}
@@ -233,7 +213,6 @@ vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag)
struct vb2_digest_context *dc;
struct vb2_public_key key;
struct vb2_workbuf wb;
- vb2_error_t rv;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -286,18 +265,16 @@ vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag)
if (!sd->data_key_size)
return VB2_ERROR_API_INIT_HASH_DATA_KEY;
- rv = vb2_unpack_key_buffer(&key,
- vb2_member_of(sd, sd->data_key_offset),
- sd->data_key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_unpack_key_buffer(&key,
+ vb2_member_of(sd, sd->data_key_offset),
+ sd->data_key_size));
sd->hash_tag = tag;
sd->hash_remaining_size = pre->body_signature.data_size;
if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) {
- rv = vb2ex_hwcrypto_digest_init(key.hash_alg,
- pre->body_signature.data_size);
+ vb2_error_t rv = vb2ex_hwcrypto_digest_init(
+ key.hash_alg, pre->body_signature.data_size);
if (!rv) {
VB2_DEBUG("Using HW crypto engine for hash_alg %d\n",
key.hash_alg);
@@ -330,7 +307,6 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
struct vb2_fw_preamble *pre;
struct vb2_public_key key;
- vb2_error_t rv;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -354,11 +330,9 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
/* Finalize the digest */
if (dc->using_hwcrypto)
- rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size);
+ VB2_TRY(vb2ex_hwcrypto_digest_finalize(digest, digest_size));
else
- rv = vb2_digest_finalize(dc, digest, digest_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
/* The code below is specific to the body signature */
if (sd->hash_tag != VB2_HASH_TAG_FW_BODY)
@@ -373,19 +347,16 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
if (!sd->data_key_size)
return VB2_ERROR_API_CHECK_HASH_DATA_KEY;
- rv = vb2_unpack_key_buffer(&key,
- vb2_member_of(sd, sd->data_key_offset),
- sd->data_key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_unpack_key_buffer(&key,
+ vb2_member_of(sd, sd->data_key_offset),
+ sd->data_key_size));
/*
* Check digest vs. signature. Note that this destroys the signature.
* That's ok, because we only check each signature once per boot.
*/
- rv = vb2_verify_digest(&key, &pre->body_signature, digest, &wb);
- if (rv)
- vb2api_fail(ctx, VB2_RECOVERY_FW_BODY, rv);
+ VB2_TRY(vb2_verify_digest(&key, &pre->body_signature, digest, &wb),
+ ctx, VB2_RECOVERY_FW_BODY);
if (digest_out != NULL) {
if (digest_out_size < digest_size)
@@ -393,7 +364,7 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
memcpy(digest_out, digest, digest_size);
}
- return rv;
+ return VB2_SUCCESS;
}
int vb2api_check_hash(struct vb2_context *ctx)
diff --git a/firmware/2lib/2auxfw_sync.c b/firmware/2lib/2auxfw_sync.c
index ec0c8345..d5182b36 100644
--- a/firmware/2lib/2auxfw_sync.c
+++ b/firmware/2lib/2auxfw_sync.c
@@ -98,12 +98,9 @@ static vb2_error_t auxfw_sync_check_update(struct vb2_context *ctx,
vb2_error_t vb2api_auxfw_sync(struct vb2_context *ctx)
{
enum vb2_auxfw_update_severity fw_update = VB_AUX_FW_NO_UPDATE;
- vb2_error_t rv;
/* Check for update severity */
- rv = auxfw_sync_check_update(ctx, &fw_update);
- if (rv)
- return rv;
+ VB2_TRY(auxfw_sync_check_update(ctx, &fw_update));
/* If AUX FW update is slow display the wait screen */
if (fw_update == VB_AUX_FW_SLOW_UPDATE) {
@@ -114,9 +111,7 @@ vb2_error_t vb2api_auxfw_sync(struct vb2_context *ctx)
}
if (fw_update > VB_AUX_FW_NO_UPDATE) {
- rv = update_auxfw(ctx);
- if (rv)
- return rv;
+ VB2_TRY(update_auxfw(ctx));
/*
* AUX FW Update is applied successfully. Request EC reboot to
* RO, so that the chips that had FW update get reset to a
diff --git a/firmware/2lib/2common.c b/firmware/2lib/2common.c
index b05e7245..e51b84ff 100644
--- a/firmware/2lib/2common.c
+++ b/firmware/2lib/2common.c
@@ -176,7 +176,6 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size,
struct vb2_digest_context *dc;
uint8_t *digest;
uint32_t digest_size;
- vb2_error_t rv;
if (sig->data_size > size) {
VB2_DEBUG("Data buffer smaller than length of signed data.\n");
@@ -197,17 +196,9 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size,
if (!dc)
return VB2_ERROR_VDATA_WORKBUF_HASHING;
- rv = vb2_digest_init(dc, key->hash_alg);
- if (rv)
- return rv;
-
- rv = vb2_digest_extend(dc, data, sig->data_size);
- if (rv)
- return rv;
-
- rv = vb2_digest_finalize(dc, digest, digest_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_init(dc, key->hash_alg));
+ VB2_TRY(vb2_digest_extend(dc, data, sig->data_size));
+ VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
vb2_workbuf_free(&wblocal, sizeof(*dc));
@@ -277,9 +268,7 @@ vb2_error_t vb2_verify_keyblock(struct vb2_keyblock *block, uint32_t size,
vb2_error_t rv;
/* Sanity check keyblock before attempting signature check of data */
- rv = vb2_check_keyblock(block, size, sig);
- if (rv)
- return rv;
+ VB2_TRY(vb2_check_keyblock(block, size, sig));
VB2_DEBUG("Checking keyblock signature...\n");
rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb);
diff --git a/firmware/2lib/2ec_sync.c b/firmware/2lib/2ec_sync.c
index 1871b50c..e82366d9 100644
--- a/firmware/2lib/2ec_sync.c
+++ b/firmware/2lib/2ec_sync.c
@@ -472,7 +472,6 @@ static vb2_error_t ec_sync_phase2(struct vb2_context *ctx)
vb2_error_t vb2api_ec_sync(struct vb2_context *ctx)
{
struct vb2_shared_data *sd = vb2_get_sd(ctx);
- vb2_error_t rv;
/*
* If the status indicates that the EC has already gone through
@@ -506,14 +505,10 @@ vb2_error_t vb2api_ec_sync(struct vb2_context *ctx)
display_wait_screen(ctx);
/* Phase 2; Applies update and/or jumps to the correct EC image */
- rv = ec_sync_phase2(ctx);
- if (rv)
- return rv;
+ VB2_TRY(ec_sync_phase2(ctx));
/* Phase 3; Let the platform know that EC software sync is now done */
- rv = vb2ex_ec_vboot_done(ctx);
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_ec_vboot_done(ctx));
/* Establish that EC software sync is complete and successful */
sd->status |= VB2_SD_STATUS_EC_SYNC_COMPLETE;
diff --git a/firmware/2lib/2gbb.c b/firmware/2lib/2gbb.c
index a752c8ba..9238c30c 100644
--- a/firmware/2lib/2gbb.c
+++ b/firmware/2lib/2gbb.c
@@ -14,7 +14,6 @@ static vb2_error_t vb2_gbb_read_key(struct vb2_context *ctx, uint32_t offset,
struct vb2_workbuf *wb)
{
struct vb2_workbuf wblocal = *wb;
- vb2_error_t rv;
/* Check offset and size. */
if (offset < sizeof(struct vb2_gbb_header))
@@ -27,14 +26,10 @@ static vb2_error_t vb2_gbb_read_key(struct vb2_context *ctx, uint32_t offset,
*keyp = vb2_workbuf_alloc(&wblocal, sizeof(**keyp));
if (!*keyp)
return VB2_ERROR_GBB_WORKBUF;
- rv = vb2ex_read_resource(ctx, VB2_RES_GBB, offset, *keyp,
- sizeof(**keyp));
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB, offset, *keyp,
+ sizeof(**keyp)));
- rv = vb2_verify_packed_key_inside(*keyp, *size, *keyp);
- if (rv)
- return rv;
+ VB2_TRY(vb2_verify_packed_key_inside(*keyp, *size, *keyp));
/* Deal with a zero-size key (used in testing). */
*size = (*keyp)->key_offset + (*keyp)->key_size;
@@ -46,13 +41,12 @@ static vb2_error_t vb2_gbb_read_key(struct vb2_context *ctx, uint32_t offset,
if (!*keyp)
return VB2_ERROR_GBB_WORKBUF;
- rv = vb2ex_read_resource(ctx, VB2_RES_GBB,
- offset + sizeof(**keyp),
- (void *)*keyp + sizeof(**keyp),
- *size - sizeof(**keyp));
- if (!rv)
- *wb = wblocal;
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB,
+ offset + sizeof(**keyp),
+ (void *)*keyp + sizeof(**keyp),
+ *size - sizeof(**keyp)));
+ *wb = wblocal;
+ return VB2_SUCCESS;
}
vb2_error_t vb2_gbb_read_root_key(struct vb2_context *ctx,
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index ac9d0f24..30d6011c 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -52,17 +52,11 @@ test_mockable
vb2_error_t vb2_read_gbb_header(struct vb2_context *ctx,
struct vb2_gbb_header *gbb)
{
- vb2_error_t rv;
-
/* Read the entire header */
- rv = vb2ex_read_resource(ctx, VB2_RES_GBB, 0, gbb, sizeof(*gbb));
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB, 0, gbb, sizeof(*gbb)));
/* Make sure it's really a GBB */
- rv = vb2_validate_gbb_signature(gbb->signature);
- if (rv)
- return rv;
+ VB2_TRY(vb2_validate_gbb_signature(gbb->signature));
/* Check for compatible version */
if (gbb->major_version != VB2_GBB_MAJOR_VER)
@@ -176,7 +170,6 @@ vb2_error_t vb2_fw_init_gbb(struct vb2_context *ctx)
struct vb2_shared_data *sd = vb2_get_sd(ctx);
struct vb2_gbb_header *gbb;
struct vb2_workbuf wb;
- vb2_error_t rv;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -185,9 +178,7 @@ vb2_error_t vb2_fw_init_gbb(struct vb2_context *ctx)
if (!gbb)
return VB2_ERROR_GBB_WORKBUF;
- rv = vb2_read_gbb_header(ctx, gbb);
- if (rv)
- return rv;
+ VB2_TRY(vb2_read_gbb_header(ctx, gbb));
/* Keep on the work buffer permanently */
sd->gbb_offset = vb2_offset_of(sd, gbb);
diff --git a/firmware/2lib/2secdata_firmware.c b/firmware/2lib/2secdata_firmware.c
index 98e65b05..b5d9692a 100644
--- a/firmware/2lib/2secdata_firmware.c
+++ b/firmware/2lib/2secdata_firmware.c
@@ -56,11 +56,8 @@ uint32_t vb2api_secdata_firmware_create(struct vb2_context *ctx)
vb2_error_t vb2_secdata_firmware_init(struct vb2_context *ctx)
{
struct vb2_shared_data *sd = vb2_get_sd(ctx);
- vb2_error_t rv;
- rv = vb2api_secdata_firmware_check(ctx);
- if (rv)
- return rv;
+ VB2_TRY(vb2api_secdata_firmware_check(ctx));
/* Set status flag */
sd->status |= VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
diff --git a/firmware/2lib/2secdata_fwmp.c b/firmware/2lib/2secdata_fwmp.c
index ec6cc6c3..a28b5bbf 100644
--- a/firmware/2lib/2secdata_fwmp.c
+++ b/firmware/2lib/2secdata_fwmp.c
@@ -65,14 +65,10 @@ vb2_error_t vb2_secdata_fwmp_init(struct vb2_context *ctx)
struct vb2_shared_data *sd = vb2_get_sd(ctx);
struct vb2_secdata_fwmp *sec =
(struct vb2_secdata_fwmp *)&ctx->secdata_fwmp;
- vb2_error_t rv;
/* Skip checking if NO_SECDATA_FWMP is set. */
- if (!(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP)) {
- rv = vb2api_secdata_fwmp_check(ctx, &sec->struct_size);
- if (rv)
- return rv;
- }
+ if (!(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP))
+ VB2_TRY(vb2api_secdata_fwmp_check(ctx, &sec->struct_size));
/* Mark as initialized */
sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
diff --git a/firmware/2lib/2secdata_kernel.c b/firmware/2lib/2secdata_kernel.c
index f4d1b825..04763a1f 100644
--- a/firmware/2lib/2secdata_kernel.c
+++ b/firmware/2lib/2secdata_kernel.c
@@ -166,11 +166,8 @@ vb2_error_t vb2_secdata_kernel_init(struct vb2_context *ctx)
{
struct vb2_shared_data *sd = vb2_get_sd(ctx);
uint8_t size = VB2_SECDATA_KERNEL_MAX_SIZE;
- vb2_error_t rv;
- rv = vb2api_secdata_kernel_check(ctx, &size);
- if (rv)
- return rv;
+ VB2_TRY(vb2api_secdata_kernel_check(ctx, &size));
/* Set status flag */
sd->status |= VB2_SD_STATUS_SECDATA_KERNEL_INIT;
diff --git a/firmware/2lib/2sha_utility.c b/firmware/2lib/2sha_utility.c
index 16a41f94..4c8d41ca 100644
--- a/firmware/2lib/2sha_utility.c
+++ b/firmware/2lib/2sha_utility.c
@@ -203,15 +203,9 @@ vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
uint32_t digest_size)
{
struct vb2_digest_context dc;
- vb2_error_t rv;
- rv = vb2_digest_init(&dc, hash_alg);
- if (rv)
- return rv;
-
- rv = vb2_digest_extend(&dc, buf, size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_init(&dc, hash_alg));
+ VB2_TRY(vb2_digest_extend(&dc, buf, size));
return vb2_digest_finalize(&dc, digest, digest_size);
}
@@ -221,10 +215,8 @@ vb2_error_t vb2_hash_verify(const void *buf, uint32_t size,
{
uint8_t hash_buf[VB2_MAX_DIGEST_SIZE];
size_t hash_size = vb2_digest_size(hash->algo);
- vb2_error_t rv = vb2_digest_buffer(buf, size, hash->algo,
- hash_buf, hash_size);
- if (rv)
- return rv;
+
+ VB2_TRY(vb2_digest_buffer(buf, size, hash->algo, hash_buf, hash_size));
if (memcmp(hash_buf, hash->raw, hash_size))
return VB2_ERROR_SHA_MISMATCH;
else
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index 6be8a8d4..d932dbe0 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -28,6 +28,39 @@
#include "2return_codes.h"
#include "2secdata_struct.h"
+#define _VB2_TRY_IMPL(expr, ctx, recovery_reason, ...) do { \
+ vb2_error_t _vb2_try_rv = (expr); \
+ struct vb2_context *_vb2_try_ctx = (ctx); \
+ uint8_t _vb2_try_reason = (recovery_reason); \
+ if (_vb2_try_rv != VB2_SUCCESS) { \
+ vb2ex_printf(__func__, \
+ "%s returned %#x\n", #expr, _vb2_try_rv); \
+ if ((_vb2_try_ctx) && \
+ (_vb2_try_reason) != VB2_RECOVERY_NOT_REQUESTED) \
+ vb2api_fail(_vb2_try_ctx, _vb2_try_reason, \
+ _vb2_try_rv); \
+ return _vb2_try_rv; \
+ } \
+} while (0)
+
+/*
+ * Evaluate an expression and return *from the caller* on failure.
+ *
+ * This macro supports two forms of usage:
+ * 1. VB2_TRY(expr)
+ * 2. VB2_TRY(expr, ctx, recovery_reason)
+ *
+ * When the second form is used, vb2api_fail() will be called on failure before
+ * return. Note that nvdata only holds one byte for recovery subcode, so any
+ * other more significant bytes will be truncated.
+ *
+ * @param expr An expression (such as a function call) of type
+ * vb2_error_t.
+ * @param ctx Vboot context.
+ * @param recovery_reason Recovery reason passed to vb2api_fail().
+ */
+#define VB2_TRY(expr, ...) _VB2_TRY_IMPL(expr, ##__VA_ARGS__, NULL, 0)
+
/* Modes for vb2ex_tpm_set_mode. */
enum vb2_tpm_mode {
/*
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 8b7aab9e..4f86046a 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -35,8 +35,6 @@ struct LoadKernelParams *VbApiKernelGetParams(void)
static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx)
{
- vb2_error_t rv;
-
/*
* Check if we need to cut-off battery. This should be done after EC
* FW and Aux FW are updated, and before the kernel is started. This
@@ -48,9 +46,7 @@ static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx)
vb2_nv_set(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST, 0);
/* May lose power immediately, so commit our update now. */
- rv = vb2ex_commit_data(ctx);
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_commit_data(ctx));
vb2ex_ec_battery_cutoff();
return VBERROR_SHUTDOWN_REQUESTED;
@@ -181,19 +177,14 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
VbSelectAndLoadKernelParams *kparams)
{
struct vb2_shared_data *sd = vb2_get_sd(ctx);
- vb2_error_t rv;
/* Init nvstorage space. TODO(kitching): Remove once we add assertions
to vb2_nv_get and vb2_nv_set. */
vb2_nv_init(ctx);
- rv = vb2_kernel_init_kparams(ctx, kparams);
- if (rv)
- return rv;
+ VB2_TRY(vb2_kernel_init_kparams(ctx, kparams));
- rv = vb2api_kernel_phase1(ctx);
- if (rv)
- return rv;
+ VB2_TRY(vb2api_kernel_phase1(ctx));
VB2_DEBUG("GBB flags are %#x\n", vb2_get_gbb(ctx)->flags);
@@ -202,17 +193,9 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
* has UI but it's just a single non-interactive WAIT screen.
*/
if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
- rv = vb2api_ec_sync(ctx);
- if (rv)
- return rv;
-
- rv = vb2api_auxfw_sync(ctx);
- if (rv)
- return rv;
-
- rv = handle_battery_cutoff(ctx);
- if (rv)
- return rv;
+ VB2_TRY(vb2api_ec_sync(ctx));
+ VB2_TRY(vb2api_auxfw_sync(ctx));
+ VB2_TRY(handle_battery_cutoff(ctx));
}
/* Select boot path */
@@ -244,13 +227,13 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
/* Recovery boot. This has UI. */
if (MENU_UI) {
if (vb2_allow_recovery(ctx))
- rv = vb2_manual_recovery_menu(ctx);
+ VB2_TRY(vb2_manual_recovery_menu(ctx));
else
- rv = vb2_broken_recovery_menu(ctx);
+ VB2_TRY(vb2_broken_recovery_menu(ctx));
} else if (LEGACY_MENU_UI) {
- rv = VbBootRecoveryLegacyMenu(ctx);
+ VB2_TRY(VbBootRecoveryLegacyMenu(ctx));
} else {
- rv = VbBootRecoveryLegacyClamshell(ctx);
+ VB2_TRY(VbBootRecoveryLegacyClamshell(ctx));
}
} else if (DIAGNOSTIC_UI && vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST)) {
vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 0);
@@ -261,36 +244,32 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
* needed. This mode is also 1-shot so it's placed
* before developer mode.
*/
- rv = VbBootDiagnosticLegacyClamshell(ctx);
+ VB2_TRY(VbBootDiagnosticLegacyClamshell(ctx));
/*
* The diagnostic menu should either boot a rom, or
- * return either of reboot or shutdown. The following
- * check is a safety precaution.
+ * return either of reboot or shutdown.
*/
- if (!rv)
- rv = VBERROR_REBOOT_REQUIRED;
+ return VBERROR_REBOOT_REQUIRED;
} else if (ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) {
/* Developer boot. This has UI. */
if (MENU_UI)
- rv = vb2_developer_menu(ctx);
+ VB2_TRY(vb2_developer_menu(ctx));
else if (LEGACY_MENU_UI)
- rv = VbBootDeveloperLegacyMenu(ctx);
+ VB2_TRY(VbBootDeveloperLegacyMenu(ctx));
else
- rv = VbBootDeveloperLegacyClamshell(ctx);
+ VB2_TRY(VbBootDeveloperLegacyClamshell(ctx));
} else {
/* Normal boot */
- rv = vb2_normal_boot(ctx);
+ VB2_TRY(vb2_normal_boot(ctx));
}
- if (VB2_SUCCESS == rv && (ctx->flags & VB2_CONTEXT_NO_BOOT)) {
+ if (ctx->flags & VB2_CONTEXT_NO_BOOT) {
/* Stop all cases returning SUCCESS against NO_BOOT flag. */
VB2_DEBUG("Blocking boot in NO_BOOT mode.\n");
- vb2api_fail(ctx, VB2_RECOVERY_RW_INVALID_OS, rv);
- rv = VB2_ERROR_ESCAPE_NO_BOOT;
+ vb2api_fail(ctx, VB2_RECOVERY_RW_INVALID_OS, 0);
+ return VB2_ERROR_ESCAPE_NO_BOOT;
}
- if (rv == VB2_SUCCESS)
- vb2_kernel_fill_kparams(ctx, kparams);
-
- return rv;
+ vb2_kernel_fill_kparams(ctx, kparams);
+ return VB2_SUCCESS;
}
diff --git a/firmware/lib20/api_kernel.c b/firmware/lib20/api_kernel.c
index 36456f61..9ab85222 100644
--- a/firmware/lib20/api_kernel.c
+++ b/firmware/lib20/api_kernel.c
@@ -18,17 +18,11 @@
vb2_error_t vb2api_load_kernel_vblock(struct vb2_context *ctx)
{
- vb2_error_t rv;
-
/* Verify kernel keyblock */
- rv = vb2_load_kernel_keyblock(ctx);
- if (rv)
- return rv;
+ VB2_TRY(vb2_load_kernel_keyblock(ctx));
/* Verify kernel preamble */
- rv = vb2_load_kernel_preamble(ctx);
- if (rv)
- return rv;
+ VB2_TRY(vb2_load_kernel_preamble(ctx));
return VB2_SUCCESS;
}
@@ -72,8 +66,6 @@ vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf,
uint8_t *digest;
uint32_t digest_size;
- vb2_error_t rv;
-
vb2_workbuf_from_ctx(ctx, &wb);
/* Get preamble pointer */
@@ -104,28 +96,20 @@ vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf,
if (!sd->data_key_size)
return VB2_ERROR_API_VERIFY_KDATA_KEY;
- rv = vb2_unpack_key_buffer(&key,
- vb2_member_of(sd, sd->data_key_offset),
- sd->data_key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_unpack_key_buffer(&key,
+ vb2_member_of(sd, sd->data_key_offset),
+ sd->data_key_size));
- rv = vb2_digest_init(dc, key.hash_alg);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_init(dc, key.hash_alg));
- rv = vb2_digest_extend(dc, buf, size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_extend(dc, buf, size));
digest_size = vb2_digest_size(key.hash_alg);
digest = vb2_workbuf_alloc(&wb, digest_size);
if (!digest)
return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;
- rv = vb2_digest_finalize(dc, digest, digest_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
/*
* The body signature is currently a *signature* of the body data, not
diff --git a/firmware/lib20/kernel.c b/firmware/lib20/kernel.c
index 8e340349..ed04c6f3 100644
--- a/firmware/lib20/kernel.c
+++ b/firmware/lib20/kernel.c
@@ -45,12 +45,9 @@ vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
struct vb2_digest_context *dc;
uint8_t *digest;
uint32_t digest_size;
- vb2_error_t rv;
/* Sanity check keyblock before attempting hash check of data */
- rv = vb2_check_keyblock(block, size, sig);
- if (rv)
- return rv;
+ VB2_TRY(vb2_check_keyblock(block, size, sig));
VB2_DEBUG("Checking keyblock hash...\n");
@@ -65,17 +62,11 @@ vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
if (!dc)
return VB2_ERROR_VDATA_WORKBUF_HASHING;
- rv = vb2_digest_init(dc, VB2_HASH_SHA512);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_init(dc, VB2_HASH_SHA512));
- rv = vb2_digest_extend(dc, (const uint8_t *)block, sig->data_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_extend(dc, (const uint8_t *)block, sig->data_size));
- rv = vb2_digest_finalize(dc, digest, digest_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
if (vb2_safe_memcmp(vb2_signature_data(sig), digest,
digest_size) != 0) {
@@ -119,19 +110,15 @@ vb2_error_t vb2_load_kernel_keyblock(struct vb2_context *ctx)
/* Unpack the kernel key */
key_data = vb2_member_of(sd, sd->kernel_key_offset);
key_size = sd->kernel_key_size;
- rv = vb2_unpack_key_buffer(&kernel_key, key_data, key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_unpack_key_buffer(&kernel_key, key_data, key_size));
/* Load the kernel keyblock header after the root key */
kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
if (!kb)
return VB2_ERROR_KERNEL_KEYBLOCK_WORKBUF_HEADER;
- rv = vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK, 0, kb,
- sizeof(*kb));
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK, 0, kb,
+ sizeof(*kb)));
block_size = kb->keyblock_size;
@@ -145,9 +132,8 @@ vb2_error_t vb2_load_kernel_keyblock(struct vb2_context *ctx)
if (!kb)
return VB2_ERROR_KERNEL_KEYBLOCK_WORKBUF;
- rv = vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK, 0, kb, block_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK, 0, kb,
+ block_size));
/* Verify the keyblock */
rv = vb2_verify_keyblock(kb, block_size, &kernel_key, &wb);
@@ -157,9 +143,7 @@ vb2_error_t vb2_load_kernel_keyblock(struct vb2_context *ctx)
return rv;
/* Signature is invalid, but hash may be fine */
- rv = vb2_verify_keyblock_hash(kb, block_size, &wb);
- if (rv)
- return rv;
+ VB2_TRY(vb2_verify_keyblock_hash(kb, block_size, &wb));
}
/* Check the keyblock flags against the current boot mode */
@@ -363,28 +347,22 @@ vb2_error_t vb2_load_kernel_preamble(struct vb2_context *ctx)
struct vb2_kernel_preamble *pre;
uint32_t pre_size;
- vb2_error_t rv;
-
vb2_workbuf_from_ctx(ctx, &wb);
/* Unpack the kernel data key */
if (!sd->data_key_size)
return VB2_ERROR_KERNEL_PREAMBLE2_DATA_KEY;
- rv = vb2_unpack_key_buffer(&data_key, key_data, key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_unpack_key_buffer(&data_key, key_data, key_size));
/* Load the kernel preamble header */
pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
if (!pre)
return VB2_ERROR_KERNEL_PREAMBLE2_WORKBUF_HEADER;
- rv = vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK,
- sd->vblock_preamble_offset,
- pre, sizeof(*pre));
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK,
+ sd->vblock_preamble_offset,
+ pre, sizeof(*pre)));
pre_size = pre->preamble_size;
@@ -393,11 +371,9 @@ vb2_error_t vb2_load_kernel_preamble(struct vb2_context *ctx)
if (!pre)
return VB2_ERROR_KERNEL_PREAMBLE2_WORKBUF;
- rv = vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK,
- sd->vblock_preamble_offset,
- pre, pre_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_KERNEL_VBLOCK,
+ sd->vblock_preamble_offset,
+ pre, pre_size));
/*
* Work buffer now contains:
@@ -408,9 +384,7 @@ vb2_error_t vb2_load_kernel_preamble(struct vb2_context *ctx)
*/
/* Verify the preamble */
- rv = vb2_verify_kernel_preamble(pre, pre_size, &data_key, &wb);
- if (rv)
- return rv;
+ VB2_TRY(vb2_verify_kernel_preamble(pre, pre_size, &data_key, &wb));
/*
* Kernel preamble version is the lower 16 bits of the composite kernel
diff --git a/firmware/lib20/misc.c b/firmware/lib20/misc.c
index da12f028..4e1250c0 100644
--- a/firmware/lib20/misc.c
+++ b/firmware/lib20/misc.c
@@ -27,7 +27,7 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
struct vb2_keyblock *kb;
uint32_t block_size;
- vb2_error_t rv;
+ vb2_error_t rv = VB2_SUCCESS;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -37,24 +37,19 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
if (!key_data)
return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY;
- rv = vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->rootkey_offset,
- key_data, key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->rootkey_offset,
+ key_data, key_size));
/* Unpack the root key */
- rv = vb2_unpack_key_buffer(&root_key, key_data, key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_unpack_key_buffer(&root_key, key_data, key_size));
/* Load the firmware keyblock header after the root key */
kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
if (!kb)
return VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER;
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, sizeof(*kb));
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0,
+ kb, sizeof(*kb)));
block_size = kb->keyblock_size;
@@ -68,16 +63,11 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
if (!kb)
return VB2_ERROR_FW_KEYBLOCK_WORKBUF;
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size));
/* Verify the keyblock */
- rv = vb2_verify_keyblock(kb, block_size, &root_key, &wb);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_FW_KEYBLOCK, rv);
- return rv;
- }
+ VB2_TRY(vb2_verify_keyblock(kb, block_size, &root_key, &wb),
+ ctx, VB2_RECOVERY_FW_KEYBLOCK);
/* Key version is the upper 16 bits of the composite firmware version */
if (kb->data_key.key_version > VB2_MAX_KEY_VERSION)
@@ -104,9 +94,7 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
* no longer need the root key. First, let's double-check that it is
* well-formed though (although the keyblock was signed anyway).
*/
- rv = vb2_verify_packed_key_inside(kb, block_size, &kb->data_key);
- if (rv)
- return rv;
+ VB2_TRY(vb2_verify_packed_key_inside(kb, block_size, &kb->data_key));
/* Save the future offset and size while kb->data_key is still valid.
The check above made sure that key_offset and key_size are sane. */
@@ -149,7 +137,7 @@ vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx)
struct vb2_fw_preamble *pre;
uint32_t pre_size;
- vb2_error_t rv;
+ vb2_error_t rv = VB2_SUCCESS;
vb2_workbuf_from_ctx(ctx, &wb);
@@ -157,20 +145,16 @@ vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx)
if (!sd->data_key_size)
return VB2_ERROR_FW_PREAMBLE2_DATA_KEY;
- rv = vb2_unpack_key_buffer(&data_key, key_data, key_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2_unpack_key_buffer(&data_key, key_data, key_size));
/* Load the firmware preamble header */
pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
if (!pre)
return VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER;
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
- sd->vblock_preamble_offset,
- pre, sizeof(*pre));
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
+ sd->vblock_preamble_offset,
+ pre, sizeof(*pre)));
pre_size = pre->preamble_size;
@@ -179,20 +163,15 @@ vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx)
if (!pre)
return VB2_ERROR_FW_PREAMBLE2_WORKBUF;
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
- sd->vblock_preamble_offset,
- pre, pre_size);
- if (rv)
- return rv;
+ VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
+ sd->vblock_preamble_offset,
+ pre, pre_size));
/* Work buffer now contains the data subkey data and the preamble */
/* Verify the preamble */
- rv = vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_FW_PREAMBLE, rv);
- return rv;
- }
+ VB2_TRY(vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb),
+ ctx, VB2_RECOVERY_FW_PREAMBLE);
/*
* Firmware version is the lower 16 bits of the composite firmware
diff --git a/firmware/lib20/packed_key.c b/firmware/lib20/packed_key.c
index 20b36a37..6d8fdebe 100644
--- a/firmware/lib20/packed_key.c
+++ b/firmware/lib20/packed_key.c
@@ -18,12 +18,9 @@ vb2_error_t vb2_unpack_key_buffer(struct vb2_public_key *key,
(const struct vb2_packed_key *)buf;
const uint32_t *buf32;
uint32_t expected_key_size;
- vb2_error_t rv;
/* Make sure passed buffer is big enough for the packed key */
- rv = vb2_verify_packed_key_inside(buf, size, packed_key);
- if (rv)
- return rv;
+ VB2_TRY(vb2_verify_packed_key_inside(buf, size, packed_key));
/* Unpack key algorithm */
key->sig_alg = vb2_crypto_to_signature(packed_key->algorithm);
diff --git a/tests/vb2_api_tests.c b/tests/vb2_api_tests.c
index 9cb2f195..50bdf742 100644
--- a/tests/vb2_api_tests.c
+++ b/tests/vb2_api_tests.c
@@ -267,6 +267,19 @@ vb2_error_t vb2_rsa_verify_digest(const struct vb2_public_key *key,
}
/* Tests */
+static int vb2_try_returned;
+
+static vb2_error_t call_vb2_try(vb2_error_t expr, uint8_t recovery_reason,
+ int one_arg)
+{
+ vb2_try_returned = 1;
+ if (one_arg)
+ VB2_TRY(expr);
+ else
+ VB2_TRY(expr, ctx, recovery_reason);
+ vb2_try_returned = 0;
+ return VB2_SUCCESS;
+}
static void misc_tests(void)
{
@@ -297,6 +310,35 @@ static void misc_tests(void)
reset_common_data(FOR_MISC);
sd->preamble_size = 0;
TEST_EQ(vb2api_get_firmware_size(ctx), 0, "firmware_size too early");
+
+ /* Test VB2_TRY() */
+ reset_common_data(FOR_MISC);
+ call_vb2_try(VB2_SUCCESS, VB2_RECOVERY_NOT_REQUESTED, 1);
+ TEST_EQ(vb2_try_returned, 0, "VB2_TRY(expr) success");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_NOT_REQUESTED, " vb2api_fail no request");
+
+ reset_common_data(FOR_MISC);
+ call_vb2_try(VB2_ERROR_MOCK, VB2_RECOVERY_NOT_REQUESTED, 1);
+ TEST_EQ(vb2_try_returned, 1, "VB2_TRY(expr) error");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_NOT_REQUESTED, " vb2api_fail no request");
+
+ reset_common_data(FOR_MISC);
+ call_vb2_try(VB2_SUCCESS, 123, 0);
+ TEST_EQ(vb2_try_returned, 0, "VB2_TRY(expr, ...) success");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_NOT_REQUESTED, " vb2api_fail no request");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE),
+ 0, " vb2api_fail no subcode");
+
+ reset_common_data(FOR_MISC);
+ call_vb2_try(456, 123, 0);
+ TEST_EQ(vb2_try_returned, 1, "VB2_TRY(expr, ...) error");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
+ 123, " vb2api_fail request");
+ TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE),
+ 456 & 0xff, " vb2api_fail subcode");
}
static void phase1_tests(void)