Blame SOURCES/0062-Implement-lennysz-s-suggestions-for-MokListRT.patch

00e791
From 65be350308783a8ef537246c8ad0545b4e6ad069 Mon Sep 17 00:00:00 2001
00e791
From: Peter Jones <pjones@redhat.com>
00e791
Date: Sat, 25 Jul 2020 22:13:57 -0400
00e791
Subject: [PATCH 62/62] Implement lennysz's suggestions for MokListRT
00e791
00e791
Signed-off-by: Peter Jones <pjones@redhat.com>
00e791
---
00e791
 mok.c             | 726 ++++++++++++++++++++++++++++++++--------------
00e791
 shim.c            |   7 +-
00e791
 include/PeImage.h |   3 +-
00e791
 3 files changed, 515 insertions(+), 221 deletions(-)
00e791
00e791
diff --git a/mok.c b/mok.c
00e791
index 4e141fb21fc..3e6c7e43025 100644
00e791
--- a/mok.c
00e791
+++ b/mok.c
00e791
@@ -7,6 +7,8 @@
00e791
 
00e791
 #include <stdint.h>
00e791
 
00e791
+#include "hexdump.h"
00e791
+
00e791
 /*
00e791
  * Check if a variable exists
00e791
  */
00e791
@@ -25,6 +27,15 @@ static BOOLEAN check_var(CHAR16 *varname)
00e791
 	return FALSE;
00e791
 }
00e791
 
