summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mok.h18
-rw-r--r--mok.c16
2 files changed, 33 insertions, 1 deletions
diff --git a/include/mok.h b/include/mok.h
index fe92cf03..c37ccba5 100644
--- a/include/mok.h
+++ b/include/mok.h
@@ -17,6 +17,7 @@ typedef enum {
struct mok_state_variable;
typedef vendor_addend_category_t (vendor_addend_categorizer_t)(struct mok_state_variable *);
+typedef UINTN (mok_variable_format_helper_t)(UINT8 *buf, size_t sz, struct mok_state_variable *);
/*
* MoK variables that need to have their storage validated.
@@ -91,6 +92,23 @@ struct mok_state_variable {
* mirrored.
*/
UINT8 *state;
+
+ /*
+ * If this is non-NULL, this function will be called during the
+ * "import" phase to format the variable data. It'll get called
+ * twice, once as:
+ *
+ * sz = format(NULL, 0, ptr);
+ *
+ * a buffer of size sz will then be allocated, and it'll be called
+ * again to fill the buffer:
+ *
+ * format(buf, sz, ptr);
+ *
+ * Note that as an implementation detail data and data_size must be
+ * NULL and 0 respectively for this entry.
+ */
+ mok_variable_format_helper_t *format;
};
extern size_t n_mok_state_variables;
diff --git a/mok.c b/mok.c
index 2778cd05..67a798a3 100644
--- a/mok.c
+++ b/mok.c
@@ -985,8 +985,22 @@ EFI_STATUS import_one_mok_state(struct mok_state_variable *v,
}
}
+ if (v->format) {
+ v->data_size = v->format(NULL, 0, v);
+ if (v->data_size > 0) {
+ v->data = AllocatePool(v->data_size);
+ if (!v->data) {
+ perror(L"Could not allocate %lu bytes for %s\n",
+ v->data_size, v->name);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ v->format(v->data, v->data_size, v);
+ }
+
if (!v->data && !v->data_size &&
- (v->flags & MOK_VARIABLE_CONFIG_ONLY)) {
+ (v->flags & MOK_VARIABLE_CONFIG_ONLY) &&
+ !v->format) {
efi_status = get_variable_attr(v->name,
&v->data, &v->data_size,
*v->guid, &attrs);