| /* 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); |
| } |