00e791
+#define SetVariable(name, guid, attrs, varsz, var) ({			\
00e791
+	EFI_STATUS efi_status_;						\
00e791
+	efi_status_ = gRT->SetVariable(name, guid, attrs, varsz, var);	\
00e791
+	dprint_(L"%a:%d:%a() SetVariable(\"%s\", ... varsz=0x%llx) = %r\n",\
00e791
+		 __FILE__, __LINE__, __func__,				\
00e791
+		name, varsz, efi_status_);				\
00e791
+	efi_status_;							\
00e791
+})
00e791
+
00e791
 /*
00e791
  * If the OS has set any of these variables we need to drop into MOK and
00e791
  * handle them appropriately
00e791
@@ -193,33 +204,296 @@ should_mirror_build_cert(struct mok_state_variable *v)
00e791
 
00e791
 static const uint8_t null_sha256[32] = { 0, };
00e791
 
00e791
+typedef UINTN SIZE_T;
00e791
+
00e791
+static EFI_STATUS
00e791
+get_max_var_sz(UINT32 attrs, SIZE_T *max_var_szp)
00e791
+{
00e791
+	EFI_STATUS efi_status;
00e791
+	uint64_t max_storage_sz = 0;
00e791
+	uint64_t remaining_sz = 0;
00e791
+	uint64_t max_var_sz = 0;
00e791
+
00e791
+	*max_var_szp = 0;
00e791
+	efi_status = gRT->QueryVariableInfo(attrs, &max_storage_sz,
00e791
+					    &remaining_sz, &max_var_sz);
00e791
+	if (EFI_ERROR(efi_status)) {
00e791
+		perror(L"Could not get variable storage info: %r\n", efi_status);
00e791
+		return efi_status;
00e791
+	}
00e791
+
00e791
+	/*
00e791
+	 * I just don't trust implementations to not be showing static data
00e791
+	 * for max_var_sz
00e791
+	 */
00e791
+	*max_var_szp = (max_var_sz < remaining_sz) ? max_var_sz : remaining_sz;
00e791
+	dprint("max_var_sz:%lx remaining_sz:%lx max_storage_sz:%lx\n",
00e791
+		max_var_sz, remaining_sz, max_storage_sz);
00e791
+	return efi_status;
00e791
+}
00e791
+
00e791
+/*
00e791
+ * If any entries fit in < maxsz, and nothing goes wrong, create a variable
00e791
+ * of the given name and guid with as many esd entries as possible in it,
00e791
+ * and updates *esdp with what would be the next entry (even if makes *esdp
00e791
+ * > esl+esl->SignatureListSize), and returns whatever SetVariable()
00e791
+ * returns
00e791
+ *
00e791
+ * If no entries fit (i.e. sizeof(esl) + esl->SignatureSize > maxsz),
00e791
+ * returns EFI_BUFFER_TOO_SMALL;
00e791
+ */
00e791
+static EFI_STATUS
00e791
+mirror_one_esl(CHAR16 *name, EFI_GUID *guid, UINT32 attrs,
00e791
+	       EFI_SIGNATURE_LIST *esl, EFI_SIGNATURE_DATA *esd,
00e791
+	       UINTN *newsz, SIZE_T maxsz)
00e791
+{
00e791
+	EFI_STATUS efi_status;
00e791
+	SIZE_T howmany, varsz = 0, esdsz;
00e791
+	UINT8 *var, *data;
00e791
+
00e791
+	howmany = min((maxsz - sizeof(*esl)) / esl->SignatureSize,
00e791
+		      (esl->SignatureListSize - sizeof(*esl)) / esl->SignatureSize);
00e791
+	if (howmany < 1) {
00e791
+		return EFI_BUFFER_TOO_SMALL;
00e791
+	}
00e791
+
00e791
+	/*
00e791
+	 * We always assume esl->SignatureHeaderSize is 0 (and so far,
00e791
+	 * that's true as per UEFI 2.8)
00e791
+	 */
00e791
+	esdsz = howmany * esl->SignatureSize;
00e791
+	data = (UINT8 *)esd;
00e791
+	dprint(L"Trying to add %lx signatures to \"%s\" of size %lx\n",
00e791
+	       howmany, name, esl->SignatureSize);
00e791
+
00e791
+	/*
00e791
+	 * Because of the semantics of variable_create_esl(), the first
00e791
+	 * owner guid from the data is not part of esdsz, or the data.
00e791
+	 *
00e791
+	 * Compensate here.
00e791
+	 */
00e791
+	efi_status = variable_create_esl(data + sizeof(EFI_GUID),
00e791
+					 esdsz - sizeof(EFI_GUID),
00e791
+					 &esl->SignatureType,
00e791
+					 &esd->SignatureOwner,
00e791
+					 &var, &varsz;;
00e791
+	if (EFI_ERROR(efi_status) || !var || !varsz) {
00e791
+		LogError(L"Couldn't allocate %lu bytes for mok variable \"%s\": %r\n",
00e791
+			 varsz, var, efi_status);
00e791
+		return efi_status;
00e791
+	}
00e791
+
00e791
+	dprint(L"new esl:\n");
00e791
+	dhexdumpat(var, varsz, 0);
00e791
+
00e791
+	efi_status = SetVariable(name, guid, attrs, varsz, var);
00e791
+	FreePool(var);
00e791
+	if (EFI_ERROR(efi_status)) {
00e791
+		LogError(L"Couldn't create mok variable \"%s\": %r\n",
00e791
+			 varsz, var, efi_status);
00e791
+		return efi_status;
00e791
+	}
00e791
+
00e791
+	*newsz = esdsz;
00e791
+
00e791
+	return efi_status;
00e791
+}
00e791
+
00e791
+static EFI_STATUS
00e791
+mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs,
00e791
+	      UINT8 *FullData, SIZE_T FullDataSize, BOOLEAN only_first)
00e791
+{
00e791
+	EFI_STATUS efi_status = EFI_SUCCESS;
00e791
+	SIZE_T max_var_sz;
00e791
+
00e791
+	if (only_first) {
00e791
+		efi_status = get_max_var_sz(attrs, &max_var_sz);
00e791
+		if (EFI_ERROR(efi_status)) {
00e791
+			LogError(L"Could not get maximum variable size: %r",
00e791
+				 efi_status);
00e791
+			return efi_status;
00e791
+		}
00e791
+
00e791
+		if (FullDataSize <= max_var_sz) {
00e791
+			efi_status = SetVariable(name, guid, attrs,
00e791
+						 FullDataSize, FullData);
00e791
+			return efi_status;
00e791
+		}
00e791
+	}
00e791
+
00e791
+	CHAR16 *namen;
00e791
+	CHAR8 *namen8;
00e791
+	UINTN namelen, namesz;
00e791
+
00e791
+	namelen = StrLen(name);
00e791
+	namesz = namelen * 2;
00e791
+	if (only_first) {
00e791
+		namen = name;
00e791
+		namen8 = name8;
00e791
+	} else {
00e791
+		namelen += 18;
00e791
+		namesz += 34;
00e791
+		namen = AllocateZeroPool(namesz);
00e791
+		if (!namen) {
00e791
+			LogError(L"Could not allocate %lu bytes", namesz);
00e791
+			return EFI_OUT_OF_RESOURCES;
00e791
+		}
00e791
+		namen8 = AllocateZeroPool(namelen);
00e791
+		if (!namen8) {
00e791
+			FreePool(namen);
00e791
+			LogError(L"Could not allocate %lu bytes", namelen);
00e791
+			return EFI_OUT_OF_RESOURCES;
00e791
+		}
00e791
+	}
00e791
+
00e791
+	UINTN pos, i;
00e791
+	const SIZE_T minsz = sizeof(EFI_SIGNATURE_LIST)
00e791
+			     + sizeof(EFI_SIGNATURE_DATA)
00e791
+			     + SHA1_DIGEST_SIZE;
00e791
+	BOOLEAN did_one = FALSE;
00e791
+
00e791
+	/*
00e791
+	 * Create any entries that can fit.
00e791
+	 */
00e791
+	if (!only_first) {
00e791
+		dprint(L"full data for \"%s\":\n", name);
00e791
+		dhexdumpat(FullData, FullDataSize, 0);
00e791
+	}
00e791
+	EFI_SIGNATURE_LIST *esl = NULL;
00e791
+	UINTN esl_end_pos = 0;
00e791
+	for (i = 0, pos = 0; FullDataSize - pos >= minsz && FullData; ) {
00e791
+		EFI_SIGNATURE_DATA *esd = NULL;
00e791
+
00e791
+		dprint(L"pos:0x%llx FullDataSize:0x%llx\n", pos, FullDataSize);
00e791
+		if (esl == NULL || pos >= esl_end_pos) {
00e791
+			UINT8 *nesl = FullData + pos;
00e791
+			dprint(L"esl:0x%llx->0x%llx\n", esl, nesl);
00e791
+			esl = (EFI_SIGNATURE_LIST *)nesl;
00e791
+			esl_end_pos = pos + esl->SignatureListSize;
00e791
+			dprint(L"pos:0x%llx->0x%llx\n", pos, pos + sizeof(*esl));
00e791
+			pos += sizeof(*esl);
00e791
+		}
00e791
+		esd = (EFI_SIGNATURE_DATA *)(FullData + pos);
00e791
+		if (pos >= FullDataSize)
00e791
+			break;
00e791
+		if (esl->SignatureListSize == 0 || esl->SignatureSize == 0)
00e791
+			break;
00e791
+
00e791
+		dprint(L"esl[%lu] 0x%llx = {sls=0x%lx, ss=0x%lx} esd:0x%llx\n",
00e791
+		       i, esl, esl->SignatureListSize, esl->SignatureSize, esd);
00e791
+
00e791
+		if (!only_first) {
00e791
+			SPrint(namen, namelen, L"%s%lu", name, i);
00e791
+			namen[namelen-1] = 0;
00e791
+			/* uggggh */
00e791
+			UINTN j;
00e791
+			for (j = 0; j < namelen; j++)
00e791
+				namen8[j] = (CHAR8)(namen[j] & 0xff);
00e791
+			namen8[namelen - 1] = 0;
00e791
+		}
00e791
+
00e791
+		/*
00e791
+		 * In case max_var_sz is computed dynamically, refresh the
00e791
+		 * value here.
00e791
+		 */
00e791
+		efi_status = get_max_var_sz(attrs, &max_var_sz);
00e791
+		if (EFI_ERROR(efi_status)) {
00e791
+			LogError(L"Could not get maximum variable size: %r",
00e791
+				 efi_status);
00e791
+			if (!only_first) {
00e791
+				FreePool(namen);
00e791
+				FreePool(namen8);
00e791
+			}
00e791
+			return efi_status;
00e791
+		}
00e791
+
00e791
+		SIZE_T howmany;
00e791
+		UINTN adj = 0;
00e791
+		howmany = min((max_var_sz - sizeof(*esl)) / esl->SignatureSize,
00e791
+			      (esl->SignatureListSize - sizeof(*esl)) / esl->SignatureSize);
00e791
+		if (!only_first && i == 0 && howmany >= 1) {
00e791
+			adj = howmany * esl->SignatureSize;
00e791
+			dprint(L"pos:0x%llx->0x%llx\n", pos, pos + adj);
00e791
+			pos += adj;
00e791
+			i++;
00e791
+			continue;
00e791
+
00e791
+		}
00e791
+
00e791
+		efi_status = mirror_one_esl(namen, guid, attrs,
00e791
+					    esl, esd, &adj, max_var_sz);
00e791
+		dprint(L"esd:0x%llx adj:0x%llx\n", esd, adj);
00e791
+		if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) {
00e791
+			LogError(L"Could not mirror mok variable \"%s\": %r\n",
00e791
+				 namen, efi_status);
00e791
+			break;
00e791
+		}
00e791
+
00e791
+		if (!EFI_ERROR(efi_status)) {
00e791
+			did_one = TRUE;
00e791
+			if (only_first)
00e791
+				break;
00e791
+			dprint(L"pos:0x%llx->0x%llx\n", pos, pos + adj);
00e791
+			pos += adj;
00e791
+			i++;
00e791
+		}
00e791
+	}
00e791
+
00e791
+	if (only_first && !did_one) {
00e791
+		/*
00e791
+		 * In this case we're going to try to create a
00e791
+		 * dummy variable so that there's one there.  It
00e791
+		 * may or may not work, because on some firmware
00e791
+		 * builds when the SetVariable call above fails it
00e791
+		 * does actually set the variable(!), so aside from
00e791
+		 * not using the allocation if it doesn't work, we
00e791
+		 * don't care about failures here.
00e791
+		 */
00e791
+		UINT8 *var;
00e791
+		UINTN varsz;
00e791
+
00e791
+		efi_status = variable_create_esl(
00e791
+				null_sha256, sizeof(null_sha256),
00e791
+				&EFI_CERT_SHA256_GUID, &SHIM_LOCK_GUID,
00e791
+				&var, &varsz;;
00e791
+		/*
00e791
+		 * from here we don't really care if it works or
00e791
+		 * doesn't.
00e791
+		 */
00e791
+		if (!EFI_ERROR(efi_status) && var && varsz) {
00e791
+			SetVariable(name, guid,
00e791
+				    EFI_VARIABLE_BOOTSERVICE_ACCESS
00e791
+				    | EFI_VARIABLE_RUNTIME_ACCESS,
00e791
+				    varsz, var);
00e791
+			FreePool(var);
00e791
+		}
00e791
+		efi_status = EFI_INVALID_PARAMETER;
00e791
+	} else if (EFI_ERROR(efi_status)) {
00e791
+		perror(L"Failed to set %s: %r\n", name, efi_status);
00e791
+	}
00e791
+	return efi_status;
00e791
+}
00e791
+
00e791
+
00e791
 static EFI_STATUS nonnull(1)
