diff --git a/.shim.metadata b/.shim.metadata
index 7f2a942..a6c53d4 100644
--- a/.shim.metadata
+++ b/.shim.metadata
@@ -1,7 +1,3 @@
-d193e3e3cf19148c8ac867de8e1ae39f9b66afec SOURCES/DB.auth
 7686b4eb198c0efb70dae703dc8d71885d462ab0 SOURCES/0.7.tar.gz
-b8452a8a6a929d4938391d106e810fd517430bbc SOURCES/PK.auth
-66895070de7ebfc2d49324ad24ee53debcc540db SOURCES/securebootca.cer
-4c954f56aa4273f24bb45c6e8b0084a67999c251 SOURCES/KEK.auth
-f4e556118ee4f4dec187db15dc8767b92e99461d SOURCES/mokutil-0.2.0.tar.bz2
-531f3d9eb430649609695efd3d97ff3f6b8b9326 SOURCES/0.3.tar.gz
+cf9230e69000076727e5b784ec871d22716dc5da SOURCES/securebootca.cer
+ef680b489eb689a390ed2e1470eaaf2682ad5072 SOURCES/mokutil-0.2.0.tar.gz
diff --git a/SOURCES/0001-Actually-reflect-the-upstream-commit-this-patchset-g.patch b/SOURCES/0001-Actually-reflect-the-upstream-commit-this-patchset-g.patch
new file mode 100644
index 0000000..807a104
--- /dev/null
+++ b/SOURCES/0001-Actually-reflect-the-upstream-commit-this-patchset-g.patch
@@ -0,0 +1,37 @@
+From af3293e11528d991090b34a564c4d2e5de416e79 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Tue, 18 Feb 2014 15:19:07 -0500
+Subject: [PATCH] Actually reflect the upstream commit this patchset gets us
+ to.
+
+Signed-off-by: Peter Jones <shim-owner@fedoraproject.org>
+---
+ Makefile | 2 +-
+ commit   | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+ create mode 100644 commit
+
+diff --git a/Makefile b/Makefile
+index e65d28d..c3ce4be 100644
+--- a/Makefile
++++ b/Makefile
+@@ -67,7 +67,7 @@ shim_cert.h: shim.cer
+ version.c : version.c.in
+ 	sed	-e "s,@@VERSION@@,$(VERSION)," \
+ 		-e "s,@@UNAME@@,$(shell uname -a)," \
+-		-e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \
++		-e "s,@@COMMIT@@,$(shell if [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \
+ 		< version.c.in > version.c
+ 
+ certdb/secmod.db: shim.crt
+diff --git a/commit b/commit
+new file mode 100644
+index 0000000..c52fa12
+--- /dev/null
++++ b/commit
+@@ -0,0 +1 @@
++06495f692fa748a553ffbde8bfae2974d8c791c0
+\ No newline at end of file
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0001-Add-a-preliminary-test-plan.patch b/SOURCES/0001-Add-a-preliminary-test-plan.patch
new file mode 100644
index 0000000..89a7995
--- /dev/null
+++ b/SOURCES/0001-Add-a-preliminary-test-plan.patch
@@ -0,0 +1,104 @@
+From ac356a0e7723662d0a83ca3991088ce346495772 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 14 Feb 2014 14:06:45 -0500
+Subject: [PATCH 1/3] Add a preliminary test plan.
+
+Because you know you wanted a test plan.  You feel it deeply inside.
+
+Note that none of the /negative/ cases are tested yet.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ testplan.txt | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 80 insertions(+)
+ create mode 100644 testplan.txt
+
+diff --git a/testplan.txt b/testplan.txt
+new file mode 100644
+index 0000000..118dfcd
+--- /dev/null
++++ b/testplan.txt
+@@ -0,0 +1,80 @@
++How to test a new shim build for RHEL/fedora:
++
++1) build pesign-test-app, and sign it with the appropriate key
++2) build shim with the appropriate key built in
++3) install pesign-test-app and shim-unsigned on the test machine
++4) make a lockdown.efi for "Red Hat Test Certificate" and put it in \EFI\test
++   mkdir /boot/efi/EFI/test/
++   wget http://pjones.fedorapeople.org/shim/LockDown-rhtest.efi
++   mv LockDown-rhtest.efi /boot/efi/EFI/test/lockdown.efi
++5) sign shim with RHTC and put it in \EFI\test:
++   pesign -i /usr/share/shim/shim.efi -o /boot/efi/EFI/test/shim.efi \
++        -s -c "Red Hat Test Certificate"
++6) put pesign-test-app-signed.efi in \EFI\test as grubx64.efi
++   cp /usr/share/pesign-test-app-0.4/pesign-test-app-signed.efi \
++   	/boot/efi/EFI/test/test.efi
++7) sign a copy of grubx64.efi with RHTC and iput it in \EFI\test\:
++    pesign -i /boot/efi/EFI/redhat/grubx64.efi -o grubx64-unsigned.efi \
++    	-r -u 0
++    pesign -i grubx64-unsigned.efi -o /boot/efi/EFI/test/grub.efi \
++        -s -c "Red Hat Test Certificate"
++8) sign a copy of mokmanager with RHTC and put it in \EFI\test:
++    pesign -i /usr/share/shim/MokManager.efi \
++    	-o /boot/efi/EFI/test/MokManager.efi -s \
++	-c "Red Hat Test Certificate"
++9) copy grub.cfg to our test directory:
++    cp /boot/efi/EFI/redhat/grub.cfg /boot/efi/EFI/test/grub.cfg
++10) *move* \EFI\redhat\BOOT.CSV to \EFI\test 
++    mv /boot/efi/EFI/redhat/BOOT.CSV /boot/efi/EFI/test/BOOT.CSV
++11) sign a copy of fallback.efi and put it in \EFI\BOOT\fallback.efi
++    rm -rf /boot/efi/EFI/BOOT/
++    mkdir /boot/efi/EFI/BOOT/
++    pesign -i /usr/share/shim/fallback.efi \
++	-o /boot/efi/EFI/BOOT/fallback.efi \
++	-s -c "Red Hat Test Certificate"
++12) put shim.efi there as well
++    cp /boot/efi/EFI/test/shim.efi /boot/efi/EFI/BOOT/BOOTX64.EFI
++13) enroll the current kernel's certificate with mokutil:
++    mokutil --import ~/redhatsecurebootca2.cer
++14) put machine in setup mode
++15) boot to the UEFI shell
++16) run lockdown.efi from #4:
++    fs0:\EFI\test\lockdown.efi
++17) enable secure boot verification
++18) verify it can't run other binaries:
++    fs0:\EFI\redhat\grubx64.efi
++    result should be an error, probably similar to:
++    "fs0:\...\grubx64.efi is not recognized as an internal or external command"
++19) copy test.efi to grubx64.efi:
++    cp \EFI\test\test.efi \EFI\test\grubx64.efi
++20) in the EFI shell, run fs0:\EFI\test\shim.efi
++21) you should see MokManager.  Enroll the certificate you added in #13, and
++    the system will reboot.
++22) reboot to the UEFI shell and run fs0:\EFI\test\shim.efi
++    result: "This is a test application that should be completely safe."
++  If you get the expected result, shim can run things signed by its internal
++  key ring.  Check a box someplace that says it can do that.
++23) from the EFI shell, copy grub to grubx64.efi:
++    cp \EFI\test\grubx.efi \EFI\test\grubx64.efi
++24) in the EFI shell, run fs0:\EFI\test\shim.efi
++    result: this should start grub, which will let you boot a kernel
++  If grub starts, it means shim can run things signed by a key in the system's
++  db.  Check a box someplace that says it can do that.
++  If the kernel boots, it means shim can run things from Mok.  Check a box
++  someplace that says it can do that.
++25) remove all boot entries and the BootOrder variable:
++    [root@uefi ~]# cd /sys/firmware/efi/efivars/
++    [root@uefi efivars]# rm -vf Boot[0123456789]* BootOrder-*
++    removed ‘Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c’
++    removed ‘Boot0001-8be4df61-93ca-11d2-aa0d-00e098032b8c’
++    removed ‘Boot0002-8be4df61-93ca-11d2-aa0d-00e098032b8c’
++    removed ‘Boot2001-8be4df61-93ca-11d2-aa0d-00e098032b8c’
++    removed ‘BootOrder-8be4df61-93ca-11d2-aa0d-00e098032b8c’
++    [root@uefi efivars]# 
++27) reboot
++28) the system should run \EFI\BOOT\BOOTX64.EFI .  If it doesn't, you may just
++    have an old machine.  In that case, go to the EFI shell and run:
++    fs0:\EFI\BOOT\BOOTX64.EFI
++  If this works, you should see a bit of output very quickly and then the same
++  thing as #24.  This means shim recognized it was in \EFI\BOOT and ran
++  fallback.efi, which worked.
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0001-Fix-path-generation-for-Dhcpv4-bootloader.patch b/SOURCES/0001-Fix-path-generation-for-Dhcpv4-bootloader.patch
deleted file mode 100644
index 5bbcb2d..0000000
--- a/SOURCES/0001-Fix-path-generation-for-Dhcpv4-bootloader.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 0ca010d2f46a4bd49d79a529efb74680110012b5 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Wed, 20 Nov 2013 12:20:23 -0500
-Subject: [PATCH] Fix path generation for Dhcpv4 bootloader.
-
-Right now we always look for e.g. "\grubx64.efi", which is completely
-wrong.  This makes it look for the path shim was loaded from and modify
-that to end in a sanitized version of our default loader name.
-
-Resolves: rhbz#1032583
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
----
- include/str.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
- netboot.c     | 28 +++++++++++++++++++++-------
- 2 files changed, 66 insertions(+), 7 deletions(-)
- create mode 100644 include/str.h
-
-diff --git a/include/str.h b/include/str.h
-new file mode 100644
-index 0000000..0f3e003
---- /dev/null
-+++ b/include/str.h
-@@ -0,0 +1,45 @@
-+#ifndef SHIM_STR_H
-+#define SHIM_STR_H
-+
-+static inline
-+__attribute__((unused))
-+unsigned long strnlena(const CHAR8 *s, unsigned long n)
-+{
-+	unsigned long i;
-+	for (i = 0; i <= n; i++)
-+		if (s[i] == '\0')
-+			break;
-+	return i;
-+}
-+
-+static inline
-+__attribute__((unused))
-+CHAR8 *
-+strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n)
-+{
-+	unsigned long i;
-+
-+	for (i = 0; i < n && src[i] != '\0'; i++)
-+		dest[i] = src[i];
-+	for (; i < n; i++)
-+		dest[i] = '\0';
-+
-+	return dest;
-+}
-+
-+static inline
-+__attribute__((unused))
-+CHAR8 *
-+strcata(CHAR8 *dest, const CHAR8 *src)
-+{
-+	unsigned long dest_len = strlena(dest);
-+	unsigned long i;
-+
-+	for (i = 0; src[i] != '\0'; i++)
-+		dest[dest_len + i] = src[i];
-+	dest[dest_len + i] = '\0';
-+
-+	return dest;
-+}
-+
-+#endif /* SHIM_STR_H */
-diff --git a/netboot.c b/netboot.c
-index a83c82a..1732dc7 100644
---- a/netboot.c
-+++ b/netboot.c
-@@ -38,6 +38,7 @@
- #include <string.h>
- #include "shim.h"
- #include "netboot.h"
-+#include "str.h"
- 
- static inline unsigned short int __swap16(unsigned short int x)
- {
-@@ -305,19 +306,32 @@ static EFI_STATUS parseDhcp6()
- 
- static EFI_STATUS parseDhcp4()
- {
--	CHAR8 *template = (CHAR8 *)DEFAULT_LOADER_CHAR;
--	full_path = AllocateZeroPool(strlen(template)+1);
-+	CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
-+	UINTN template_len = strlen(template) + 1;
-+
-+	UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
-+	UINTN i;
-+	UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
-+
-+	for (i = dir_len; i >= 0; i--) {
-+		if (dir[i] == '/')
-+			break;
-+	}
-+	dir_len = (i >= 0) ? i + 1 : 0;
-+
-+	full_path = AllocateZeroPool(dir_len + template_len);
- 
- 	if (!full_path)
- 		return EFI_OUT_OF_RESOURCES;
- 
-+	if (dir_len > 0) {
-+		strncpya(full_path, dir, dir_len);
-+		if (full_path[dir_len-1] == '/' && template[0] == '/')
-+			full_path[dir_len-1] = '\0';
-+	}
-+	strcata(full_path, template);
- 	memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
- 
--	memcpy(full_path, template, strlen(template));
--
--	/* Note we don't capture the filename option here because we know its shim.efi
--	 * We instead assume the filename at the end of the path is going to be grubx64.efi
--	 */
- 	return EFI_SUCCESS;
- }
- 
--- 
-1.8.3.1
-
diff --git a/SOURCES/0001-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch b/SOURCES/0001-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch
deleted file mode 100644
index 62712c3..0000000
--- a/SOURCES/0001-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 36c3ce078d59abe148cd5045c0a8d9b9f7ffb88e Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Thu, 21 Nov 2013 11:26:08 -0500
-Subject: [PATCH] Lengths that might be -1 can't be unsigned, Peter.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
----
- netboot.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/netboot.c b/netboot.c
-index 1732dc7..07e2773 100644
---- a/netboot.c
-+++ b/netboot.c
-@@ -307,10 +307,10 @@ static EFI_STATUS parseDhcp6()
- static EFI_STATUS parseDhcp4()
- {
- 	CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
--	UINTN template_len = strlen(template) + 1;
-+	INTN template_len = strlen(template) + 1;
- 
--	UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
--	UINTN i;
-+	INTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
-+	INTN i;
- 	UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
- 
- 	for (i = dir_len; i >= 0; i--) {
-@@ -329,6 +329,8 @@ static EFI_STATUS parseDhcp4()
- 		if (full_path[dir_len-1] == '/' && template[0] == '/')
- 			full_path[dir_len-1] = '\0';
- 	}
-+	if (dir_len == 0 && dir[0] != '/' && template[0] == '/')
-+		template++;
- 	strcata(full_path, template);
- 	memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
- 
--- 
-1.8.3.1
-
diff --git a/SOURCES/0001-fix-verify_mok.patch b/SOURCES/0001-fix-verify_mok.patch
new file mode 100644
index 0000000..cd4e642
--- /dev/null
+++ b/SOURCES/0001-fix-verify_mok.patch
@@ -0,0 +1,54 @@
+From 11495d4019d44dce1487939f91f7d751ffbb9730 Mon Sep 17 00:00:00 2001
+From: Andrew Boie <andrew.p.boie@intel.com>
+Date: Mon, 15 Apr 2013 14:11:17 -0700
+Subject: [PATCH 01/19] fix verify_mok()
+
+() Fix the return value semantics. If the MokList doesn't
+exist, we are OK. If the MokList was compromised but we
+were able to erase it, that is OK too. Only if the list
+can't be nuked do we return an error.
+
+() Fix use of potentially uninitialized attribute variable
+
+() Actually use the return value when called from verify_buffer.
+
+Change-Id: If16df21d79c52a1726928df96d133390cde4cb7e
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ shim.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/shim.c b/shim.c
+index 23dd0ee..dcb36d0 100644
+--- a/shim.c
++++ b/shim.c
+@@ -670,13 +670,12 @@ static EFI_STATUS verify_mok (void) {
+ 	status = get_variable_attr(L"MokList", &MokListData, &MokListDataSize,
+ 				   shim_lock_guid, &attributes);
+ 
+-	if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
++	if (!EFI_ERROR(status) && attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+ 		Print(L"MokList is compromised!\nErase all keys in MokList!\n");
+ 		if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) {
+ 			Print(L"Failed to erase MokList\n");
++                        return EFI_ACCESS_DENIED;
+ 		}
+-		status = EFI_ACCESS_DENIED;
+-		return status;
+ 	}
+ 
+ 	if (MokListData)
+@@ -722,7 +721,9 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
+ 	/*
+ 	 * Check that the MOK database hasn't been modified
+ 	 */
+-	verify_mok();
++	status = verify_mok();
++	if (status != EFI_SUCCESS)
++		return status;
+ 
+ 	/*
+ 	 * Ensure that the binary isn't blacklisted
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0002-Fix-a-part-of-the-test-plan-that-was-out-of-order.patch b/SOURCES/0002-Fix-a-part-of-the-test-plan-that-was-out-of-order.patch
new file mode 100644
index 0000000..8213cb6
--- /dev/null
+++ b/SOURCES/0002-Fix-a-part-of-the-test-plan-that-was-out-of-order.patch
@@ -0,0 +1,39 @@
+From 9e8d5151979040c331f45b9d2cd443a59ca297e4 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 14 Feb 2014 14:44:31 -0500
+Subject: [PATCH 2/4] Fix a part of the test plan that was out of order.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ testplan.txt | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/testplan.txt b/testplan.txt
+index 118dfcd..96aa364 100644
+--- a/testplan.txt
++++ b/testplan.txt
+@@ -25,10 +25,10 @@ How to test a new shim build for RHEL/fedora:
+ 9) copy grub.cfg to our test directory:
+     cp /boot/efi/EFI/redhat/grub.cfg /boot/efi/EFI/test/grub.cfg
+ 10) *move* \EFI\redhat\BOOT.CSV to \EFI\test 
+-    mv /boot/efi/EFI/redhat/BOOT.CSV /boot/efi/EFI/test/BOOT.CSV
+-11) sign a copy of fallback.efi and put it in \EFI\BOOT\fallback.efi
+     rm -rf /boot/efi/EFI/BOOT/
+     mkdir /boot/efi/EFI/BOOT/
++    mv /boot/efi/EFI/redhat/BOOT.CSV /boot/efi/EFI/test/BOOT.CSV
++11) sign a copy of fallback.efi and put it in \EFI\BOOT\fallback.efi
+     pesign -i /usr/share/shim/fallback.efi \
+ 	-o /boot/efi/EFI/BOOT/fallback.efi \
+ 	-s -c "Red Hat Test Certificate"
+@@ -55,7 +55,7 @@ How to test a new shim build for RHEL/fedora:
+   If you get the expected result, shim can run things signed by its internal
+   key ring.  Check a box someplace that says it can do that.
+ 23) from the EFI shell, copy grub to grubx64.efi:
+-    cp \EFI\test\grubx.efi \EFI\test\grubx64.efi
++    cp \EFI\test\grub.efi \EFI\test\grubx64.efi
+ 24) in the EFI shell, run fs0:\EFI\test\shim.efi
+     result: this should start grub, which will let you boot a kernel
+   If grub starts, it means shim can run things signed by a key in the system's
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0002-shim.c-Add-support-for-hashing-relocation-of-32-bit-.patch b/SOURCES/0002-shim.c-Add-support-for-hashing-relocation-of-32-bit-.patch
new file mode 100644
index 0000000..8f6d38c
--- /dev/null
+++ b/SOURCES/0002-shim.c-Add-support-for-hashing-relocation-of-32-bit-.patch
@@ -0,0 +1,175 @@
+From 8e9d3af7b108cc76ce18017b3f58ad4b2e60989f Mon Sep 17 00:00:00 2001
+From: Mohanraj S <mohanrajx.sakkaraiappan@intel.com>
+Date: Tue, 27 Aug 2013 09:27:00 -0700
+Subject: [PATCH 02/19] shim.c: Add support for hashing/relocation of 32-bit
+ binaries
+
+Change-Id: Ib93305f7f1691d1b142567507df1058de62dde06
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ shim.c | 72 +++++++++++++++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 49 insertions(+), 23 deletions(-)
+
+diff --git a/shim.c b/shim.c
+index dcb36d0..a043779 100644
+--- a/shim.c
++++ b/shim.c
+@@ -126,7 +126,11 @@ static EFI_STATUS relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ 	int size = context->ImageSize;
+ 	void *ImageEnd = (char *)data + size;
+ 
++#if __LP64__
+ 	context->PEHdr->Pe32Plus.OptionalHeader.ImageBase = (UINT64)data;
++#else
++	context->PEHdr->Pe32.OptionalHeader.ImageBase = (UINT32)data;
++#endif
+ 
+ 	if (context->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ 		Print(L"Image has no relocation entry\n");
+@@ -141,7 +145,7 @@ static EFI_STATUS relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ 		return EFI_UNSUPPORTED;
+ 	}
+ 
+-	Adjust = (UINT64)data - context->ImageAddress;
++	Adjust = (UINTN)data - context->ImageAddress;
+ 
+ 	if (Adjust == 0)
+ 		return EFI_SUCCESS;
+@@ -549,9 +553,15 @@ static EFI_STATUS generate_hash (char *data, int datasize,
+ 	}
+ 
+ 	/* Hash end of certificate table to end of image header */
++#if __LP64__
+ 	hashbase = (char *) &context->PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
+ 	hashsize = context->PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders -
+ 		(int) ((char *) (&context->PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - data);
++#else
++	hashbase = (char *) &context->PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
++	hashsize = context->PEHdr->Pe32.OptionalHeader.SizeOfHeaders -
++		(int) ((char *) (&context->PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - data);
++#endif
+ 
+ 	if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+ 	    !(Sha1Update(sha1ctx, hashbase, hashsize))) {
+@@ -561,7 +571,11 @@ static EFI_STATUS generate_hash (char *data, int datasize,
+ 	}
+ 
+ 	/* Sort sections */
++#if __LP64__
+ 	SumOfBytesHashed = context->PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
++#else
++	SumOfBytesHashed = context->PEHdr->Pe32.OptionalHeader.SizeOfHeaders;
++#endif
+ 
+ 	Section = (EFI_IMAGE_SECTION_HEADER *) (
+ 		(char *)context->PEHdr + sizeof (UINT32) +
+@@ -628,7 +642,11 @@ static EFI_STATUS generate_hash (char *data, int datasize,
+ 		hashbase = data + SumOfBytesHashed;
+ 		hashsize = (unsigned int)(
+ 			size -
++#if __LP64__
+ 			context->PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
++#else
++			context->PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
++#endif
+ 			SumOfBytesHashed);
+ 
+ 		if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
+@@ -781,7 +799,7 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
+ {
+ 	EFI_IMAGE_DOS_HEADER *DosHdr = data;
+ 	EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data;
+-	unsigned long HeaderWithoutDataDir, SectionHeaderOffset;
++	unsigned long HeaderWithoutDataDir, SectionHeaderOffset, OptHeaderSize;
+ 
+ 	if (datasize < sizeof(EFI_IMAGE_DOS_HEADER)) {
+ 		Print(L"Invalid image\n");
+@@ -790,18 +808,28 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
+ 
+ 	if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE)
+ 		PEHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((char *)data + DosHdr->e_lfanew);
++#if __LP64__
++	context->NumberOfRvaAndSizes = PEHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;
++	context->SizeOfHeaders = PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
++	context->ImageSize = PEHdr->Pe32Plus.OptionalHeader.SizeOfImage;
++	OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64);
++#else
++	context->NumberOfRvaAndSizes = PEHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes;
++	context->SizeOfHeaders = PEHdr->Pe32.OptionalHeader.SizeOfHeaders;
++	context->ImageSize = (UINT64)PEHdr->Pe32.OptionalHeader.SizeOfImage;
++	OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32);
++#endif
++	context->NumberOfSections = PEHdr->Pe32.FileHeader.NumberOfSections;
+ 
+-	if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES
+-			< PEHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes) {
++	if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < context->NumberOfRvaAndSizes) {
+ 		Print(L"Image header too small\n");
+ 		return EFI_UNSUPPORTED;
+ 	}
+ 
+-	HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER64)
++	HeaderWithoutDataDir = OptHeaderSize
+ 			- sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
+-	if (((UINT32)PEHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=
+-			PEHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes
+-				* sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
++	if (((UINT32)PEHdr->Pe32.FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=
++			context->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {
+ 		Print(L"Image header overflows data directory\n");
+ 		return EFI_UNSUPPORTED;
+ 	}
+@@ -809,15 +837,15 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
+ 	SectionHeaderOffset = DosHdr->e_lfanew
+ 				+ sizeof (UINT32)
+ 				+ sizeof (EFI_IMAGE_FILE_HEADER)
+-				+ PEHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader;
+-	if ((PEHdr->Pe32Plus.OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
+-			<= PEHdr->Pe32Plus.FileHeader.NumberOfSections) {
++				+ PEHdr->Pe32.FileHeader.SizeOfOptionalHeader;
++	if (((UINT32)context->ImageSize - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
++			<= context->NumberOfSections) {
+ 		Print(L"Image sections overflow image size\n");
+ 		return EFI_UNSUPPORTED;
+ 	}
+ 
+-	if ((PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
+-			< (UINT32)PEHdr->Pe32Plus.FileHeader.NumberOfSections) {
++	if ((context->SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER
++			< (UINT32)context->NumberOfSections) {
+ 		Print(L"Image sections overflow section headers\n");
+ 		return EFI_UNSUPPORTED;
+ 	}
+@@ -837,21 +865,19 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
+ 		return EFI_UNSUPPORTED;
+ 	}
+ 
+-	if (PEHdr->Pe32.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+-		Print(L"Only 64-bit images supported\n");
+-		return EFI_UNSUPPORTED;
+-	}
+-
+ 	context->PEHdr = PEHdr;
++#if __LP64__
+ 	context->ImageAddress = PEHdr->Pe32Plus.OptionalHeader.ImageBase;
+-	context->ImageSize = (UINT64)PEHdr->Pe32Plus.OptionalHeader.SizeOfImage;
+-	context->SizeOfHeaders = PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
+ 	context->EntryPoint = PEHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint;
+ 	context->RelocDir = &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+-	context->NumberOfRvaAndSizes = PEHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;
+-	context->NumberOfSections = PEHdr->Pe32.FileHeader.NumberOfSections;
+-	context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)((char *)PEHdr + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader + sizeof(UINT32) + sizeof(EFI_IMAGE_FILE_HEADER));
+ 	context->SecDir = (EFI_IMAGE_DATA_DIRECTORY *) &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
++#else
++	context->ImageAddress = PEHdr->Pe32.OptionalHeader.ImageBase;
++	context->EntryPoint = PEHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
++	context->RelocDir = &PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
++	context->SecDir = (EFI_IMAGE_DATA_DIRECTORY *) &PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
++#endif
++	context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)((char *)PEHdr + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader + sizeof(UINT32) + sizeof(EFI_IMAGE_FILE_HEADER));
+ 
+ 	if (context->ImageSize < context->SizeOfHeaders) {
+ 		Print(L"Invalid image\n");
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0003-Allow-fallback-to-use-the-system-s-LoadImage-StartIm.patch b/SOURCES/0003-Allow-fallback-to-use-the-system-s-LoadImage-StartIm.patch
new file mode 100644
index 0000000..7ac76f0
--- /dev/null
+++ b/SOURCES/0003-Allow-fallback-to-use-the-system-s-LoadImage-StartIm.patch
@@ -0,0 +1,249 @@
+From 06495f692fa748a553ffbde8bfae2974d8c791c0 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 14 Feb 2014 15:38:25 -0500
+Subject: [PATCH 3/3] Allow fallback to use the system's LoadImage/StartImage .
+
+Track use of the system's LoadImage(), and when the next StartImage()
+call is for an image the system verified, allow that to count as
+participating, since it has been verified by the system's db.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ replacements.c | 68 +++++++++++++++++++++++++++++++++++++++++++++-
+ replacements.h |  3 +++
+ shim.c         | 85 +++++++++++++++++++++++++++++++++++-----------------------
+ 3 files changed, 121 insertions(+), 35 deletions(-)
+
+diff --git a/replacements.c b/replacements.c
+index 5ea5c32..48dc437 100644
+--- a/replacements.c
++++ b/replacements.c
+@@ -60,26 +60,82 @@
+ 
+ static EFI_SYSTEM_TABLE *systab;
+ 
++static typeof(systab->BootServices->LoadImage) system_load_image;
+ static typeof(systab->BootServices->StartImage) system_start_image;
+ static typeof(systab->BootServices->Exit) system_exit;
+ static typeof(systab->BootServices->ExitBootServices) system_exit_boot_services;
+ 
++static EFI_HANDLE last_loaded_image;
++
+ void
+ unhook_system_services(void)
+ {
+ 	systab->BootServices->Exit = system_exit;
++	systab->BootServices->LoadImage = system_load_image;
+ 	systab->BootServices->StartImage = system_start_image;
+ 	systab->BootServices->ExitBootServices = system_exit_boot_services;
+ }
+ 
+ static EFI_STATUS EFIAPI
++load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle,
++	EFI_DEVICE_PATH *DevicePath, VOID *SourceBuffer,
++	UINTN SourceSize, EFI_HANDLE *ImageHandle)
++{
++	EFI_STATUS status;
++	unhook_system_services();
++
++	status = systab->BootServices->LoadImage(BootPolicy,
++			ParentImageHandle, DevicePath,
++			SourceBuffer, SourceSize, ImageHandle);
++	hook_system_services(systab);
++	if (EFI_ERROR(status))
++		last_loaded_image = NULL;
++	else
++		last_loaded_image = *ImageHandle;
++	return status;
++}
++
++static EFI_STATUS EFIAPI
+ start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data)
+ {
+ 	EFI_STATUS status;
+ 	unhook_system_services();
++
++	/* We have to uninstall shim's protocol here, because if we're
++	 * On the fallback.efi path, then our call pathway is:
++	 *
++	 * shim->fallback->shim->grub
++	 * ^               ^      ^
++	 * |               |      \- gets protocol #0
++	 * |               \- installs its protocol (#1)
++	 * \- installs its protocol (#0)
++	 * and if we haven't removed this, then grub will get the *first*
++	 * shim's protocol, but it'll get the second shim's systab
++	 * replacements.  So even though it will participate and verify
++	 * the kernel, the systab never finds out.
++	 */
++	if (image_handle == last_loaded_image) {
++		loader_is_participating = 1;
++		uninstall_shim_protocols();
++	}
+ 	status = systab->BootServices->StartImage(image_handle, exit_data_size, exit_data);
+-	if (EFI_ERROR(status))
++	if (EFI_ERROR(status)) {
++		if (image_handle == last_loaded_image) {
++			EFI_STATUS status2 = install_shim_protocols();
++
++			if (EFI_ERROR(status2)) {
++				Print(L"Something has gone seriously wrong: %d\n",
++					status2);
++				Print(L"shim cannot continue, sorry.\n");
++				systab->BootServices->Stall(5000000);
++				systab->RuntimeServices->ResetSystem(
++					EfiResetShutdown,
++					EFI_SECURITY_VIOLATION, 0, NULL);
++			}
++		}
+ 		hook_system_services(systab);
++		loader_is_participating = 0;
++	}
+ 	return status;
+ }
+ 
+@@ -123,6 +179,16 @@ hook_system_services(EFI_SYSTEM_TABLE *local_systab)
+ 
+ 	/* We need to hook various calls to make this work... */
+ 
++	/* We need LoadImage() hooked so that fallback.c can load shim
++	 * without having to fake LoadImage as well.  This allows it
++	 * to call the system LoadImage(), and have us track the output
++	 * and mark loader_is_participating in start_image.  This means
++	 * anything added by fallback has to be verified by the system db,
++	 * which we want to preserve anyway, since that's all launching
++	 * through BDS gives us. */
++	system_load_image = systab->BootServices->LoadImage;
++	systab->BootServices->LoadImage = load_image;
++
+ 	/* we need StartImage() so that we can allow chain booting to an
+ 	 * image trusted by the firmware */
+ 	system_start_image = systab->BootServices->StartImage;
+diff --git a/replacements.h b/replacements.h
+index 5b57bc2..bd09424 100644
+--- a/replacements.h
++++ b/replacements.h
+@@ -41,4 +41,7 @@ extern int loader_is_participating;
+ extern void hook_system_services(EFI_SYSTEM_TABLE *local_systab);
+ extern void unhook_system_services(void);
+ 
++extern EFI_STATUS install_shim_protocols(void);
++extern void uninstall_shim_protocols(void);
++
+ #endif /* SHIM_REPLACEMENTS_H */
+diff --git a/shim.c b/shim.c
+index cf93d65..0e18d38 100644
+--- a/shim.c
++++ b/shim.c
+@@ -1707,11 +1707,56 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
+ 	return EFI_SUCCESS;
+ }
+ 
+-EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
++static SHIM_LOCK shim_lock_interface;
++static EFI_HANDLE shim_lock_handle;
++
++EFI_STATUS
++install_shim_protocols(void)
++{
++	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
++	EFI_STATUS efi_status;
++	/*
++	 * Install the protocol
++	 */
++	efi_status = uefi_call_wrapper(BS->InstallProtocolInterface, 4,
++			  &shim_lock_handle, &shim_lock_guid,
++			  EFI_NATIVE_INTERFACE, &shim_lock_interface);
++	if (EFI_ERROR(efi_status)) {
++		console_error(L"Could not install security protocol",
++			      efi_status);
++		return efi_status;
++	}
++
++#if defined(OVERRIDE_SECURITY_POLICY)
++	/*
++	 * Install the security protocol hook
++	 */
++	security_policy_install(shim_verify);
++#endif
++
++	return EFI_SUCCESS;
++}
++
++void
++uninstall_shim_protocols(void)
+ {
+ 	EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+-	static SHIM_LOCK shim_lock_interface;
+-	EFI_HANDLE handle = NULL;
++#if defined(OVERRIDE_SECURITY_POLICY)
++	/*
++	 * Clean up the security protocol hook
++	 */
++	security_policy_uninstall();
++#endif
++
++	/*
++	 * If we're back here then clean everything up before exiting
++	 */
++	uefi_call_wrapper(BS->UninstallProtocolInterface, 3, shim_lock_handle,
++			  &shim_lock_guid, &shim_lock_interface);
++}
++
++EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
++{
+ 	EFI_STATUS efi_status;
+ 
+ 	verification_method = VERIFIED_BY_NOTHING;
+@@ -1768,24 +1813,9 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
+ 		}
+ 	}
+ 
+-	/*
+-	 * Install the protocol
+-	 */
+-	efi_status = uefi_call_wrapper(BS->InstallProtocolInterface, 4,
+-			  &handle, &shim_lock_guid, EFI_NATIVE_INTERFACE,
+-			  &shim_lock_interface);
+-	if (EFI_ERROR(efi_status)) {
+-		console_error(L"Could not install security protocol",
+-			      efi_status);
++	efi_status = install_shim_protocols();
++	if (EFI_ERROR(efi_status))
+ 		return efi_status;
+-	}
+-
+-#if defined(OVERRIDE_SECURITY_POLICY)
+-	/*
+-	 * Install the security protocol hook
+-	 */
+-	security_policy_install(shim_verify);
+-#endif
+ 
+ 	/*
+ 	 * Enter MokManager if necessary
+@@ -1810,20 +1840,7 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
+ 
+ 	efi_status = init_grub(image_handle);
+ 
+-#if defined(OVERRIDE_SECURITY_POLICY)
+-	/*
+-	 * Clean up the security protocol hook
+-	 */
+-	security_policy_uninstall();
+-#endif
+-
+-	/*
+-	 * If we're back here then clean everything up before exiting
+-	 */
+-	uefi_call_wrapper(BS->UninstallProtocolInterface, 3, handle,
+-			  &shim_lock_guid, &shim_lock_interface);
+-
+-
++	uninstall_shim_protocols();
+ 	/*
+ 	 * Remove our hooks from system services.
+ 	 */
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0003-netboot.h-fix-build-error-on-32-bit-systems.patch b/SOURCES/0003-netboot.h-fix-build-error-on-32-bit-systems.patch
new file mode 100644
index 0000000..abd8da7
--- /dev/null
+++ b/SOURCES/0003-netboot.h-fix-build-error-on-32-bit-systems.patch
@@ -0,0 +1,27 @@
+From 434e854202236ec5809dbb96589fc34313dbff9e Mon Sep 17 00:00:00 2001
+From: Andrew Boie <andrew.p.boie@intel.com>
+Date: Thu, 31 Oct 2013 13:56:56 -0700
+Subject: [PATCH 03/19] netboot.h: fix build error on 32-bit systems
+
+Function prototype/implementation mismatch.
+
+Change-Id: I89aaae1b49d0372d3aed76fc21c194e0ae55f72e
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ netboot.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/netboot.h b/netboot.h
+index 2cdb421..6417373 100644
+--- a/netboot.h
++++ b/netboot.h
+@@ -5,5 +5,5 @@ extern BOOLEAN findNetboot(EFI_HANDLE image_handle);
+ 
+ extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle);
+ 
+-extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINTN *bufsiz);
++extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *bufsiz);
+ #endif
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0004-properly-compile-OpenSSL-in-32-bit-mode.patch b/SOURCES/0004-properly-compile-OpenSSL-in-32-bit-mode.patch
new file mode 100644
index 0000000..d528ecb
--- /dev/null
+++ b/SOURCES/0004-properly-compile-OpenSSL-in-32-bit-mode.patch
@@ -0,0 +1,34 @@
+From c5ed2dfa5d9c2d5de33db290ae8cc237342dbc4c Mon Sep 17 00:00:00 2001
+From: Andrey Petrov <andrey.petrov@intel.com>
+Date: Mon, 11 Nov 2013 13:46:42 -0800
+Subject: [PATCH 04/19] properly compile OpenSSL in 32-bit mode
+
+Change-Id: Iff3ee5ae0f0b95b282b99a23e465723b4e9f6104
+Signed-off-by: Andrey Petrov <andrey.petrov@intel.com>
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ Cryptlib/OpenSSL/Makefile | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile
+index c93d5af..3d5a87c 100644
+--- a/Cryptlib/OpenSSL/Makefile
++++ b/Cryptlib/OpenSSL/Makefile
+@@ -10,9 +10,12 @@ LIB_GCC		= $(shell $(CC) -print-libgcc-file-name)
+ EFI_LIBS	= -lefi -lgnuefi $(LIB_GCC)
+ 
+ CFLAGS		= -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \
+-		  -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
++		  -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
+ ifeq ($(ARCH),x86_64)
+-	CFLAGS	+= -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
++	CFLAGS	+= -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DSIXTY_FOUR_BIT_LONG
++endif
++ifeq ($(ARCH),ia32)
++	CFLAGS	+= -DTHIRTY_TWO_BIT
+ endif
+ LDFLAGS		= -nostdlib -znocombreloc
+ 
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0005-fallback.c-fix-32-bit-compilation.patch b/SOURCES/0005-fallback.c-fix-32-bit-compilation.patch
new file mode 100644
index 0000000..1d89b3c
--- /dev/null
+++ b/SOURCES/0005-fallback.c-fix-32-bit-compilation.patch
@@ -0,0 +1,38 @@
+From d74ab697f7f20418eeb09f0291cc480d43241dea Mon Sep 17 00:00:00 2001
+From: Andrew Boie <andrew.p.boie@intel.com>
+Date: Mon, 11 Nov 2013 16:12:23 -0800
+Subject: [PATCH 05/19] fallback.c: fix 32-bit compilation
+
+fh->Read expects pointer to 32-bit int, use UINTN
+
+Change-Id: If1a728efd51a9a24dfcd8123e84bf4c0713491fe
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ fallback.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fallback.c b/fallback.c
+index 82ddbf2..c875144 100644
+--- a/fallback.c
++++ b/fallback.c
+@@ -15,7 +15,7 @@
+ EFI_LOADED_IMAGE *this_image = NULL;
+ 
+ static EFI_STATUS
+-get_file_size(EFI_FILE_HANDLE fh, UINT64 *retsize)
++get_file_size(EFI_FILE_HANDLE fh, UINTN *retsize)
+ {
+ 	EFI_STATUS rc;
+ 	void *buffer = NULL;
+@@ -60,7 +60,7 @@ read_file(EFI_FILE_HANDLE fh, CHAR16 *fullpath, CHAR16 **buffer, UINT64 *bs)
+ 		return rc;
+ 	}
+ 
+-	UINT64 len = 0;
++	UINTN len = 0;
+ 	CHAR16 *b = NULL;
+ 	rc = get_file_size(fh2, &len);
+ 	if (EFI_ERROR(rc)) {
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0006-fix-fallback.so-build-dependency.patch b/SOURCES/0006-fix-fallback.so-build-dependency.patch
new file mode 100644
index 0000000..883bc85
--- /dev/null
+++ b/SOURCES/0006-fix-fallback.so-build-dependency.patch
@@ -0,0 +1,29 @@
+From 06e15d762966d4224f7e54480b9213c4dcf1fe35 Mon Sep 17 00:00:00 2001
+From: Andrew Boie <andrew.p.boie@intel.com>
+Date: Mon, 11 Nov 2013 16:14:22 -0800
+Subject: [PATCH 06/19] fix fallback.so build dependency
+
+Exposed during parallel builds
+
+Change-Id: I9867858166dcafd69438f37ee5da14a267ace8f4
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index a22c6b3..2eab862 100644
+--- a/Makefile
++++ b/Makefile
+@@ -83,7 +83,7 @@ shim.so: $(OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+ 
+ fallback.o: $(FALLBACK_SRCS)
+ 
+-fallback.so: $(FALLBACK_OBJS)
++fallback.so: $(FALLBACK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+ 	$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
+ 
+ MokManager.o: $(MOK_SOURCES)
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0007-propagate-some-path-variables.patch b/SOURCES/0007-propagate-some-path-variables.patch
new file mode 100644
index 0000000..83dcdb4
--- /dev/null
+++ b/SOURCES/0007-propagate-some-path-variables.patch
@@ -0,0 +1,38 @@
+From 476d376ed08e1431bf7e20bf47ea3fc6c36dd168 Mon Sep 17 00:00:00 2001
+From: Andrew Boie <andrew.p.boie@intel.com>
+Date: Mon, 11 Nov 2013 16:15:39 -0800
+Subject: [PATCH 07/19] propagate some path variables
+
+If these are overridden on the command line, pass them along to
+the sub-makes.
+
+Change-Id: I531ccb5d2f5e4be8e99d4892cdcfffffc1ad9877
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ Makefile | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 2eab862..d619ff4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -92,13 +92,13 @@ MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a
+ 	$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
+ 
+ Cryptlib/libcryptlib.a:
+-	$(MAKE) -C Cryptlib
++	$(MAKE) -C Cryptlib EFI_PATH=$(EFI_PATH) EFI_INCLUDE=$(EFI_INCLUDE) ARCH=$(ARCH)
+ 
+ Cryptlib/OpenSSL/libopenssl.a:
+-	$(MAKE) -C Cryptlib/OpenSSL
++	$(MAKE) -C Cryptlib/OpenSSL EFI_PATH=$(EFI_PATH) EFI_INCLUDE=$(EFI_INCLUDE) ARCH=$(ARCH) 
+ 
+ lib/lib.a:
+-	$(MAKE) -C lib EFI_PATH=$(EFI_PATH)
++	$(MAKE) -C lib EFI_PATH=$(EFI_PATH) EFI_INCLUDE=$(EFI_INCLUDE) ARCH=$(ARCH)
+ 
+ %.efi: %.so
+ 	objcopy -j .text -j .sdata -j .data \
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0008-allow-32-bit-compilation-with-64-bit-compiler.patch b/SOURCES/0008-allow-32-bit-compilation-with-64-bit-compiler.patch
new file mode 100644
index 0000000..291c16b
--- /dev/null
+++ b/SOURCES/0008-allow-32-bit-compilation-with-64-bit-compiler.patch
@@ -0,0 +1,90 @@
+From 9712a7e77dc12f7569858b81d620d85301f50ede Mon Sep 17 00:00:00 2001
+From: Andrew Boie <andrew.p.boie@intel.com>
+Date: Mon, 11 Nov 2013 16:17:20 -0800
+Subject: [PATCH 08/19] allow 32-bit compilation with 64-bit compiler
+
+Also removed unused LIB_PATH from some Makefiles.
+
+Change-Id: I7d28d18f7531b51b6121a2ffb88bcaedec57c467
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ Cryptlib/Makefile         | 5 +++--
+ Cryptlib/OpenSSL/Makefile | 4 +---
+ Makefile                  | 3 +++
+ lib/Makefile              | 3 +++
+ 4 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile
+index a05a4db..d24e59e 100644
+--- a/Cryptlib/Makefile
++++ b/Cryptlib/Makefile
+@@ -1,7 +1,5 @@
+ ARCH		= $(shell uname -m | sed s,i[3456789]86,ia32,)
+ 
+-LIB_PATH	= /usr/lib64
+-
+ EFI_INCLUDE	= /usr/include/efi
+ EFI_INCLUDES	= -nostdinc -IInclude -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
+ EFI_PATH	= /usr/lib64/gnuefi
+@@ -14,6 +12,9 @@ CFLAGS		= -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort-
+ ifeq ($(ARCH),x86_64)
+ 	CFLAGS	+= -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
+ endif
++ifeq ($(ARCH),ia32)
++	CFLAGS	+= -m32
++endif
+ LDFLAGS		= -nostdlib -znocombreloc
+ 
+ TARGET		= libcryptlib.a
+diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile
+index 3d5a87c..8e2f2a6 100644
+--- a/Cryptlib/OpenSSL/Makefile
++++ b/Cryptlib/OpenSSL/Makefile
+@@ -1,7 +1,5 @@
+ ARCH		= $(shell uname -m | sed s,i[3456789]86,ia32,)
+ 
+-LIB_PATH	= /usr/lib64
+-
+ EFI_INCLUDE	= /usr/include/efi
+ EFI_INCLUDES	= -I../Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
+ EFI_PATH	= /usr/lib64/gnuefi
+@@ -15,7 +13,7 @@ ifeq ($(ARCH),x86_64)
+ 	CFLAGS	+= -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DSIXTY_FOUR_BIT_LONG
+ endif
+ ifeq ($(ARCH),ia32)
+-	CFLAGS	+= -DTHIRTY_TWO_BIT
++	CFLAGS	+= -m32 -DTHIRTY_TWO_BIT
+ endif
+ LDFLAGS		= -nostdlib -znocombreloc
+ 
+diff --git a/Makefile b/Makefile
+index d619ff4..e65d28d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -28,6 +28,9 @@ endif
+ ifeq ($(ARCH),x86_64)
+ 	CFLAGS	+= -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
+ endif
++ifeq ($(ARCH),ia32)
++	CFLAGS	+= -m32
++endif
+ ifneq ($(origin VENDOR_CERT_FILE), undefined)
+ 	CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\"
+ endif
+diff --git a/lib/Makefile b/lib/Makefile
+index adb0347..a9c9cf6 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -17,6 +17,9 @@ CFLAGS          = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
+ ifeq ($(ARCH),x86_64)
+         CFLAGS  += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
+ endif
++ifeq ($(ARCH),ia32)
++        CFLAGS  += -m32
++endif
+ 
+ lib.a: $(LIBFILES)
+ 	ar rcs lib.a $(LIBFILES)
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0009-shim-improve-error-messages.patch b/SOURCES/0009-shim-improve-error-messages.patch
new file mode 100644
index 0000000..81ab3fd
--- /dev/null
+++ b/SOURCES/0009-shim-improve-error-messages.patch
@@ -0,0 +1,186 @@
+From 2f09d0ab290d9b0d8aa14c3243f1d85a20bc34e6 Mon Sep 17 00:00:00 2001
+From: Andrew Boie <andrew.p.boie@intel.com>
+Date: Mon, 11 Nov 2013 17:29:06 -0800
+Subject: [PATCH 09/19] shim: improve error messages
+
+%r when used in Print() will show a string representation of
+an EFI_STATUS code.
+
+Change-Id: I6db47f5213454603bd66177aca378ad01e9f0bd4
+Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
+---
+ shim.c | 38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/shim.c b/shim.c
+index a043779..9ae1936 100644
+--- a/shim.c
++++ b/shim.c
+@@ -914,7 +914,7 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
+ 	 */
+ 	efi_status = read_header(data, datasize, &context);
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Failed to read header\n");
++		Print(L"Failed to read header: %r\n", efi_status);
+ 		return efi_status;
+ 	}
+ 
+@@ -981,7 +981,7 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
+ 	efi_status = relocate_coff(&context, buffer);
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Relocation failed\n");
++		Print(L"Relocation failed: %r\n", efi_status);
+ 		FreePool(buffer);
+ 		return efi_status;
+ 	}
+@@ -1022,7 +1022,7 @@ should_use_fallback(EFI_HANDLE image_handle)
+ 	rc = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
+ 				       &loaded_image_protocol, (void **)&li);
+ 	if (EFI_ERROR(rc)) {
+-		Print(L"Could not get image for bootx64.efi: %d\n", rc);
++		Print(L"Could not get image for bootx64.efi: %r\n", rc);
+ 		return 0;
+ 	}
+ 
+@@ -1044,13 +1044,13 @@ should_use_fallback(EFI_HANDLE image_handle)
+ 	rc = uefi_call_wrapper(BS->HandleProtocol, 3, li->DeviceHandle,
+ 			       &FileSystemProtocol, (void **)&fio);
+ 	if (EFI_ERROR(rc)) {
+-		Print(L"Could not get fio for li->DeviceHandle: %d\n", rc);
++		Print(L"Could not get fio for li->DeviceHandle: %r\n", rc);
+ 		return 0;
+ 	}
+ 	
+ 	rc = uefi_call_wrapper(fio->OpenVolume, 2, fio, &vh);
+ 	if (EFI_ERROR(rc)) {
+-		Print(L"Could not open fio volume: %d\n", rc);
++		Print(L"Could not open fio volume: %r\n", rc);
+ 		return 0;
+ 	}
+ 
+@@ -1172,14 +1172,14 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
+ 				       (void **)&drive);
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Failed to find fs\n");
++		Print(L"Failed to find fs: %r\n", efi_status);
+ 		goto error;
+ 	}
+ 
+ 	efi_status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Failed to open fs\n");
++		Print(L"Failed to open fs: %r\n", efi_status);
+ 		goto error;
+ 	}
+ 
+@@ -1190,7 +1190,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
+ 				       EFI_FILE_MODE_READ, 0);
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Failed to open %s - %lx\n", PathName, efi_status);
++		Print(L"Failed to open %s - %r\n", PathName, efi_status);
+ 		goto error;
+ 	}
+ 
+@@ -1223,7 +1223,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
+ 	}
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Unable to get file info\n");
++		Print(L"Unable to get file info: %r\n", efi_status);
+ 		goto error;
+ 	}
+ 
+@@ -1251,7 +1251,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
+ 	}
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Unexpected return from initial read: %x, buffersize %x\n", efi_status, buffersize);
++		Print(L"Unexpected return from initial read: %r, buffersize %x\n", efi_status, buffersize);
+ 		goto error;
+ 	}
+ 
+@@ -1328,20 +1328,20 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
+ 	efi_status = generate_path(li, ImagePath, &path, &PathName);
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Unable to generate path: %s\n", ImagePath);
++		Print(L"Unable to generate path %s: %r\n", ImagePath, efi_status);
+ 		goto done;
+ 	}
+ 
+ 	if (findNetboot(image_handle)) {
+ 		efi_status = parseNetbootinfo(image_handle);
+ 		if (efi_status != EFI_SUCCESS) {
+-			Print(L"Netboot parsing failed: %d\n", efi_status);
++			Print(L"Netboot parsing failed: %r\n", efi_status);
+ 			return EFI_PROTOCOL_ERROR;
+ 		}
+ 		efi_status = FetchNetbootimage(image_handle, &sourcebuffer,
+ 					       &sourcesize);
+ 		if (efi_status != EFI_SUCCESS) {
+-			Print(L"Unable to fetch TFTP image\n");
++			Print(L"Unable to fetch TFTP image: %r\n", efi_status);
+ 			return efi_status;
+ 		}
+ 		data = sourcebuffer;
+@@ -1353,7 +1353,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
+ 		efi_status = load_image(li, &data, &datasize, PathName);
+ 
+ 		if (efi_status != EFI_SUCCESS) {
+-			Print(L"Failed to load image\n");
++			Print(L"Failed to load image %s: %r\n", PathName, efi_status);
+ 			goto done;
+ 		}
+ 	}
+@@ -1370,7 +1370,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
+ 	efi_status = handle_image(data, datasize, li);
+ 
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Failed to load image\n");
++		Print(L"Failed to load image: %r\n", efi_status);
+ 		CopyMem(li, &li_bak, sizeof(li_bak));
+ 		goto done;
+ 	}
+@@ -1473,7 +1473,7 @@ EFI_STATUS mirror_mok_list()
+ 				       | EFI_VARIABLE_RUNTIME_ACCESS,
+ 				       FullDataSize, FullData);
+ 	if (efi_status != EFI_SUCCESS) {
+-		Print(L"Failed to set MokListRT %d\n", efi_status);
++		Print(L"Failed to set MokListRT: %r\n", efi_status);
+ 	}
+ 
+ 	return efi_status;
+@@ -1514,7 +1514,7 @@ EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
+ 		efi_status = start_image(image_handle, MOK_MANAGER);
+ 
+ 		if (efi_status != EFI_SUCCESS) {
+-			Print(L"Failed to start MokManager\n");
++			Print(L"Failed to start MokManager: %r\n", efi_status);
+ 			return efi_status;
+ 		}
+ 	}
+@@ -1621,7 +1621,7 @@ static EFI_STATUS mok_ignore_db()
+ 				| EFI_VARIABLE_RUNTIME_ACCESS,
+ 				DataSize, (void *)&Data);
+ 		if (efi_status != EFI_SUCCESS) {
+-			Print(L"Failed to set MokIgnoreDB %d\n", efi_status);
++			Print(L"Failed to set MokIgnoreDB: %r\n", efi_status);
+ 		}
+ 	}
+ 
+@@ -1648,7 +1648,7 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
+ 	status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
+ 				   &LoadedImageProtocol, (void **) &li);
+ 	if (status != EFI_SUCCESS) {
+-		Print (L"Failed to get load options\n");
++		Print (L"Failed to get load options: %r\n", status);
+ 		return status;
+ 	}
+ 
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0010-Clarify-meaning-of-insecure_mode.patch b/SOURCES/0010-Clarify-meaning-of-insecure_mode.patch
new file mode 100644
index 0000000..71146ef
--- /dev/null
+++ b/SOURCES/0010-Clarify-meaning-of-insecure_mode.patch
@@ -0,0 +1,99 @@
+From d95b24bd02cf41cca9adebd95f10609d6424d2b3 Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Tue, 19 Nov 2013 10:09:13 -0500
+Subject: [PATCH 10/19] Clarify meaning of insecure_mode
+
+insecure_mode was intended to indicate that the user had explicity disabled
+checks with mokutil, which means it wasn't the opposite of secure_mode().
+Change the names to clarify this and don't show the insecure mode message
+unless the user has explicitly enabled that mode.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+---
+ replacements.c |  6 ------
+ shim.c         | 12 ++++++------
+ 2 files changed, 6 insertions(+), 12 deletions(-)
+
+diff --git a/replacements.c b/replacements.c
+index bac5e5d..5ea5c32 100644
+--- a/replacements.c
++++ b/replacements.c
+@@ -64,13 +64,9 @@ static typeof(systab->BootServices->StartImage) system_start_image;
+ static typeof(systab->BootServices->Exit) system_exit;
+ static typeof(systab->BootServices->ExitBootServices) system_exit_boot_services;
+ 
+-extern UINT8 insecure_mode;
+-
+ void
+ unhook_system_services(void)
+ {
+-	if (insecure_mode)
+-		return;
+ 	systab->BootServices->Exit = system_exit;
+ 	systab->BootServices->StartImage = system_start_image;
+ 	systab->BootServices->ExitBootServices = system_exit_boot_services;
+@@ -123,8 +119,6 @@ exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus,
+ void
+ hook_system_services(EFI_SYSTEM_TABLE *local_systab)
+ {
+-	if (insecure_mode)
+-		return;
+ 	systab = local_systab;
+ 
+ 	/* We need to hook various calls to make this work... */
+diff --git a/shim.c b/shim.c
+index 9ae1936..524f5fc 100644
+--- a/shim.c
++++ b/shim.c
+@@ -85,7 +85,7 @@ int loader_is_participating;
+ 
+ #define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
+ 
+-UINT8 insecure_mode;
++UINT8 user_insecure_mode;
+ UINT8 ignore_db;
+ 
+ typedef enum {
+@@ -456,7 +456,7 @@ static BOOLEAN secure_mode (void)
+ 	UINT8 *Data;
+ 	UINT8 sb, setupmode;
+ 
+-	if (insecure_mode)
++	if (user_insecure_mode)
+ 		return FALSE;
+ 
+ 	status = get_variable(L"SecureBoot", &Data, &len, global_var);
+@@ -1534,7 +1534,7 @@ static EFI_STATUS check_mok_sb (void)
+ 	UINTN MokSBStateSize = 0;
+ 	UINT32 attributes;
+ 
+-	insecure_mode = 0;
++	user_insecure_mode = 0;
+ 	ignore_db = 0;
+ 
+ 	status = get_variable_attr(L"MokSBState", &MokSBState, &MokSBStateSize,
+@@ -1555,7 +1555,7 @@ static EFI_STATUS check_mok_sb (void)
+ 		status = EFI_ACCESS_DENIED;
+ 	} else {
+ 		if (*(UINT8 *)MokSBState == 1) {
+-			insecure_mode = 1;
++			user_insecure_mode = 1;
+ 		}
+ 	}
+ 
+@@ -1753,10 +1753,10 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
+ 	/*
+ 	 * Tell the user that we're in insecure mode if necessary
+ 	 */
+-	if (!secure_mode()) {
++	if (user_insecure_mode) {
+ 		Print(L"Booting in insecure mode\n");
+ 		uefi_call_wrapper(BS->Stall, 1, 2000000);
+-	} else {
++	} else if (secure_mode()) {
+ 		/*
+ 		 * Install our hooks for ExitBootServices() and StartImage()
+ 		 */
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0011-Don-t-hook-system-services-if-shim-has-no-built-in-k.patch b/SOURCES/0011-Don-t-hook-system-services-if-shim-has-no-built-in-k.patch
new file mode 100644
index 0000000..c07d207
--- /dev/null
+++ b/SOURCES/0011-Don-t-hook-system-services-if-shim-has-no-built-in-k.patch
@@ -0,0 +1,42 @@
+From 8b48ec5c70cd97d37f48581a4eab8139c1a95a1f Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Tue, 19 Nov 2013 10:15:55 -0500
+Subject: [PATCH 11/19] Don't hook system services if shim has no built-in keys
+
+Shim should only need to enforce its security policy when its launching
+binaries signed with its built-in key. Binaries signed by keys in db or
+Mokdb should be able to rely on their own security policy.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+---
+ shim.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/shim.c b/shim.c
+index 524f5fc..cf93d65 100644
+--- a/shim.c
++++ b/shim.c
+@@ -1757,11 +1757,15 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
+ 		Print(L"Booting in insecure mode\n");
+ 		uefi_call_wrapper(BS->Stall, 1, 2000000);
+ 	} else if (secure_mode()) {
+-		/*
+-		 * Install our hooks for ExitBootServices() and StartImage()
+-		 */
+-		hook_system_services(systab);
+-		loader_is_participating = 0;
++		if (vendor_cert_size || vendor_dbx_size) {
++			/*
++			 * If shim includes its own certificates then ensure
++			 * that anything it boots has performed some
++			 * validation of the next image.
++			 */
++			hook_system_services(systab);
++			loader_is_participating = 0;
++		}
+ 	}
+ 
+ 	/*
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0012-Fix-path-generation-for-Dhcpv4-bootloader.patch b/SOURCES/0012-Fix-path-generation-for-Dhcpv4-bootloader.patch
new file mode 100644
index 0000000..9591b28
--- /dev/null
+++ b/SOURCES/0012-Fix-path-generation-for-Dhcpv4-bootloader.patch
@@ -0,0 +1,124 @@
+From e62b69a5b0b87c6df7a4fc23906134945309e927 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Wed, 20 Nov 2013 12:20:23 -0500
+Subject: [PATCH 12/19] Fix path generation for Dhcpv4 bootloader.
+
+Right now we always look for e.g. "\grubx64.efi", which is completely
+wrong.  This makes it look for the path shim was loaded from and modify
+that to end in a sanitized version of our default loader name.
+
+Resolves: rhbz#1032583
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ include/str.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ netboot.c     | 28 +++++++++++++++++++++-------
+ 2 files changed, 66 insertions(+), 7 deletions(-)
+ create mode 100644 include/str.h
+
+diff --git a/include/str.h b/include/str.h
+new file mode 100644
+index 0000000..0f3e003
+--- /dev/null
++++ b/include/str.h
+@@ -0,0 +1,45 @@
++#ifndef SHIM_STR_H
++#define SHIM_STR_H
++
++static inline
++__attribute__((unused))
++unsigned long strnlena(const CHAR8 *s, unsigned long n)
++{
++	unsigned long i;
++	for (i = 0; i <= n; i++)
++		if (s[i] == '\0')
++			break;
++	return i;
++}
++
++static inline
++__attribute__((unused))
++CHAR8 *
++strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n)
++{
++	unsigned long i;
++
++	for (i = 0; i < n && src[i] != '\0'; i++)
++		dest[i] = src[i];
++	for (; i < n; i++)
++		dest[i] = '\0';
++
++	return dest;
++}
++
++static inline
++__attribute__((unused))
++CHAR8 *
++strcata(CHAR8 *dest, const CHAR8 *src)
++{
++	unsigned long dest_len = strlena(dest);
++	unsigned long i;
++
++	for (i = 0; src[i] != '\0'; i++)
++		dest[dest_len + i] = src[i];
++	dest[dest_len + i] = '\0';
++
++	return dest;
++}
++
++#endif /* SHIM_STR_H */
+diff --git a/netboot.c b/netboot.c
+index a83c82a..1732dc7 100644
+--- a/netboot.c
++++ b/netboot.c
+@@ -38,6 +38,7 @@
+ #include <string.h>
+ #include "shim.h"
+ #include "netboot.h"
++#include "str.h"
+ 
+ static inline unsigned short int __swap16(unsigned short int x)
+ {
+@@ -305,19 +306,32 @@ static EFI_STATUS parseDhcp6()
+ 
+ static EFI_STATUS parseDhcp4()
+ {
+-	CHAR8 *template = (CHAR8 *)DEFAULT_LOADER_CHAR;
+-	full_path = AllocateZeroPool(strlen(template)+1);
++	CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
++	UINTN template_len = strlen(template) + 1;
++
++	UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
++	UINTN i;
++	UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
++
++	for (i = dir_len; i >= 0; i--) {
++		if (dir[i] == '/')
++			break;
++	}
++	dir_len = (i >= 0) ? i + 1 : 0;
++
++	full_path = AllocateZeroPool(dir_len + template_len);
+ 
+ 	if (!full_path)
+ 		return EFI_OUT_OF_RESOURCES;
+ 
++	if (dir_len > 0) {
++		strncpya(full_path, dir, dir_len);
++		if (full_path[dir_len-1] == '/' && template[0] == '/')
++			full_path[dir_len-1] = '\0';
++	}
++	strcata(full_path, template);
+ 	memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
+ 
+-	memcpy(full_path, template, strlen(template));
+-
+-	/* Note we don't capture the filename option here because we know its shim.efi
+-	 * We instead assume the filename at the end of the path is going to be grubx64.efi
+-	 */
+ 	return EFI_SUCCESS;
+ }
+ 
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0013-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch b/SOURCES/0013-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch
new file mode 100644
index 0000000..c057508
--- /dev/null
+++ b/SOURCES/0013-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch
@@ -0,0 +1,40 @@
+From 27129a5a05d1947e6f7479766e8281d50d6031f6 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Thu, 21 Nov 2013 11:26:08 -0500
+Subject: [PATCH 13/19] Lengths that might be -1 can't be unsigned, Peter.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ netboot.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/netboot.c b/netboot.c
+index 1732dc7..07e2773 100644
+--- a/netboot.c
++++ b/netboot.c
+@@ -307,10 +307,10 @@ static EFI_STATUS parseDhcp6()
+ static EFI_STATUS parseDhcp4()
+ {
+ 	CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
+-	UINTN template_len = strlen(template) + 1;
++	INTN template_len = strlen(template) + 1;
+ 
+-	UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
+-	UINTN i;
++	INTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
++	INTN i;
+ 	UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
+ 
+ 	for (i = dir_len; i >= 0; i--) {
+@@ -329,6 +329,8 @@ static EFI_STATUS parseDhcp4()
+ 		if (full_path[dir_len-1] == '/' && template[0] == '/')
+ 			full_path[dir_len-1] = '\0';
+ 	}
++	if (dir_len == 0 && dir[0] != '/' && template[0] == '/')
++		template++;
+ 	strcata(full_path, template);
+ 	memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
+ 
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0014-Fix-wrong-sizeof.patch b/SOURCES/0014-Fix-wrong-sizeof.patch
new file mode 100644
index 0000000..e548615
--- /dev/null
+++ b/SOURCES/0014-Fix-wrong-sizeof.patch
@@ -0,0 +1,30 @@
+From af25679e166da9bd32a0ed7fbf67a408dda7f71a Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 15 Nov 2013 09:21:53 -0500
+Subject: [PATCH 14/19] Fix wrong sizeof().
+
+CHAR16* vs CHAR16**, so the result is the same on all platforms.
+
+Detected by coverity.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ lib/shell.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/shell.c b/lib/shell.c
+index 51de4e0..7337834 100644
+--- a/lib/shell.c
++++ b/lib/shell.c
+@@ -35,7 +35,7 @@ argsplit(EFI_HANDLE image, int *argc, CHAR16*** ARGV)
+ 
+ 	(*argc)++;		/* we counted spaces, so add one for initial */
+ 
+-	*ARGV = AllocatePool(*argc * sizeof(*ARGV));
++	*ARGV = AllocatePool(*argc * sizeof(**ARGV));
+ 	if (!*ARGV) {
+ 		return EFI_OUT_OF_RESOURCES;
+ 	}
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0015-Initialize-entries-before-we-pass-it-to-another-func.patch b/SOURCES/0015-Initialize-entries-before-we-pass-it-to-another-func.patch
new file mode 100644
index 0000000..855c7a0
--- /dev/null
+++ b/SOURCES/0015-Initialize-entries-before-we-pass-it-to-another-func.patch
@@ -0,0 +1,30 @@
+From 4dbef508ab6359e8ca14df53b83f970bdeec17ba Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 15 Nov 2013 09:24:01 -0500
+Subject: [PATCH 15/19] Initialize entries before we pass it to another
+ function.
+
+Coverity scan noticed that entries is uninitialized when we pass its
+location to another function.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ lib/simple_file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/simple_file.c b/lib/simple_file.c
+index 3af0ec8..d345d87 100644
+--- a/lib/simple_file.c
++++ b/lib/simple_file.c
+@@ -415,7 +415,7 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
+ 		     CHAR16 *filter, CHAR16 **result)
+ {
+ 	EFI_STATUS status;
+-	CHAR16 **entries;
++	CHAR16 **entries = NULL;
+ 	EFI_FILE_INFO *dmp;
+ 	int count, select, len;
+ 	CHAR16 *newname, *selected;
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0016-Rewrite-directory-traversal-allocation-path-so-cover.patch b/SOURCES/0016-Rewrite-directory-traversal-allocation-path-so-cover.patch
new file mode 100644
index 0000000..bce4434
--- /dev/null
+++ b/SOURCES/0016-Rewrite-directory-traversal-allocation-path-so-cover.patch
@@ -0,0 +1,63 @@
+From 3a7feeff6cdb3b96a1ef2ccff8c150e2324d50a9 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 15 Nov 2013 09:38:41 -0500
+Subject: [PATCH 16/19] Rewrite directory traversal allocation path so coverity
+ can grok it.
+
+The things we do for our tools.  In this case, make the AllocatePool()
+happen outside of a conditional, even though that conditional will
+always bee satisfied.  This way coverity won't think we're setting fi
+to NULL and passing it to StrCaseCmp.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ fallback.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/fallback.c b/fallback.c
+index c875144..ba864ee 100644
+--- a/fallback.c
++++ b/fallback.c
+@@ -445,25 +445,32 @@ find_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname)
+ 		return EFI_SUCCESS;
+ 	}
+ 	FreePool(buffer);
++	buffer = NULL;
+ 
+ 	bs = 0;
+ 	do {
+ 		bs = 0;
+ 		rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, NULL);
+-		if (rc == EFI_BUFFER_TOO_SMALL) {
+-			buffer = AllocateZeroPool(bs);
+-			if (!buffer) {
+-				Print(L"Could not allocate memory\n");
+-				return EFI_OUT_OF_RESOURCES;
+-			}
++		if (EFI_ERROR(rc) && rc != EFI_BUFFER_TOO_SMALL) {
++			Print(L"Could not read \\EFI\\%s\\: %d\n", dirname, rc);
++			if (buffer)
++				FreePool(buffer);
++			return rc;
++		}
+ 
+-			rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, buffer);
++		buffer = AllocateZeroPool(bs);
++		if (!buffer) {
++			Print(L"Could not allocate memory\n");
++			return EFI_OUT_OF_RESOURCES;
+ 		}
++
++		rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, buffer);
+ 		if (EFI_ERROR(rc)) {
+ 			Print(L"Could not read \\EFI\\%s\\: %d\n", dirname, rc);
+ 			FreePool(buffer);
+ 			return rc;
+ 		}
++
+ 		if (bs == 0)
+ 			break;
+ 
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0017-Error-check-the-right-thing-in-get_variable_attr-whe.patch b/SOURCES/0017-Error-check-the-right-thing-in-get_variable_attr-whe.patch
new file mode 100644
index 0000000..c76d442
--- /dev/null
+++ b/SOURCES/0017-Error-check-the-right-thing-in-get_variable_attr-whe.patch
@@ -0,0 +1,27 @@
+From 293f28d1fe3921c5348c60948b4dedcef5042d5b Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 15 Nov 2013 10:55:37 -0500
+Subject: [PATCH 17/19] Error check the right thing in get_variable_attr() when
+ allocating.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ lib/variables.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/variables.c b/lib/variables.c
+index 81bd34d..3a9735e 100644
+--- a/lib/variables.c
++++ b/lib/variables.c
+@@ -224,7 +224,7 @@ get_variable_attr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
+ 		return efi_status;
+ 
+ 	*data = AllocateZeroPool(*len);
+-	if (!data)
++	if (!*data)
+ 		return EFI_OUT_OF_RESOURCES;
+ 	
+ 	efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0018-fallback-For-HD-device-paths-use-just-the-media-node.patch b/SOURCES/0018-fallback-For-HD-device-paths-use-just-the-media-node.patch
new file mode 100644
index 0000000..2d3ba26
--- /dev/null
+++ b/SOURCES/0018-fallback-For-HD-device-paths-use-just-the-media-node.patch
@@ -0,0 +1,219 @@
+From dfd6c73a212f8cf6b32ce74807de9a08a87f0b79 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 31 Jan 2014 10:30:24 -0500
+Subject: [PATCH 18/19] [fallback] For HD() device paths, use just the media
+ node and later.
+
+UEFI 2.x section 3.1.2 provides for "short-form device path", where the
+first element specified is a "hard drive media device path", so that you
+can move a disk around on different buses without invalidating your
+device path.  Fallback has not been using this option, though in most
+cases efibootmgr has.
+
+Note that we still keep the full device path, because LoadImage()
+isn't necessarily the layer where HD() works - one some systems BDS is
+responsible for resolving the full path and passes that to LoadImage()
+instead.  So we have to do LoadImage() with the full path.
+---
+ fallback.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 78 insertions(+), 25 deletions(-)
+
+diff --git a/fallback.c b/fallback.c
+index ba864ee..a12bb74 100644
+--- a/fallback.c
++++ b/fallback.c
+@@ -15,6 +15,27 @@
+ EFI_LOADED_IMAGE *this_image = NULL;
+ 
+ static EFI_STATUS
++FindSubDevicePath(EFI_DEVICE_PATH *In, UINT8 Type, UINT8 SubType,
++		  EFI_DEVICE_PATH **Out)
++{
++	EFI_DEVICE_PATH *dp = In;
++	if (!In || !Out)
++		return EFI_INVALID_PARAMETER;
++
++	for (dp = In; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
++		if (DevicePathType(dp) == Type &&
++				DevicePathSubType(dp) == SubType) {
++			*Out = DuplicateDevicePath(dp);
++			if (!*Out)
++				return EFI_OUT_OF_RESOURCES;
++			return EFI_SUCCESS;
++		}
++	}
++	*Out = NULL;
++	return EFI_NOT_FOUND;
++}
++
++static EFI_STATUS
+ get_file_size(EFI_FILE_HANDLE fh, UINTN *retsize)
+ {
+ 	EFI_STATUS rc;
+@@ -93,7 +114,9 @@ make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen)
+ {
+ 	UINT64 len;
+ 	
+-	len = StrLen(dirname) + StrLen(filename) + StrLen(L"\\EFI\\\\") + 2;
++	len = StrLen(L"\\EFI\\") + StrLen(dirname)
++	    + StrLen(L"\\") + StrLen(filename)
++	    + 2;
+ 
+ 	CHAR16 *fullpath = AllocateZeroPool(len*sizeof(CHAR16));
+ 	if (!fullpath) {
+@@ -119,7 +142,8 @@ VOID *first_new_option_args = NULL;
+ UINTN first_new_option_size = 0;
+ 
+ EFI_STATUS
+-add_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
++add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp,
++		CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
+ {
+ 	static int i = 0;
+ 	CHAR16 varname[] = L"Boot0000";
+@@ -136,24 +160,31 @@ add_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, CHAR16 *ar
+ 		void *var = LibGetVariable(varname, &global);
+ 		if (!var) {
+ 			int size = sizeof(UINT32) + sizeof (UINT16) +
+-				StrLen(label)*2 + 2 + DevicePathSize(dp) +
+-				StrLen(arguments) * 2 + 2;
++				StrLen(label)*2 + 2 + DevicePathSize(hddp) +
++				StrLen(arguments) * 2;
+ 
+ 			CHAR8 *data = AllocateZeroPool(size);
+ 			CHAR8 *cursor = data;
+ 			*(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
+ 			cursor += sizeof (UINT32);
+-			*(UINT16 *)cursor = DevicePathSize(dp);
++			*(UINT16 *)cursor = DevicePathSize(hddp);
+ 			cursor += sizeof (UINT16);
+ 			StrCpy((CHAR16 *)cursor, label);
+ 			cursor += StrLen(label)*2 + 2;
+-			CopyMem(cursor, dp, DevicePathSize(dp));
+-			cursor += DevicePathSize(dp);
++			CopyMem(cursor, hddp, DevicePathSize(hddp));
++			cursor += DevicePathSize(hddp);
+ 			StrCpy((CHAR16 *)cursor, arguments);
+ 
+ 			Print(L"Creating boot entry \"%s\" with label \"%s\" "
+ 					L"for file \"%s\"\n",
+ 				varname, label, filename);
++
++			if (!first_new_option) {
++				first_new_option = DuplicateDevicePath(fulldp);
++				first_new_option_args = arguments;
++				first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
++			}
++
+ 			rc = uefi_call_wrapper(RT->SetVariable, 5, varname,
+ 				&global, EFI_VARIABLE_NON_VOLATILE |
+ 					 EFI_VARIABLE_BOOTSERVICE_ACCESS |
+@@ -254,7 +285,10 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
+ 	if (EFI_ERROR(rc))
+ 		return rc;
+ 	
+-	EFI_DEVICE_PATH *dph = NULL, *dpf = NULL, *dp = NULL;
++	EFI_DEVICE_PATH *dph = NULL;
++	EFI_DEVICE_PATH *file = NULL;
++	EFI_DEVICE_PATH *full_device_path = NULL;
++	EFI_DEVICE_PATH *dp = NULL;
+ 	
+ 	dph = DevicePathFromHandle(this_image->DeviceHandle);
+ 	if (!dph) {
+@@ -262,19 +296,31 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
+ 		goto err;
+ 	}
+ 
+-	dpf = FileDevicePath(fh, fullpath);
+-	if (!dpf) {
++	file = FileDevicePath(fh, fullpath);
++	if (!file) {
+ 		rc = EFI_OUT_OF_RESOURCES;
+ 		goto err;
+ 	}
+ 
+-	dp = AppendDevicePath(dph, dpf);
+-	if (!dp) {
++	full_device_path = AppendDevicePath(dph, file);
++	if (!full_device_path) {
+ 		rc = EFI_OUT_OF_RESOURCES;
+ 		goto err;
+ 	}
+ 
++	rc = FindSubDevicePath(full_device_path,
++				MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, &dp);
++	if (EFI_ERROR(rc)) {
++		if (rc == EFI_NOT_FOUND) {
++			dp = full_device_path;
++		} else {
++			rc = EFI_OUT_OF_RESOURCES;
++			goto err;
++		}
++	}
++
+ #ifdef DEBUG_FALLBACK
++	{
+ 	UINTN s = DevicePathSize(dp);
+ 	int i;
+ 	UINT8 *dpv = (void *)dp;
+@@ -287,20 +333,16 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
+ 
+ 	CHAR16 *dps = DevicePathToStr(dp);
+ 	Print(L"device path: \"%s\"\n", dps);
+-#endif
+-	if (!first_new_option) {
+-		CHAR16 *dps = DevicePathToStr(dp);
+-		Print(L"device path: \"%s\"\n", dps);
+-		first_new_option = DuplicateDevicePath(dp);
+-		first_new_option_args = arguments;
+-		first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
+ 	}
++#endif
+ 
+-	add_boot_option(dp, fullpath, label, arguments);
++	add_boot_option(dp, full_device_path, fullpath, label, arguments);
+ 
+ err:
+-	if (dpf)
+-		FreePool(dpf);
++	if (file)
++		FreePool(file);
++	if (full_device_path)
++		FreePool(full_device_path);
+ 	if (dp)
+ 		FreePool(dp);
+ 	if (fullpath)
+@@ -629,8 +671,19 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
+ 			       first_new_option, NULL, 0,
+ 			       &image_handle);
+ 	if (EFI_ERROR(rc)) {
+-		Print(L"LoadImage failed: %d\n", rc);
+-		uefi_call_wrapper(BS->Stall, 1, 2000000);
++		CHAR16 *dps = DevicePathToStr(first_new_option);
++		UINTN s = DevicePathSize(first_new_option);
++		int i;
++		UINT8 *dpv = (void *)first_new_option;
++		Print(L"LoadImage failed: %d\nDevice path: \"%s\"\n", rc, dps);
++		for (i = 0; i < s; i++) {
++			if (i > 0 && i % 16 == 0)
++				Print(L"\n");
++			Print(L"%02x ", dpv[i]);
++		}
++		Print(L"\n");
++
++		uefi_call_wrapper(BS->Stall, 1, 500000000);
+ 		return rc;
+ 	}
+ 
+@@ -644,7 +697,7 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
+ 	rc = uefi_call_wrapper(BS->StartImage, 3, image_handle, NULL, NULL);
+ 	if (EFI_ERROR(rc)) {
+ 		Print(L"StartImage failed: %d\n", rc);
+-		uefi_call_wrapper(BS->Stall, 1, 2000000);
++		uefi_call_wrapper(BS->Stall, 1, 500000000);
+ 	}
+ 	return rc;
+ }
+-- 
+1.8.5.3
+
diff --git a/SOURCES/0019-fallback-Attempt-to-re-use-existing-entries-when-pos.patch b/SOURCES/0019-fallback-Attempt-to-re-use-existing-entries-when-pos.patch
new file mode 100644
index 0000000..86ab395
--- /dev/null
+++ b/SOURCES/0019-fallback-Attempt-to-re-use-existing-entries-when-pos.patch
@@ -0,0 +1,147 @@
+From 894a2738d6c843a7b51245fb92bb2f835901e613 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Fri, 31 Jan 2014 10:31:10 -0500
+Subject: [PATCH 19/19] [fallback] Attempt to re-use existing entries when
+ possible.
+
+Some firmwares seem to ignore our boot entries and put their fallback
+entries back on top.  Right now that results in a lot of boot entries
+for our stuff, a la https://bugzilla.redhat.com/show_bug.cgi?id=995834 .
+
+Instead of that happening, if we simply find existing entries that match
+the entry we would create and move them to the top of the boot order,
+the machine will continue to operate in failure mode (which we can't
+avoid), but at least we won't create thousands of extra entries.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ fallback.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 98 insertions(+), 1 deletion(-)
+
+diff --git a/fallback.c b/fallback.c
+index a12bb74..44638ec 100644
+--- a/fallback.c
++++ b/fallback.c
+@@ -226,6 +226,85 @@ add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp,
+ }
+ 
+ EFI_STATUS
++find_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label,
++		CHAR16 *arguments, UINT16 *optnum)
++{
++	int size = sizeof(UINT32) + sizeof (UINT16) +
++		StrLen(label)*2 + 2 + DevicePathSize(dp) +
++		StrLen(arguments) * 2 + 2;
++
++	CHAR8 *data = AllocateZeroPool(size);
++	if (!data)
++		return EFI_OUT_OF_RESOURCES;
++	CHAR8 *cursor = data;
++	*(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
++	cursor += sizeof (UINT32);
++	*(UINT16 *)cursor = DevicePathSize(dp);
++	cursor += sizeof (UINT16);
++	StrCpy((CHAR16 *)cursor, label);
++	cursor += StrLen(label)*2 + 2;
++	CopyMem(cursor, dp, DevicePathSize(dp));
++	cursor += DevicePathSize(dp);
++	StrCpy((CHAR16 *)cursor, arguments);
++
++	int i = 0;
++	CHAR16 varname[] = L"Boot0000";
++	CHAR16 hexmap[] = L"0123456789ABCDEF";
++	EFI_GUID global = EFI_GLOBAL_VARIABLE;
++	EFI_STATUS rc;
++
++	CHAR8 *candidate = AllocateZeroPool(size);
++	if (!candidate) {
++		FreePool(data);
++		return EFI_OUT_OF_RESOURCES;
++	}
++
++	for(i = 0; i < nbootorder && i < 0x10000; i++) {
++		varname[4] = hexmap[(bootorder[i] & 0xf000) >> 12];
++		varname[5] = hexmap[(bootorder[i] & 0x0f00) >> 8];
++		varname[6] = hexmap[(bootorder[i] & 0x00f0) >> 4];
++		varname[7] = hexmap[(bootorder[i] & 0x000f) >> 0];
++
++		UINTN candidate_size = size;
++		rc = uefi_call_wrapper(RT->GetVariable, 5, varname, &global,
++					NULL, &candidate_size, candidate);
++		if (EFI_ERROR(rc))
++			continue;
++
++		if (candidate_size != size)
++			continue;
++
++		if (CompareMem(candidate, data, size))
++			continue;
++
++		/* at this point, we have duplicate data. */
++		*optnum = i;
++		FreePool(candidate);
++		FreePool(data);
++		return EFI_SUCCESS;
++	}
++	FreePool(candidate);
++	FreePool(data);
++	return EFI_NOT_FOUND;
++}
++
++EFI_STATUS
++set_boot_order(void)
++{
++	CHAR16 *oldbootorder;
++	UINTN size;
++	EFI_GUID global = EFI_GLOBAL_VARIABLE;
++
++	oldbootorder = LibGetVariableAndSize(L"BootOrder", &global, &size);
++	if (oldbootorder) {
++		nbootorder = size / sizeof (CHAR16);
++		bootorder = oldbootorder;
++	}
++	return EFI_SUCCESS;
++
++}
++
++EFI_STATUS
+ update_boot_order(void)
+ {
+ 	CHAR16 *oldbootorder;
+@@ -336,7 +415,23 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
+ 	}
+ #endif
+ 
+-	add_boot_option(dp, full_device_path, fullpath, label, arguments);
++	UINT16 option;
++	rc = find_boot_option(dp, fullpath, label, arguments, &option);
++	if (EFI_ERROR(rc)) {
++		add_boot_option(dp, full_device_path, fullpath, label, arguments);
++	} else if (option != 0) {
++		CHAR16 *newbootorder;
++		newbootorder = AllocateZeroPool(sizeof (CHAR16) * nbootorder);
++		if (!newbootorder)
++			return EFI_OUT_OF_RESOURCES;
++
++		newbootorder[0] = bootorder[option];
++		CopyMem(newbootorder + 1, bootorder, sizeof (CHAR16) * option);
++		CopyMem(newbootorder + option + 1, bootorder + option + 1,
++			sizeof (CHAR16) * (nbootorder - option - 1));
++		FreePool(bootorder);
++		bootorder = newbootorder;
++	}
+ 
+ err:
+ 	if (file)
+@@ -717,6 +812,8 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
+ 
+ 	Print(L"System BootOrder not found.  Initializing defaults.\n");
+ 
++	set_boot_order();
++
+ 	rc = find_boot_options(this_image->DeviceHandle);
+ 	if (EFI_ERROR(rc)) {
+ 		Print(L"Error: could not find boot options: %d\n", rc);
+-- 
+1.8.5.3
+
diff --git a/SPECS/shim.spec b/SPECS/shim.spec
index 1867183..4ba9aa6 100644
--- a/SPECS/shim.spec
+++ b/SPECS/shim.spec
@@ -1,6 +1,6 @@
 Name:           shim
 Version:        0.7
-Release:        4%{?dist}
+Release:        5%{?dist}
 Summary:        First-stage UEFI bootloader
 
 License:        BSD
@@ -10,18 +10,34 @@ Source1:	securebootca.cer
 
 # incorporate mokutil for packaging simplicity
 %global mokutilver 0.2.0
-Source2:	https://github.com/lcp/mokutil/archive/mokutil-%{mokutilver}.tar.bz2
+Source2:	https://github.com/lcp/mokutil/archive/mokutil-%{mokutilver}.tar.gz
 
 # currently here's what's in our dbx:
 # nothing.
 #Source3:	dbx.esl
-%global lockdownver 0.3
-Source4:	https://github.com/vathpela/lockdown/archive/%{lockdownver}.tar.gz
-Source5:	DB.auth
-Source6:	KEK.auth
-Source7:	PK.auth
-Patch0000:	0001-Fix-path-generation-for-Dhcpv4-bootloader.patch
-Patch0002:	0001-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch
+Patch0001: 0001-fix-verify_mok.patch
+Patch0002: 0002-shim.c-Add-support-for-hashing-relocation-of-32-bit-.patch
+Patch0003: 0003-netboot.h-fix-build-error-on-32-bit-systems.patch
+Patch0004: 0004-properly-compile-OpenSSL-in-32-bit-mode.patch
+Patch0005: 0005-fallback.c-fix-32-bit-compilation.patch
+Patch0006: 0006-fix-fallback.so-build-dependency.patch
+Patch0007: 0007-propagate-some-path-variables.patch
+Patch0008: 0008-allow-32-bit-compilation-with-64-bit-compiler.patch
+Patch0009: 0009-shim-improve-error-messages.patch
+Patch0010: 0010-Clarify-meaning-of-insecure_mode.patch
+Patch0011: 0011-Don-t-hook-system-services-if-shim-has-no-built-in-k.patch
+Patch0012: 0012-Fix-path-generation-for-Dhcpv4-bootloader.patch
+Patch0013: 0013-Lengths-that-might-be-1-can-t-be-unsigned-Peter.patch
+Patch0014: 0014-Fix-wrong-sizeof.patch
+Patch0015: 0015-Initialize-entries-before-we-pass-it-to-another-func.patch
+Patch0016: 0016-Rewrite-directory-traversal-allocation-path-so-cover.patch
+Patch0017: 0017-Error-check-the-right-thing-in-get_variable_attr-whe.patch
+Patch0018: 0018-fallback-For-HD-device-paths-use-just-the-media-node.patch
+Patch0019: 0019-fallback-Attempt-to-re-use-existing-entries-when-pos.patch
+Patch0020: 0001-Add-a-preliminary-test-plan.patch
+Patch0021: 0002-Fix-a-part-of-the-test-plan-that-was-out-of-order.patch
+Patch0022: 0003-Allow-fallback-to-use-the-system-s-LoadImage-StartIm.patch
+Patch0023: 0001-Actually-reflect-the-upstream-commit-this-patchset-g.patch
 
 BuildRequires: git openssl-devel openssl
 BuildRequires: pesign >= 0.106-1
@@ -30,6 +46,9 @@ BuildRequires: gnu-efi = 3.0u, gnu-efi-devel = 3.0u
 # for xxd
 BuildRequires: vim-common
 
+# for mokutil's configure
+BuildRequires: autoconf automake
+
 # Shim uses OpenSSL, but cannot use the system copy as the UEFI ABI is not
 # compatible with SysV (there's no red zone under UEFI) and there isn't a
 # POSIX-style C library.
@@ -69,7 +88,6 @@ Utilities for managing the "Machine's Own Keys" list.
 %prep
 %setup -q
 %setup -q -a 2 -D -T
-%setup -q -a 4 -D -T
 
 git init
 git config user.email "shim-owner@fedoraproject.org"
@@ -86,14 +104,9 @@ fi
 # MAKEFLAGS="$MAKEFLAGS VENDOR_DBX_FILE=%{SOURCE3}"
 make 'DEFAULT_LOADER=\\\\grubx64.efi' ${MAKEFLAGS} shim.efi MokManager.efi fallback.efi
 cd mokutil-%{mokutilver}
+./autogen.sh
 %configure
 make %{?_smp_mflags}
-cd ../lockdown-%{lockdownver}/
-cp %{SOURCE5} %{SOURCE6} %{SOURCE7} ./
-xxd -i DB.auth > DB.h
-xxd -i KEK.auth > KEK.h
-xxd -i PK.auth > PK.h
-make DB_FILE=%{SOURCE5} KEK_FILE=%{SOURCE6} PK_FILE=%{SOURCE7} lockdown.efi
 
 %install
 rm -rf $RPM_BUILD_ROOT
@@ -105,8 +118,6 @@ install -m 0644 fallback.efi $RPM_BUILD_ROOT%{_datadir}/shim/fallback.efi
 install -m 0644 MokManager.efi $RPM_BUILD_ROOT%{_datadir}/shim/MokManager.efi
 cd mokutil-%{mokutilver}
 make PREFIX=%{_prefix} LIBDIR=%{_libdir} DESTDIR=%{buildroot} install
-cd ../lockdown-%{lockdownver}
-install -m 0644 lockdown.efi $RPM_BUILD_ROOT%{_datadir}/shim/lockdown.efi
 
 %files -n shim-unsigned
 %doc
@@ -118,6 +129,11 @@ install -m 0644 lockdown.efi $RPM_BUILD_ROOT%{_datadir}/shim/lockdown.efi
 /usr/share/man/man1/mokutil.1.gz
 
 %changelog
+* Tue Feb 18 2014 Peter Jones <pjones@redhat.com> - 0.7-5
+- Update for production signing
+  Resolves: rhbz#1064424
+  Related: rhbz#1064449
+
 * Thu Nov 21 2013 Peter Jones <pjones@redhat.com> - 0.7-4
 - Make dhcpv4 paths work better when netbooting.
   Resolves: rhbz#1032583