Files
OpenCellular/firmware/lib21/api.c
Randall Spangler 308d254092 vboot2: Get rid of extra '2' at end of new struct names
Now that lib20 and lib21 are distinct, they can have overlapping
struct names.  This will be cleaner in the long run, since vboot 2.0
(lib20) is just a temporary stepping stone to vboot 2.1 (lib21).  It
would be a shame to need to carry around the overhead of that extra
digit forever.

No functional changes, just a lot of renaming.

BUG=chromium:423882
BRANCH=none
TEST=make runtests && VBOOT2=1 make runtests (works with/withoug VBOOT2 flag)
     And compile firmware for veyron_pinky

Change-Id: I25f348fd31e32d08ca576836dfdd1278828765a1
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/233183
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
2014-12-05 00:02:00 +00:00

148 lines
3.6 KiB
C

/* 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"
#include "vb2_common.h"
int vb2api_fw_phase3(struct vb2_context *ctx)
{
int rv;
/* Verify firmware keyblock */
rv = vb2_load_fw_keyblock(ctx);
if (rv) {
vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
return rv;
}
/* Verify firmware preamble */
rv = vb2_load_fw_preamble(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_preamble *pre;
const struct vb2_signature *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_preamble *)
(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_signature *)
((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_hash(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_signature *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_signature *)(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;
}