00e791
-mirror_one_mok_variable(struct mok_state_variable *v)
00e791
+mirror_one_mok_variable(struct mok_state_variable *v,
00e791
+			BOOLEAN only_first)
00e791
 {
00e791
 	EFI_STATUS efi_status = EFI_SUCCESS;
00e791
 	uint8_t *FullData = NULL;
00e791
 	size_t FullDataSize = 0;
00e791
 	vendor_addend_category_t addend_category = VENDOR_ADDEND_NONE;
00e791
 	uint8_t *p = NULL;
00e791
-
00e791
+	uint32_t attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS |
00e791
+			 EFI_VARIABLE_RUNTIME_ACCESS;
00e791
+	BOOLEAN measure = v->flags & MOK_VARIABLE_MEASURE;
00e791
+	BOOLEAN log = v->flags & MOK_VARIABLE_LOG;
00e791
 	size_t build_cert_esl_sz = 0, addend_esl_sz = 0;
00e791
+	bool reuse = FALSE;
00e791
 
00e791
 	if (v->categorize_addend)
00e791
 		addend_category = v->categorize_addend(v);
00e791
 
00e791
-	/*
00e791
-	 * we're always mirroring the original data, whether this is an efi
00e791
-	 * security database or not
00e791
-	 */
00e791
-	dprint(L"v->name:\"%s\" v->rtname:\"%s\"\n", v->name, v->rtname);
00e791
-	dprint(L"v->data_size:%lu v->data:0x%08llx\n", v->data_size, v->data);
00e791
-	dprint(L"FullDataSize:%lu FullData:0x%08llx\n", FullDataSize, FullData);
00e791
-	if (v->data_size) {
00e791
-		FullDataSize = v->data_size;
00e791
-		dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
00e791
-		       FullDataSize, FullData);
00e791
-	}
00e791
-
00e791
 	/*
00e791
 	 * if it is, there's more data
00e791
 	 */
