/* Copyright 2019 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. * * GBB accessor functions. */ #include "2common.h" #include "2misc.h" static int vb2_gbb_read_key(struct vb2_context *ctx, uint32_t offset, uint32_t *size, struct vb2_packed_key **keyp, struct vb2_workbuf *wb) { struct vb2_workbuf wblocal = *wb; int rv; /* Check offset and size. */ if (offset < sizeof(struct vb2_gbb_header)) return VB2_ERROR_GBB_INVALID; if (*size < sizeof(**keyp)) return VB2_ERROR_GBB_INVALID; /* GBB header might be padded. Retrieve the vb2_packed_key header so we can find out what the real size is. */ *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; rv = vb2_verify_packed_key_inside(*keyp, *size, *keyp); if (rv) return rv; /* Deal with a zero-size key (used in testing). */ *size = (*keyp)->key_offset + (*keyp)->key_size; if (*size < sizeof(**keyp)) *size = sizeof(**keyp); /* Now that we know the real size of the key, retrieve the key data, and write it on the workbuf, directly after vb2_packed_key. */ *keyp = vb2_workbuf_realloc(&wblocal, sizeof(**keyp), *size); 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; } int vb2_gbb_read_root_key(struct vb2_context *ctx, struct vb2_packed_key **keyp, uint32_t *size, struct vb2_workbuf *wb) { struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); uint32_t size_in = gbb->rootkey_size; int ret = vb2_gbb_read_key(ctx, gbb->rootkey_offset, &size_in, keyp, wb); if (size) *size = size_in; return ret; } int vb2_gbb_read_recovery_key(struct vb2_context *ctx, struct vb2_packed_key **keyp, uint32_t *size, struct vb2_workbuf *wb) { struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); uint32_t size_in = gbb->recovery_key_size; int ret = vb2_gbb_read_key(ctx, gbb->recovery_key_offset, &size_in, keyp, wb); if (size) *size = size_in; return ret; } int vb2api_gbb_read_hwid(struct vb2_context *ctx, char *hwid, uint32_t *size) { struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); uint32_t i; int ret; if (gbb->hwid_size == 0) { VB2_DEBUG("invalid HWID size %d\n", gbb->hwid_size); return VB2_ERROR_GBB_INVALID; } if (*size > VB2_GBB_HWID_MAX_SIZE) *size = VB2_GBB_HWID_MAX_SIZE; if (*size > gbb->hwid_size) *size = gbb->hwid_size; ret = vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->hwid_offset, hwid, *size); if (ret) { VB2_DEBUG("read resource failure: %d\n", ret); return ret; } /* Count HWID size, and ensure that it fits in the given buffer. */ for (i = 0; i < *size; i++) { if (hwid[i] == '\0') { *size = i + 1; break; } } if (hwid[*size - 1] != '\0') return VB2_ERROR_INVALID_PARAMETER; return VB2_SUCCESS; } vb2_gbb_flags_t vb2api_gbb_get_flags(struct vb2_context *ctx) { struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); return gbb->flags; }