diff options
author | Randall Spangler <rspangler@chromium.org> | 2014-12-02 13:41:29 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-12-04 04:01:41 +0000 |
commit | a5b69b02e039d7267390fea10266d45e14630559 (patch) | |
tree | 723aff24181464dc12723f659ba40d112cc11958 /firmware/lib21/api.c | |
parent | c86f0415a0dd1ddea4497e18813a2dd00dd0e3f4 (diff) | |
download | vboot-a5b69b02e039d7267390fea10266d45e14630559.tar.gz |
vboot2: Move files which use new vboot 2.1 structs to their own directories
This is part 1 of a series of 4 changes which rearrange the vboot2
files and unit tests so that we can more cleanly switch over from
old-style structs to new-style structs.
No functional changes, just shuffling around code.
BUG=chromium:423882
BRANCH=none
TEST=make runtests && VBOOT2=1 make runtests (works with/withoug VBOOT2 flag)
And build firmware for veyron_pinky.
Change-Id: I170d737bf151a6bafe61cde23b3d2f7a3fae43ce
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/232978
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Diffstat (limited to 'firmware/lib21/api.c')
-rw-r--r-- | firmware/lib21/api.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/firmware/lib21/api.c b/firmware/lib21/api.c new file mode 100644 index 00000000..0df2cf69 --- /dev/null +++ b/firmware/lib21/api.c @@ -0,0 +1,146 @@ +/* Copyright (c) 2014 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. + * + * Externally-callable APIs + * (Firmware portion) + */ + +#include "2sysincludes.h" +#include "2api.h" +#include "2common.h" +#include "2misc.h" +#include "2nvstorage.h" +#include "2secdata.h" +#include "2sha.h" +#include "2rsa.h" + +int vb2api_fw_phase3_2(struct vb2_context *ctx) +{ + int rv; + + /* Verify firmware keyblock */ + rv = vb2_load_fw_keyblock2(ctx); + if (rv) { + vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); + return rv; + } + + /* Verify firmware preamble */ + rv = vb2_load_fw_preamble2(ctx); + if (rv) { + vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); + return rv; + } + + return VB2_SUCCESS; +} + +int vb2api_init_hash2(struct vb2_context *ctx, + const struct vb2_guid *guid, + uint32_t *size) +{ + struct vb2_shared_data *sd = vb2_get_sd(ctx); + const struct vb2_fw_preamble2 *pre; + const struct vb2_signature2 *sig = NULL; + struct vb2_digest_context *dc; + struct vb2_workbuf wb; + uint32_t hash_offset; + int i; + + vb2_workbuf_from_ctx(ctx, &wb); + + /* Get preamble pointer */ + if (!sd->workbuf_preamble_size) + return VB2_ERROR_API_INIT_HASH_PREAMBLE; + pre = (const struct vb2_fw_preamble2 *) + (ctx->workbuf + sd->workbuf_preamble_offset); + + /* Find the matching signature */ + hash_offset = pre->hash_offset; + for (i = 0; i < pre->hash_count; i++) { + sig = (const struct vb2_signature2 *) + ((uint8_t *)pre + hash_offset); + + if (!memcmp(guid, &sig->guid, sizeof(*guid))) + break; + + hash_offset += sig->c.total_size; + } + if (i >= pre->hash_count) + return VB2_ERROR_API_INIT_HASH_GUID; /* No match */ + + /* Allocate workbuf space for the hash */ + if (sd->workbuf_hash_size) { + dc = (struct vb2_digest_context *) + (ctx->workbuf + sd->workbuf_hash_offset); + } else { + uint32_t dig_size = sizeof(*dc); + + dc = vb2_workbuf_alloc(&wb, dig_size); + if (!dc) + return VB2_ERROR_API_INIT_HASH_WORKBUF; + + sd->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc); + sd->workbuf_hash_size = dig_size; + ctx->workbuf_used = sd->workbuf_hash_offset + dig_size; + } + + sd->hash_tag = vb2_offset_of(ctx->workbuf, sig); + sd->hash_remaining_size = sig->data_size; + + if (size) + *size = sig->data_size; + + return vb2_digest_init(dc, sig->hash_alg); +} + +int vb2api_check_hash2(struct vb2_context *ctx) +{ + struct vb2_shared_data *sd = vb2_get_sd(ctx); + struct vb2_digest_context *dc = (struct vb2_digest_context *) + (ctx->workbuf + sd->workbuf_hash_offset); + struct vb2_workbuf wb; + + uint8_t *digest; + uint32_t digest_size = vb2_digest_size(dc->hash_alg); + + const struct vb2_signature2 *sig; + + int rv; + + vb2_workbuf_from_ctx(ctx, &wb); + + /* Get signature pointer */ + if (!sd->hash_tag) + return VB2_ERROR_API_CHECK_HASH_TAG; + sig = (const struct vb2_signature2 *)(ctx->workbuf + sd->hash_tag); + + /* Must have initialized hash digest work area */ + if (!sd->workbuf_hash_size) + return VB2_ERROR_API_CHECK_HASH_WORKBUF; + + /* Should have hashed the right amount of data */ + if (sd->hash_remaining_size) + return VB2_ERROR_API_CHECK_HASH_SIZE; + + /* Allocate the digest */ + digest = vb2_workbuf_alloc(&wb, digest_size); + if (!digest) + return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST; + + /* Finalize the digest */ + rv = vb2_digest_finalize(dc, digest, digest_size); + if (rv) + return rv; + + /* Compare with the signature */ + if (vb2_safe_memcmp(digest, (const uint8_t *)sig + sig->sig_offset, + digest_size)) + return VB2_ERROR_API_CHECK_HASH_SIG; + + // TODO: the old check-hash function called vb2_fail() on any mismatch. + // I don't think it should do that; the caller should. + + return VB2_SUCCESS; +} |