00e791
@@ -227,7 +501,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 
00e791
 		/*
00e791
 		 * We're mirroring (into) an efi security database, aka an
00e791
-		 * array of efi_signature_list_t.  Its layout goes like:
00e791
+		 * array of EFI_SIGNATURE_LIST.  Its layout goes like:
00e791
 		 *
00e791
 		 *   existing_variable_data
00e791
 		 *   existing_variable_data_size
00e791
@@ -251,30 +525,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 		 */
00e791
 
00e791
 		/*
00e791
-		 * first bit is existing data, but we added that above
00e791
-		 */
00e791
-
00e791
-		/*
00e791
-		 * then the build cert if it's there
00e791
-		 */
00e791
-		if (should_mirror_build_cert(v)) {
00e791
-			efi_status = fill_esl(*v->build_cert,
00e791
-					      *v->build_cert_size,
00e791
-					      &EFI_CERT_TYPE_X509_GUID,
00e791
-					      &SHIM_LOCK_GUID,
00e791
-					      NULL, &build_cert_esl_sz);
00e791
-			if (efi_status != EFI_BUFFER_TOO_SMALL) {
00e791
-				perror(L"Could not add built-in cert to %s: %r\n",
00e791
-				       v->name, efi_status);
00e791
-				return efi_status;
00e791
-			}
00e791
-			FullDataSize += build_cert_esl_sz;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
00e791
-			       FullDataSize, FullData);
00e791
-		}
00e791
-
00e791
-		/*
00e791
-		 * then the addend data
00e791
+		 * *first* vendor_db or vendor_cert
00e791
 		 */
00e791
 		switch (addend_category) {
00e791
 		case VENDOR_ADDEND_DB:
00e791
@@ -282,7 +533,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 			 * if it's an ESL already, we use it wholesale
00e791
 			 */
00e791
 			FullDataSize += *v->addend_size;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx\n",
00e791
 			       FullDataSize, FullData);
00e791
 			break;
00e791
 		case VENDOR_ADDEND_X509:
00e791
@@ -296,17 +547,51 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 				return efi_status;
00e791
 			}
00e791
 			FullDataSize += addend_esl_sz;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx\n",
00e791
 				      FullDataSize, FullData);
00e791
 			break;
00e791
 		default:
00e791
 		case VENDOR_ADDEND_NONE:
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx\n",
00e791
 				      FullDataSize, FullData);
00e791
 			break;
00e791
 		}
00e791
+
00e791
+		/*
00e791
+		 * then the build cert if it's there
00e791
+		 */
00e791
+		if (should_mirror_build_cert(v)) {
00e791
+			efi_status = fill_esl(*v->build_cert,
00e791
+					      *v->build_cert_size,
00e791
+					      &EFI_CERT_TYPE_X509_GUID,
00e791
+					      &SHIM_LOCK_GUID,
00e791
+					      NULL, &build_cert_esl_sz);
00e791
+			if (efi_status != EFI_BUFFER_TOO_SMALL) {
00e791
+				perror(L"Could not add built-in cert to %s: %r\n",
00e791
+				       v->name, efi_status);
00e791
+				return efi_status;
00e791
+			}
00e791
+			FullDataSize += build_cert_esl_sz;
00e791
+			dprint(L"FullDataSize:0x%lx FullData:0x%llx\n",
00e791
+			       FullDataSize, FullData);
00e791
+		}
00e791
+
00e791
 	}
00e791
 
00e791
+	/*
00e791
+	 * we're always mirroring the original data, whether this is an efi
00e791
+	 * security database or not
00e791
+	 */
00e791
+	dprint(L"v->name:\"%s\" v->rtname:\"%s\"\n", v->name, v->rtname);
00e791
+	dprint(L"v->data_size:%lu v->data:0x%llx\n", v->data_size, v->data);
00e791
+	dprint(L"FullDataSize:%lu FullData:0x%llx\n", FullDataSize, FullData);
00e791
+	if (v->data_size) {
00e791
+		FullDataSize += v->data_size;
00e791
+		dprint(L"FullDataSize:%lu FullData:0x%llx\n",
00e791
+		       FullDataSize, FullData);
00e791
+	}
00e791
+	if (v->data_size == FullDataSize)
00e791
+		reuse = TRUE;
00e791
 
00e791
 	/*
00e791
 	 * Now we have the full size
00e791
@@ -316,38 +601,33 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 		 * allocate the buffer, or use the old one if it's just the
00e791
 		 * existing data.
00e791
 		 */
00e791
-		if (FullDataSize != v->data_size) {
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx allocating FullData\n",
00e791
+		if (FullDataSize == v->data_size) {
00e791
+			FullData = v->data;
00e791
+			FullDataSize = v->data_size;
00e791
+			p = FullData + FullDataSize;
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
+			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
+			v->data = NULL;
00e791
+			v->data_size = 0;
00e791
+		} else {
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx allocating FullData\n",
00e791
 			       FullDataSize, FullData);
00e791
-			FullData = AllocatePool(FullDataSize);
00e791
+			/*
00e791
+			 * make sure we've got some zeroes at the end, just
00e791
+			 * in case.
00e791
+			 */
00e791
+			UINTN allocsz = FullDataSize + sizeof(EFI_SIGNATURE_LIST);
00e791
+			allocsz = ALIGN_VALUE(allocsz, 4096);
00e791
+			FullData = AllocateZeroPool(FullDataSize);
00e791
 			if (!FullData) {
00e791
-				FreePool(v->data);
00e791
-				v->data = NULL;
00e791
-				v->data_size = 0;
00e791
 				perror(L"Failed to allocate %lu bytes for %s\n",
00e791
 				       FullDataSize, v->name);
00e791
 				return EFI_OUT_OF_RESOURCES;
00e791
 			}
00e791
 			p = FullData;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
-			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
-			if (v->data && v->data_size) {
00e791
-				CopyMem(p, v->data, v->data_size);
00e791
-				p += v->data_size;
00e791
-			}
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
-			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
-		} else {
00e791
-			FullData = v->data;
00e791
-			FullDataSize = v->data_size;
00e791
-			p = FullData + FullDataSize;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
-			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
-			v->data = NULL;
00e791
-			v->data_size = 0;
00e791
 		}
