/* Copyright (c) 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. * * Functions for initializing the vboot workbuffer and vb2_context. */ #include "2api.h" #include "2common.h" #include "2misc.h" #include "2sysincludes.h" void vb2_workbuf_from_ctx(struct vb2_context *ctx, struct vb2_workbuf *wb) { struct vb2_shared_data *sd = vb2_get_sd(ctx); vb2_workbuf_init(wb, (void *)sd + sd->workbuf_used, sd->workbuf_size - sd->workbuf_used); } void vb2_set_workbuf_used(struct vb2_context *ctx, uint32_t used) { struct vb2_shared_data *sd = vb2_get_sd(ctx); sd->workbuf_used = vb2_wb_round_up(used); } vb2_error_t vb2api_init(void *workbuf, uint32_t size, struct vb2_context **ctxptr) { struct vb2_shared_data *sd = workbuf; *ctxptr = NULL; if (!vb2_aligned(workbuf, VB2_WORKBUF_ALIGN)) return VB2_ERROR_WORKBUF_ALIGN; if (size < vb2_wb_round_up(sizeof(*sd))) return VB2_ERROR_WORKBUF_SMALL; /* Zero out vb2_shared_data (which includes vb2_context). */ memset(sd, 0, sizeof(*sd)); /* Initialize shared data. */ sd->magic = VB2_SHARED_DATA_MAGIC; sd->struct_version_major = VB2_SHARED_DATA_VERSION_MAJOR; sd->struct_version_minor = VB2_SHARED_DATA_VERSION_MINOR; sd->workbuf_size = size; sd->workbuf_used = vb2_wb_round_up(sizeof(*sd)); *ctxptr = &sd->ctx; return VB2_SUCCESS; } #pragma GCC diagnostic push /* Don't warn for the version_minor check even if the checked version is 0. */ #pragma GCC diagnostic ignored "-Wtype-limits" vb2_error_t vb2api_relocate(void *new_workbuf, const void *cur_workbuf, uint32_t size, struct vb2_context **ctxptr) { const struct vb2_shared_data *cur_sd = cur_workbuf; struct vb2_shared_data *new_sd; if (!vb2_aligned(new_workbuf, VB2_WORKBUF_ALIGN)) return VB2_ERROR_WORKBUF_ALIGN; /* Check magic and version. */ if (cur_sd->magic != VB2_SHARED_DATA_MAGIC) return VB2_ERROR_SHARED_DATA_MAGIC; if (cur_sd->struct_version_major != VB2_SHARED_DATA_VERSION_MAJOR || cur_sd->struct_version_minor < VB2_SHARED_DATA_VERSION_MINOR) return VB2_ERROR_SHARED_DATA_VERSION; /* Check workbuf integrity. */ if (cur_sd->workbuf_used < vb2_wb_round_up(sizeof(*cur_sd))) return VB2_ERROR_WORKBUF_INVALID; if (cur_sd->workbuf_size < cur_sd->workbuf_used) return VB2_ERROR_WORKBUF_INVALID; if (cur_sd->workbuf_used > size) return VB2_ERROR_WORKBUF_SMALL; /* Relocate if necessary. */ if (cur_workbuf != new_workbuf) memmove(new_workbuf, cur_workbuf, cur_sd->workbuf_used); /* Set the new size, and return the context pointer. */ new_sd = new_workbuf; new_sd->workbuf_size = size; *ctxptr = &new_sd->ctx; return VB2_SUCCESS; } #pragma GCC diagnostic pop vb2_error_t vb2api_reinit(void *workbuf, struct vb2_context **ctxptr) { /* Blindly retrieve workbuf_size. vb2api_relocate() will perform workbuf validation checks. */ struct vb2_shared_data *sd = workbuf; return vb2api_relocate(workbuf, workbuf, sd->workbuf_size, ctxptr); }