00e791
 	}
00e791
-	dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
+	dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
 	       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
 
00e791
 	/*
00e791
@@ -355,35 +635,13 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 	 */
00e791
 	if (v->flags & MOK_MIRROR_KEYDB) {
00e791
 		/*
00e791
-		 * first bit is existing data, but again, we added that above
00e791
+		 * first vendor_cert or vendor_db
00e791
 		 */
00e791
-
00e791
-		/*
00e791
-		 * second is the build cert
00e791
-		 */
00e791
-		dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
-		       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
-		if (should_mirror_build_cert(v)) {
00e791
-			efi_status = fill_esl(*v->build_cert,
00e791
-					      *v->build_cert_size,
00e791
-					      &EFI_CERT_TYPE_X509_GUID,
00e791
-					      &SHIM_LOCK_GUID,
00e791
-					      p, &build_cert_esl_sz);
00e791
-			if (EFI_ERROR(efi_status)) {
00e791
-				perror(L"Could not add built-in cert to %s: %r\n",
00e791
-				       v->name, efi_status);
00e791
-				return efi_status;
00e791
-			}
00e791
-			p += build_cert_esl_sz;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
-			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
-		}
00e791
-
00e791
 		switch (addend_category) {
00e791
 		case VENDOR_ADDEND_DB:
00e791
 			CopyMem(p, *v->addend, *v->addend_size);
00e791
 			p += *v->addend_size;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
 			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
 			break;
00e791
 		case VENDOR_ADDEND_X509:
00e791
@@ -397,16 +655,53 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 				return efi_status;
00e791
 			}
00e791
 			p += addend_esl_sz;
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
 			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
 			break;
00e791
 		default:
00e791
 		case VENDOR_ADDEND_NONE:
00e791
-			dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
 			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
 			break;
00e791
 		}
00e791
+
00e791
+		/*
00e791
+		 * then is the build cert
00e791
+		 */
00e791
+		dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
+		       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
+		if (should_mirror_build_cert(v)) {
00e791
+			efi_status = fill_esl(*v->build_cert,
00e791
+					      *v->build_cert_size,
00e791
+					      &EFI_CERT_TYPE_X509_GUID,
00e791
+					      &SHIM_LOCK_GUID,
00e791
+					      p, &build_cert_esl_sz);
00e791
+			if (EFI_ERROR(efi_status)) {
00e791
+				perror(L"Could not add built-in cert to %s: %r\n",
00e791
+				       v->name, efi_status);
00e791
+				return efi_status;
00e791
+			}
00e791
+			p += build_cert_esl_sz;
00e791
+			dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
+			       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
+		}
00e791
 	}
00e791
+
00e791
+	/*
00e791
+	 * last bit is existing data, unless it's the only thing,
00e791
+	 * in which case it's already there.
00e791
+	 */
00e791
+	if (!reuse) {
00e791
+		dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
+		       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
+		if (v->data && v->data_size) {
00e791
+			CopyMem(p, v->data, v->data_size);
00e791
+			p += v->data_size;
00e791
+		}
00e791
+		dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
+		       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
+	}
00e791
+
00e791
 	/*
00e791
 	 * We always want to create our key databases, so in this case we
00e791
 	 * need a dummy entry
00e791
@@ -422,68 +717,55 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
 			return efi_status;
00e791
 		}
00e791
 		p = FullData + FullDataSize;
00e791
-		dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
00e791
+		dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
 		       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
 	}
00e791
 
00e791
-	dprint(L"FullDataSize:%lu FullData:0x%016llx p:0x%016llx pos:%lld\n",
00e791
+	dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
00e791
 	       FullDataSize, FullData, p, p-(uintptr_t)FullData);
00e791
-	if (FullDataSize) {
00e791
-		uint32_t attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS |
00e791
-				 EFI_VARIABLE_RUNTIME_ACCESS;
00e791
-		uint64_t max_storage_sz = 0;
00e791
-		uint64_t remaining_sz = 0;
00e791
-		uint64_t max_var_sz = 0;
00e791
-		UINT8 *tmp = NULL;
00e791
-		UINTN tmpsz = 0;
00e791
-
00e791
-		efi_status = gRT->QueryVariableInfo(attrs, &max_storage_sz,
00e791
-						    &remaining_sz, &max_var_sz);
00e791
-		if (EFI_ERROR(efi_status)) {
00e791
-			perror(L"Could not get variable storage info: %r\n", efi_status);
00e791
-			return efi_status;
00e791
-		}
00e791
-		dprint(L"calling SetVariable(\"%s\", 0x%016llx, 0x%08lx, %lu, 0x%016llx)\n",
00e791
-		       v->rtname, v->guid,
00e791
-		       EFI_VARIABLE_BOOTSERVICE_ACCESS
00e791
-		       | EFI_VARIABLE_RUNTIME_ACCESS,
00e791
-		       FullDataSize, FullData);
00e791
-		efi_status = gRT->SetVariable(v->rtname, v->guid,
00e791
-					      EFI_VARIABLE_BOOTSERVICE_ACCESS
00e791
-					      | EFI_VARIABLE_RUNTIME_ACCESS,
00e791
-					      FullDataSize, FullData);
00e791
-		if (efi_status == EFI_INVALID_PARAMETER && max_var_sz < FullDataSize) {
00e791
+	if (FullDataSize && v->flags & MOK_MIRROR_KEYDB) {
00e791
+		dprint(L"calling mirror_mok_db(\"%s\",  datasz=%lu)\n",
00e791
+		       v->rtname, FullDataSize);
00e791
+		efi_status = mirror_mok_db(v->rtname, (CHAR8 *)v->rtname8, v->guid,
00e791
+					   attrs, FullData, FullDataSize,
00e791
+					   only_first);
00e791
+		dprint(L"mirror_mok_db(\"%s\",  datasz=%lu) returned %r\n",
00e791
+		       v->rtname, FullDataSize, efi_status);
00e791
+	} else if (FullDataSize && only_first) {
00e791
+		efi_status = SetVariable(v->rtname, v->guid, attrs,
00e791
+					 FullDataSize, FullData);
00e791
+	}
00e791
+	if (FullDataSize && only_first) {
00e791
+		if (measure) {
00e791
 			/*
00e791
-			 * In this case we're going to try to create a
00e791
-			 * dummy variable so that there's one there.  It
00e791
-			 * may or may not work, because on some firmware
00e791
-			 * builds when the SetVariable call above fails it
00e791
-			 * does actually set the variable(!), so aside from
00e791
-			 * not using the allocation if it doesn't work, we
00e791
-			 * don't care about failures here.
00e791
+			 * Measure this into PCR 7 in the Microsoft format
00e791
 			 */
00e791
-			console_print(L"WARNING: Maximum volatile variable size is %lu.\n", max_var_sz);
00e791
-			console_print(L"WARNING: Cannot set %s (%lu bytes)\n", v->rtname, FullDataSize);
00e791
-			perror(L"Failed to set %s: %r\n", v->rtname, efi_status);
00e791
-			efi_status = variable_create_esl(
00e791
-					null_sha256, sizeof(null_sha256),
00e791
-					&EFI_CERT_SHA256_GUID, &SHIM_LOCK_GUID,
00e791
-					&tmp, &tmpsz);
00e791
+			efi_status = tpm_measure_variable(v->name, *v->guid,
00e791
+							  FullDataSize, FullData);
00e791
+			if (EFI_ERROR(efi_status)) {
00e791
+				dprint(L"tpm_measure_variable(\"%s\",%lu,0x%llx)->%r\n",
00e791
+				       v->name, FullDataSize, FullData, efi_status);
00e791
+				return efi_status;
00e791
+			}
00e791
+		}
00e791
+
00e791
+		if (log) {
00e791
 			/*
00e791
-			 * from here we don't really care if it works or
00e791
-			 * doens't.
00e791
+			 * Log this variable into whichever PCR the table
00e791
+			 * says.
00e791
 			 */
00e791
-			if (!EFI_ERROR(efi_status) && tmp && tmpsz) {
00e791
-				gRT->SetVariable(v->rtname, v->guid,
00e791
-						 EFI_VARIABLE_BOOTSERVICE_ACCESS
00e791
-						 | EFI_VARIABLE_RUNTIME_ACCESS,
00e791
-						 tmpsz, tmp);
00e791
-				FreePool(tmp);
00e791
+			EFI_PHYSICAL_ADDRESS datap =
00e791
+					(EFI_PHYSICAL_ADDRESS)(UINTN)FullData,
00e791
+			efi_status = tpm_log_event(datap, FullDataSize,
00e791
+						   v->pcr, (CHAR8 *)v->name8);
00e791
+			if (EFI_ERROR(efi_status)) {
00e791
+				dprint(L"tpm_log_event(0x%llx, %lu, %lu, \"%s\")->%r\n",
00e791
+				       FullData, FullDataSize, v->pcr, v->name,
00e791
+				       efi_status);
00e791
+				return efi_status;
00e791
 			}
00e791
-			efi_status = EFI_INVALID_PARAMETER;
00e791
-		} else if (EFI_ERROR(efi_status)) {
00e791
-			perror(L"Failed to set %s: %r\n", v->rtname, efi_status);
00e791
 		}
00e791
+
00e791
 	}
00e791
 	if (v->data && v->data_size && v->data != FullData) {
00e791
 		FreePool(v->data);
00e791
@@ -501,19 +783,20 @@ mirror_one_mok_variable(struct mok_state_variable *v)
00e791
  * EFI_SECURITY_VIOLATION status at the same time.
00e791
  */
00e791
 static EFI_STATUS nonnull(1)
00e791
-maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
00e791
+maybe_mirror_one_mok_variable(struct mok_state_variable *v,
00e791
+			      EFI_STATUS ret, BOOLEAN only_first)
00e791
 {
00e791
 	EFI_STATUS efi_status;
00e791
 	BOOLEAN present = FALSE;
00e791
 
00e791
 	if (v->rtname) {
00e791
-		if (v->flags & MOK_MIRROR_DELETE_FIRST) {
00e791
+		if (!only_first && (v->flags & MOK_MIRROR_DELETE_FIRST)) {
00e791
 			dprint(L"deleting \"%s\"\n", v->rtname);
00e791
 			efi_status = LibDeleteVariable(v->rtname, v->guid);
00e791
 			dprint(L"LibDeleteVariable(\"%s\",...) => %r\n", v->rtname, efi_status);
00e791
 		}
00e791
 
00e791
-		efi_status = mirror_one_mok_variable(v);
00e791
+		efi_status = mirror_one_mok_variable(v, only_first);
00e791
 		if (EFI_ERROR(efi_status)) {
00e791
 			if (ret != EFI_SECURITY_VIOLATION)
00e791
 				ret = efi_status;
00e791
@@ -530,34 +813,6 @@ maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
00e791
 		*v->state = v->data[0];
00e791
 	}
00e791
 
00e791
-	if (v->flags & MOK_VARIABLE_MEASURE) {
00e791
-		/*
00e791
-		 * Measure this into PCR 7 in the Microsoft format
00e791
-		 */
00e791
-		efi_status = tpm_measure_variable(v->name, *v->guid,
00e791
-						  v->data_size,
00e791
-						  v->data);
00e791
-		if (EFI_ERROR(efi_status)) {
00e791
-			if (ret != EFI_SECURITY_VIOLATION)
00e791
-				ret = efi_status;
00e791
-		}
00e791
-	}
00e791
-
00e791
-	if (v->flags & MOK_VARIABLE_LOG) {
00e791
-		/*
00e791
-		 * Log this variable into whichever PCR the table
00e791
-		 * says.
00e791
-		 */
00e791
-		EFI_PHYSICAL_ADDRESS datap =
00e791
-				(EFI_PHYSICAL_ADDRESS)(UINTN)v->data,
00e791
-		efi_status = tpm_log_event(datap, v->data_size,
00e791
-					   v->pcr, (CHAR8 *)v->name8);
00e791
-		if (EFI_ERROR(efi_status)) {
00e791
-			if (ret != EFI_SECURITY_VIOLATION)
00e791
-				ret = efi_status;
00e791
-		}
00e791
-	}
00e791
-
00e791
 	return ret;
00e791
 }
00e791
 
00e791
@@ -567,6 +822,66 @@ struct mok_variable_config_entry {
00e791
 	UINT8 data[];
00e791
 };
00e791
 
00e791
+EFI_STATUS import_one_mok_state(struct mok_state_variable *v,
00e791
+				BOOLEAN only_first)
00e791
+{
00e791
+	EFI_STATUS ret = EFI_SUCCESS;
00e791
+	EFI_STATUS efi_status;
00e791
+
00e791
+	user_insecure_mode = 0;
00e791
+	ignore_db = 0;
00e791
+
00e791
+	UINT32 attrs = 0;
00e791
+	BOOLEAN delete = FALSE;
00e791
+
00e791
+	dprint(L"importing mok state for \"%s\"\n", v->name);
00e791
+
00e791
+	efi_status = get_variable_attr(v->name,
00e791
+				       &v->data, &v->data_size,
00e791
+				       *v->guid, &attrs);
00e791
+	if (efi_status == EFI_NOT_FOUND) {
00e791
+		v->data = NULL;
00e791
+		v->data_size = 0;
00e791
+	} else if (EFI_ERROR(efi_status)) {
00e791
+		perror(L"Could not verify %s: %r\n", v->name,
00e791
+		       efi_status);
00e791
+		delete = TRUE;
00e791
+	} else {
00e791
+		if (!(attrs & v->yes_attr)) {
00e791
+			perror(L"Variable %s is missing attributes:\n",
00e791
+			       v->name);
00e791
+			perror(L"  0x%08x should have 0x%08x set.\n",
00e791
+			       attrs, v->yes_attr);
00e791
+			delete = TRUE;
00e791
+		}
00e791
+		if (attrs & v->no_attr) {
00e791
+			perror(L"Variable %s has incorrect attribute:\n",
00e791
+			       v->name);
00e791
+			perror(L"  0x%08x should not have 0x%08x set.\n",
00e791
+			       attrs, v->no_attr);
00e791
+			delete = TRUE;
00e791
+		}
00e791
+	}
00e791
+	if (delete == TRUE) {
00e791
+		perror(L"Deleting bad variable %s\n", v->name);
00e791
+		efi_status = LibDeleteVariable(v->name, v->guid);
00e791
+		if (EFI_ERROR(efi_status)) {
00e791
+			perror(L"Failed to erase %s\n", v->name);
00e791
+			ret = EFI_SECURITY_VIOLATION;
00e791
+		}
00e791
+		FreePool(v->data);
00e791
+		v->data = NULL;
00e791
+		v->data_size = 0;
00e791
+	}
00e791
+
00e791
+	dprint(L"maybe mirroring \"%s\".  original data:\n", v->name);
00e791
+	dhexdumpat(v->data, v->data_size, 0);
00e791
+
00e791
+	ret = maybe_mirror_one_mok_variable(v, ret, only_first);
00e791
+	dprint(L"returning %r\n", ret);
00e791
+	return ret;
00e791
+}
00e791
+
00e791
 /*
00e791
  * Verify our non-volatile MoK state.  This checks the variables above
00e791
  * accessable and have valid attributes.  If they don't, it removes
00e791
@@ -594,58 +909,22 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
00e791
 	size_t npages = 0;
00e791
 	struct mok_variable_config_entry config_template;
00e791
 
00e791
-	dprint(L"importing mok state\n");
00e791
+	dprint(L"importing minimal mok state variables\n");
00e791
 	for (i = 0; mok_state_variables[i].name != NULL; i++) {
00e791
 		struct mok_state_variable *v = &mok_state_variables[i];
00e791
-		UINT32 attrs = 0;
00e791
-		BOOLEAN delete = FALSE;
00e791
 
00e791
-		efi_status = get_variable_attr(v->name,
00e791
-					       &v->data, &v->data_size,
00e791
-					       *v->guid, &attrs);
00e791
-		dprint(L"maybe mirroring %s\n", v->name);
00e791
-		if (efi_status == EFI_NOT_FOUND) {
00e791
-			v->data = NULL;
00e791
-			v->data_size = 0;
00e791
-		} else if (EFI_ERROR(efi_status)) {
00e791
-			perror(L"Could not verify %s: %r\n", v->name,
00e791
-			       efi_status);
00e791
+		efi_status = import_one_mok_state(v, TRUE);
00e791
+		if (EFI_ERROR(efi_status)) {
00e791
+			dprint(L"import_one_mok_state(ih, \"%s\", TRUE): %r\n",
00e791
+			       v->rtname);
00e791
 			/*
00e791
 			 * don't clobber EFI_SECURITY_VIOLATION from some
00e791
 			 * other variable in the list.
00e791
 			 */
00e791
 			if (ret != EFI_SECURITY_VIOLATION)
00e791
 				ret = efi_status;
00e791
-			delete = TRUE;
00e791
-		} else {
00e791
-			if (!(attrs & v->yes_attr)) {
00e791
-				perror(L"Variable %s is missing attributes:\n",
00e791
-				       v->name);
00e791
-				perror(L"  0x%08x should have 0x%08x set.\n",
00e791
-				       attrs, v->yes_attr);
00e791
-				delete = TRUE;
00e791
-			}
00e791
-			if (attrs & v->no_attr) {
00e791
-				perror(L"Variable %s has incorrect attribute:\n",
00e791
-				       v->name);
00e791
-				perror(L"  0x%08x should not have 0x%08x set.\n",
00e791
-				       attrs, v->no_attr);
00e791
-				delete = TRUE;
00e791
-			}
00e791
-		}
00e791
-		if (delete == TRUE) {
00e791
-			perror(L"Deleting bad variable %s\n", v->name);
00e791
-			efi_status = LibDeleteVariable(v->name, v->guid);
00e791
-			if (EFI_ERROR(efi_status)) {
00e791
-				perror(L"Failed to erase %s\n", v->name);
00e791
-				ret = EFI_SECURITY_VIOLATION;
00e791
-			}
00e791
-			FreePool(v->data);
00e791
-			v->data = NULL;
00e791
-			v->data_size = 0;
00e791
 		}
00e791
 
00e791
-		ret = maybe_mirror_one_mok_variable(v, ret);
00e791
 		if (v->data && v->data_size) {
00e791
 			config_sz += v->data_size;
00e791
 			config_sz += sizeof(config_template);
00e791
@@ -669,8 +948,6 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
00e791
 		if (EFI_ERROR(efi_status) || !config_table) {
00e791
 			console_print(L"Allocating %lu pages for mok config table failed: %r\n",
00e791
 				      npages, efi_status);
00e791
-			if (ret != EFI_SECURITY_VIOLATION)
00e791
-				ret = efi_status;
00e791
 			config_table = NULL;
00e791
 		} else {
00e791
 			ZeroMem(config_table, npages << EFI_PAGE_SHIFT);
00e791
@@ -703,6 +980,16 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
00e791
 		}
00e791
 	}
00e791
 
00e791
+	/*
00e791
+	 * This is really just to make it easy for userland.
00e791
+	 */
00e791
+	dprint(L"importing full mok state variables\n");
00e791
+	for (i = 0; mok_state_variables[i].name != NULL; i++) {
00e791
+		struct mok_state_variable *v = &mok_state_variables[i];
00e791
+
00e791
+		import_one_mok_state(v, FALSE);
00e791
+	}
00e791
+
00e791
 	/*
00e791
 	 * Enter MokManager if necessary.  Any actual *changes* here will
00e791
 	 * cause MokManager to demand a machine reboot, so this is safe to
00e791
@@ -712,6 +999,9 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
00e791
 	efi_status = check_mok_request(image_handle);
00e791
 	dprint(L"mok returned %r\n", efi_status);
00e791
 	if (EFI_ERROR(efi_status)) {
00e791
+		/*
00e791
+		 * don't clobber EFI_SECURITY_VIOLATION
00e791
+		 */
00e791
 		if (ret != EFI_SECURITY_VIOLATION)
00e791
 			ret = efi_status;
00e791
 		return ret;
00e791
diff --git a/shim.c b/shim.c
00e791
index 9248642bd57..1a4d7bb9ded 100644
00e791
--- a/shim.c
00e791
+++ b/shim.c
00e791
@@ -1445,7 +1445,10 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
00e791
 					   sha256hash, sha1hash);
00e791
 
00e791
 		if (EFI_ERROR(efi_status)) {
00e791
-			console_error(L"Verification failed", efi_status);
00e791
+			if (verbose)
00e791
+				console_print(L"Verification failed: %r\n", efi_status);
00e791
+			else
00e791
+				console_error(L"Verification failed", efi_status);
00e791
 			return efi_status;
00e791
 		} else {
00e791
 			if (verbose)
00e791
@@ -2648,7 +2651,6 @@ shim_init(void)
00e791
 {
00e791
 	EFI_STATUS efi_status;
00e791
 
00e791
-	setup_verbosity();
00e791
 	dprint(L"%a", shim_version);
00e791
 
00e791
 	/* Set the second stage loader */
00e791
@@ -2797,6 +2799,7 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
00e791
 	 * Ensure that gnu-efi functions are available
00e791
 	 */
00e791
 	InitializeLib(image_handle, systab);
00e791
+	setup_verbosity();
00e791
 
00e791
 	dprint(L"vendor_authorized:0x%08lx vendor_authorized_size:%lu\n",
00e791
 		      __FILE__, __LINE__, __func__, vendor_authorized, vendor_authorized_size);
00e791
diff --git a/include/PeImage.h b/include/PeImage.h
00e791
index a606e8b2a9f..209b96fb8ff 100644
00e791
--- a/include/PeImage.h
00e791
+++ b/include/PeImage.h
00e791
@@ -768,7 +768,8 @@ typedef struct {
00e791
 	UINT8           CertData[1];
00e791
 } WIN_CERTIFICATE_EFI_PKCS;
00e791
 
00e791
-#define SHA256_DIGEST_SIZE  32
00e791
+#define SHA1_DIGEST_SIZE	20
00e791
+#define SHA256_DIGEST_SIZE	32
00e791
 #define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
00e791
 
00e791
 typedef struct {
00e791
-- 
00e791
2.26.2
00e791