Control: tags 823751 + patch
Control: tags 823751 + pending
Control: tags 900889 + patch
Control: tags 900889 + pending
Control: tags 912306 + patch
Control: tags 912306 + pending


Dear maintainer,

I've prepared an NMU for efitools (versioned as 1.8.1-1) and
uploaded it to DELAYED/7. Please feel free to tell me if I
should delay it longer.

Regards.

diff -Nru efitools-1.4.2/cert-to-efi-hash-list.c 
efitools-1.8.1/cert-to-efi-hash-list.c
--- efitools-1.4.2/cert-to-efi-hash-list.c      1970-01-01 01:00:00.000000000 
+0100
+++ efitools-1.8.1/cert-to-efi-hash-list.c      2018-02-21 03:53:05.000000000 
+0000
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2012 <[email protected]>
+ *
+ * see COPYING file
+ */
+
+
+#include <stdint.h>
+#define _XOPEN_SOURCE
+#include <efi.h>
+#ifdef CONFIG_arm
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <wchar.h>
+
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+
+#include <guid.h>
+#include <variables.h>
+#include <version.h>
+
+static void
+usage(const char *progname)
+{
+       printf("Usage: %s [-g <guid>][-t <timestamp>][-s <hash>] <crt file> 
<efi sig list file>\n", progname);
+}
+
+static void
+help(const char * progname)
+{
+       usage(progname);
+       printf("Take an input X509 certificate (in PEM format) and convert it 
to an EFI\n"
+              "signature hash list file containing only that single 
certificate\n\n"
+              "Options:\n"
+              "\t-g <guid>        Use <guid> as the owner of the signature. If 
this is not\n"
+              "\t                 supplied, an all zero guid will be used\n"
+              "\t-s <hash>        Use SHA<hash> hash algorithm (256, 384, 
512)\n"
+              "\t-t <timestamp>   Time of Revocation for hash signature\n"
+              "                   Set to 0 if not specified meaning revoke\n"
+              "                   for all time.\n"
+              );
+       
+}
+
+int
+main(int argc, char *argv[])
+{
+       char *certfile, *efifile;
+       const char *progname = argv[0];
+       EFI_GUID owner = { 0 };
+       int sha = 256;
+       EFI_TIME timestamp;
+       char *timestampstr = NULL;
+
+       memset(&timestamp, 0, sizeof(timestamp));
+
+       while (argc > 1) {
+               if (strcmp("--version", argv[1]) == 0) {
+                       version(progname);
+                       exit(0);
+               } else if (strcmp("--help", argv[1]) == 0) {
+                       help(progname);
+                       exit(0);
+               } else if (strcmp("-g", argv[1]) == 0) {
+                       str_to_guid(argv[2], &owner);
+                       argv += 2;
+                       argc -= 2;
+               } else if (strcmp("-s", argv[1]) == 0) {
+                       sha = atoi(argv[2]);
+                       argv += 2;
+                       argc -= 2;
+               } else if (strcmp("-t", argv[1]) == 0) {
+                       timestampstr = argv[2];
+                       argv += 2;
+                       argc -= 2;
+               } else {
+                       break;
+               }
+       }
+         
+
+       if (argc != 3) {
+               usage(progname);
+               exit(1);
+       }
+
+       if (sha != 256 && sha != 384 && sha != 512) {
+               fprintf(stderr, "Supported algorithms are sha256, sha384 or 
sha512\n");
+               exit(1);
+       }
+
+       if (timestampstr) {
+               struct tm tms;
+               strptime(timestampstr, "%Y-%m-%d %H:%M:%S", &tms);
+               /* timestamp.Year is from 0 not 1900 as tm year is */
+               tms.tm_year += 1900;
+               timestamp.Year = tms.tm_year;
+               timestamp.Month = tms.tm_mon + 1;
+               timestamp.Day = tms.tm_mday;
+               timestamp.Hour = tms.tm_hour;
+               timestamp.Minute = tms.tm_min;
+               timestamp.Second = tms.tm_sec;
+       }
+       certfile = argv[1];
+       efifile = argv[2];
+
+       printf("TimeOfRevocation is %d-%d-%d %02d:%02d:%02d\n", timestamp.Year,
+              timestamp.Month, timestamp.Day, timestamp.Hour, timestamp.Minute,
+              timestamp.Second);
+
+        ERR_load_crypto_strings();
+        OpenSSL_add_all_digests();
+        OpenSSL_add_all_ciphers();
+       /* here we may get highly unlikely failures or we'll get a
+        * complaint about FIPS signatures (usually becuase the FIPS
+        * module isn't present).  In either case ignore the errors
+        * (malloc will cause other failures out lower down */
+       ERR_clear_error();
+
+        BIO *cert_bio = BIO_new_file(certfile, "r");
+        X509 *cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL);
+       unsigned char *cert_buf = NULL;
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+       int cert_len = i2d_X509_CINF(cert->cert_info, &cert_buf);
+#else
+       int cert_len = i2d_re_X509_tbs(cert, &cert_buf);
+#endif
+       ERR_print_errors_fp(stdout);
+
+       int len, digest_len, time_offset;
+       EFI_GUID guid;
+       const EVP_MD *md;
+
+       if (sha == 256) {
+               len = sizeof(EFI_CERT_X509_SHA256);
+               digest_len = sizeof(EFI_SHA256_HASH);
+               guid = EFI_CERT_X509_SHA256_GUID;
+               md = EVP_get_digestbyname("SHA256");
+               time_offset = OFFSET_OF(EFI_CERT_X509_SHA256, TimeOfRevocation);
+       } else if (sha == 384) {
+               len = sizeof(EFI_CERT_X509_SHA384);
+               digest_len = sizeof(EFI_SHA384_HASH);
+               guid = EFI_CERT_X509_SHA384_GUID;
+               md = EVP_get_digestbyname("SHA384");
+               time_offset = OFFSET_OF(EFI_CERT_X509_SHA384, TimeOfRevocation);
+       } else if (sha == 512) {
+               len = sizeof(EFI_CERT_X509_SHA512);
+               digest_len = sizeof(EFI_SHA512_HASH);
+               guid = EFI_CERT_X509_SHA512_GUID;
+               md = EVP_get_digestbyname("SHA512");
+               time_offset = OFFSET_OF(EFI_CERT_X509_SHA512, TimeOfRevocation);
+       } else {
+               fprintf(stderr, "assertion failure sha%d\n", sha);
+               exit(1);
+       }
+       len += sizeof(EFI_SIGNATURE_LIST) + OFFSET_OF(EFI_SIGNATURE_DATA, 
SignatureData);
+       unsigned char *buf = malloc(len);
+       EFI_SIGNATURE_LIST *SigList = (EFI_SIGNATURE_LIST *)buf;
+       SigList->SignatureListSize = len;
+       SigList->SignatureSize = (UINT32)(len - sizeof(EFI_SIGNATURE_LIST));
+       SigList->SignatureHeaderSize = 0;
+       SigList->SignatureType = guid;
+
+       EFI_SIGNATURE_DATA *SigData = (void *)buf + sizeof(EFI_SIGNATURE_LIST);
+       SigData->SignatureOwner = owner;
+
+       /* point buf at hash buffer */
+       unsigned char *digest = (void *)SigData + OFFSET_OF(EFI_SIGNATURE_DATA, 
SignatureData);
+
+       EFI_TIME *TimeOfRevocation = (void *)digest + time_offset;
+       *TimeOfRevocation = timestamp;
+
+       EVP_MD_CTX *ctx;
+       unsigned int md_len;
+       ctx = EVP_MD_CTX_create();
+        EVP_DigestInit_ex(ctx, md, NULL);
+        EVP_DigestUpdate(ctx, cert_buf, cert_len);
+        EVP_DigestFinal_ex(ctx, digest, &md_len);
+        EVP_MD_CTX_destroy(ctx);
+       if (digest_len != md_len) {
+               fprintf(stderr, "Digest assertion failure sha%d %d != %d\n",
+                       sha, digest_len, md_len);
+               exit(1);
+       }
+
+       FILE *f = fopen(efifile, "w");
+       if (!f) {
+               fprintf(stderr, "failed to open efi file %s: ", efifile);
+               perror("");
+               exit(1);
+       }
+       if (fwrite(buf, 1, len, f) != len) {
+               perror("Did not write enough bytes to efi file");
+               exit(1);
+       }
+
+       return 0;
+}
diff -Nru efitools-1.4.2/cert-to-efi-sig-list.c 
efitools-1.8.1/cert-to-efi-sig-list.c
--- efitools-1.4.2/cert-to-efi-sig-list.c       2013-09-19 14:14:24.000000000 
+0100
+++ efitools-1.8.1/cert-to-efi-sig-list.c       2018-02-21 03:53:05.000000000 
+0000
@@ -8,6 +8,12 @@
 #include <stdint.h>
 #define __STDC_VERSION__ 199901L
 #include <efi.h>
+#ifdef CONFIG_arm
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -75,6 +81,11 @@
         ERR_load_crypto_strings();
         OpenSSL_add_all_digests();
         OpenSSL_add_all_ciphers();
+       /* here we may get highly unlikely failures or we'll get a
+        * complaint about FIPS signatures (usually becuase the FIPS
+        * module isn't present).  In either case ignore the errors
+        * (malloc will cause other failures out lower down */
+       ERR_clear_error();
 
         BIO *cert_bio = BIO_new_file(certfile, "r");
         X509 *cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL);
diff -Nru efitools-1.4.2/debian/changelog efitools-1.8.1/debian/changelog
--- efitools-1.4.2/debian/changelog     2016-04-26 09:21:41.000000000 +0100
+++ efitools-1.8.1/debian/changelog     2018-06-01 10:10:50.000000000 +0100
@@ -1,3 +1,12 @@
+efitools (1.8.1-1) unstable; urgency=medium
+
+  * Package salvaged (Closes: #912306)
+  * New upstream release (Closes: #823751, #900889)
+  * Remove makefiles-clean patch, applied upstream
+  * Update makefile-enable-harden-local-files patch
+
+ -- Arnaud Rebillout <[email protected]>  Fri, 01 Jun 2018 
16:10:50 +0700
+
 efitools (1.4.2-2) unstable; urgency=medium
 
   * Add missing build-depends (Closes: #822262)
diff -Nru efitools-1.4.2/debian/control efitools-1.8.1/debian/control
--- efitools-1.4.2/debian/control       2016-04-26 09:20:56.000000000 +0100
+++ efitools-1.8.1/debian/control       2018-06-01 10:10:50.000000000 +0100
@@ -1,7 +1,8 @@
 Source: efitools
 Section: admin
 Priority: optional
-Maintainer: Pierre Chifflier <[email protected]>
+Maintainer: Debian UEFI Maintainers <[email protected]>
+Uploaders: Arnaud Rebillout <[email protected]>
 Build-Depends: debhelper (>= 9.0.0),
     libfile-slurp-perl,
     help2man,
@@ -11,8 +12,8 @@
     sbsigntool
 Standards-Version: 3.9.8
 Homepage: http://blog.hansenpartnership.com/uefi-secure-boot/
-#Vcs-Git: git://git.debian.org/collab-maint/efitools.git
-#Vcs-Browser: http://git.debian.org/?p=collab-maint/efitools.git;a=summary
+Vcs-Git: https://salsa.debian.org/efi-team/efitools.git
+Vcs-Browser: https://salsa.debian.org/efi-team/efitools
 
 Package: efitools
 Architecture: any
diff -Nru 
efitools-1.4.2/debian/patches/makefile-enable-harden-local-files.patch 
efitools-1.8.1/debian/patches/makefile-enable-harden-local-files.patch
--- efitools-1.4.2/debian/patches/makefile-enable-harden-local-files.patch      
2016-04-19 08:43:50.000000000 +0100
+++ efitools-1.8.1/debian/patches/makefile-enable-harden-local-files.patch      
2018-06-01 10:10:50.000000000 +0100
@@ -1,10 +1,8 @@
-Index: efitools/Makefile
-===================================================================
---- efitools.orig/Makefile
-+++ efitools/Makefile
-@@ -3,6 +3,9 @@ EFIFILES = HelloWorld.efi LockDown.efi L
- BINARIES = cert-to-efi-sig-list sig-list-to-certs sign-efi-sig-list \
-       hash-to-efi-sig-list efi-readvar efi-updatevar
+--- a/Makefile
++++ b/Makefile
+@@ -21,6 +21,9 @@
+ KEYBLACKLISTAUTH = $(ALLKEYS:=-blacklist.auth)
+ KEYHASHBLACKLISTAUTH = $(ALLKEYS:=-hash-blacklist.auth)
  
 +OLD_CFLAGS:=$(CFLAGS)
 +OLD_LDFLAGS:=$(LDFLAGS)
@@ -12,36 +10,44 @@
  export TOPDIR := $(shell pwd)/
  
  include Make.rules
-@@ -76,25 +79,25 @@ PreLoader.so: lib/lib-efi.a
- HelloWorld.so: lib/lib-efi.a
+@@ -88,31 +91,31 @@
+ ShimReplace.so: lib/lib-efi.a
  
  cert-to-efi-sig-list: cert-to-efi-sig-list.o lib/lib.a
--      $(CC) -o $@ $< -lcrypto lib/lib.a
-+      $(CC) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto 
lib/lib.a
  
  sig-list-to-certs: sig-list-to-certs.o lib/lib.a
--      $(CC) -o $@ $< -lcrypto lib/lib.a
-+      $(CC) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto 
lib/lib.a
  
  sign-efi-sig-list: sign-efi-sig-list.o lib/lib.a
--      $(CC) -o $@ $< -lcrypto lib/lib.a
-+      $(CC) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto 
lib/lib.a
  
  hash-to-efi-sig-list: hash-to-efi-sig-list.o lib/lib.a
--      $(CC) -o $@ $< lib/lib.a
-+      $(CC) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) lib/lib.a
+ 
+ cert-to-efi-hash-list: cert-to-efi-hash-list.o lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto 
lib/lib.a
  
  efi-keytool: efi-keytool.o lib/lib.a
--      $(CC) -o $@ $< lib/lib.a
-+      $(CC) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) lib/lib.a
  
  efi-readvar: efi-readvar.o lib/lib.a
--      $(CC) -o $@ $< -lcrypto lib/lib.a
-+      $(CC) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto 
lib/lib.a
  
  efi-updatevar: efi-updatevar.o lib/lib.a
--      $(CC) -o $@ $< -lcrypto lib/lib.a
-+      $(CC) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) -lcrypto 
lib/lib.a
+ 
+ flash-var: flash-var.o lib/lib.a
+-      $(CC) $(ARCH3264) -o $@ $< lib/lib.a
++      $(CC) $(ARCH3264) -o $@ $< $(OLD_CFLAGS) $(OLD_LDFLAGS) lib/lib.a
  
  clean:
        rm -f PK.* KEK.* DB.* $(EFIFILES) $(EFISIGNED) $(BINARIES) *.o *.so
diff -Nru efitools-1.4.2/debian/patches/makefiles-fix-clean.patch 
efitools-1.8.1/debian/patches/makefiles-fix-clean.patch
--- efitools-1.4.2/debian/patches/makefiles-fix-clean.patch     2016-04-19 
07:29:58.000000000 +0100
+++ efitools-1.8.1/debian/patches/makefiles-fix-clean.patch     1970-01-01 
01:00:00.000000000 +0100
@@ -1,41 +0,0 @@
-Index: efitools/lib/Makefile
-===================================================================
---- efitools.orig/lib/Makefile
-+++ efitools/lib/Makefile
-@@ -9,6 +9,9 @@ lib.a: $(LIBFILES)
- lib-efi.a: $(EFILIBFILES)
- 
- clean:
-+      $(MAKE) -C asn1 clean
-       rm -f lib.a
-       rm -f $(LIBFILES)
-+      rm -f lib-efi.a
-+      rm -f $(EFILIBFILES)
- 
-Index: efitools/lib/asn1/Makefile
-===================================================================
---- efitools.orig/lib/asn1/Makefile
-+++ efitools/lib/asn1/Makefile
-@@ -12,3 +12,9 @@ test.o: test.c ../../include/x509.h
- 
- test: test.o libasn1.a
-       $(CC) -o $@ $< libasn1.a
-+
-+clean:
-+      rm -f libasn1.a
-+      rm -f $(LIBFILES)
-+      rm -f libasn1-efi.a
-+      rm -f $(EFILIBFILES)
-Index: efitools/Makefile
-===================================================================
---- efitools.orig/Makefile
-+++ efitools/Makefile
-@@ -100,6 +100,8 @@ clean:
-       rm -f PK.* KEK.* DB.* $(EFIFILES) $(EFISIGNED) $(BINARIES) *.o *.so
-       rm -f doc/*.1
-       $(MAKE) -C lib clean
-+      rm -f *.auth *.esl
-+      rm -f HashTool.hash hashlist.h
- 
- FORCE:
- 
diff -Nru efitools-1.4.2/debian/patches/series 
efitools-1.8.1/debian/patches/series
--- efitools-1.4.2/debian/patches/series        2016-04-19 08:40:48.000000000 
+0100
+++ efitools-1.8.1/debian/patches/series        2018-06-01 10:10:50.000000000 
+0100
@@ -1,2 +1 @@
-makefiles-fix-clean.patch
 makefile-enable-harden-local-files.patch
diff -Nru efitools-1.4.2/doc/cert-to-efi-hash-list.1.in 
efitools-1.8.1/doc/cert-to-efi-hash-list.1.in
--- efitools-1.4.2/doc/cert-to-efi-hash-list.1.in       1970-01-01 
01:00:00.000000000 +0100
+++ efitools-1.8.1/doc/cert-to-efi-hash-list.1.in       2018-02-21 
03:53:05.000000000 +0000
@@ -0,0 +1,30 @@
+[name]
+cert-to-efi-hash-list - tool for converting openssl certificates to EFI 
signature hash revocation lists
+
+[examples]
+
+To take a standard X509 certificate in PEM format and
+produce an output EFI signature list file, simply do
+
+cert-to-efi-hash-list PK.crt PK.esl
+
+Note that the format of EFI signature list files is such
+that they can simply be concatenated to produce a file with
+multiple signatures:
+
+cat PK1.esl PK2.esl > PK.esl
+
+If your platform has a setup mode key manipulation ability,
+the keys will often only be displayed by GUID, so using the
+-g option to give your keys recognisable GUIDs will be
+useful if you plan to manage lots of keys.
+
+[see also]
+
+sign-efi-sig-list(1) for details on how to create an
+authenticated update to EFI secure variables when the EFI
+system is in user mode.
+
+[note]
+
+Signature revocation hashes are only implemented in UEFI 2.4 and up
diff -Nru efitools-1.4.2/efi-updatevar.c efitools-1.8.1/efi-updatevar.c
--- efitools-1.4.2/efi-updatevar.c      2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/efi-updatevar.c      2018-02-21 03:53:05.000000000 +0000
@@ -328,7 +328,7 @@
                /* FIXME: currently timestamp is one year into future because of
                 * the way we set up the secure environment  */
                timestamp.Year = tm->tm_year + 1900 + 1;
-               timestamp.Month = tm->tm_mon;
+               timestamp.Month = tm->tm_mon + 1;
                timestamp.Day = tm->tm_mday;
                timestamp.Hour = tm->tm_hour;
                timestamp.Minute = tm->tm_min;
diff -Nru efitools-1.4.2/elf_x86_64_efi.lds efitools-1.8.1/elf_x86_64_efi.lds
--- efitools-1.4.2/elf_x86_64_efi.lds   2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/elf_x86_64_efi.lds   1970-01-01 01:00:00.000000000 +0100
@@ -1,59 +0,0 @@
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(_start)
-SECTIONS
-{
-  . = 0;
-  ImageBase = .;
-  .hash : { *(.hash) } /* this MUST come first! */
-  . = ALIGN(4096);
-  .eh_frame : 
-  { 
-    *(.eh_frame)
-  }
-  . = ALIGN(4096);
-  .text :
-  {
-   *(.text)
-  }
-  . = ALIGN(4096);
-  .reloc :
-  {
-   *(.reloc)
-  }
-  . = ALIGN(4096);
-  .data :
-  {
-   *(.rodata*)
-   *(.got.plt)
-   *(.got)
-   *(.data*)
-   *(.sdata)
-   /* the EFI loader doesn't seem to like a .bss section, so we stick
-      it all into .data: */
-   *(.sbss)
-   *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-   *(.rel.local)
-  }
-  . = ALIGN(4096);
-  .dynamic  : { *(.dynamic) }
-  . = ALIGN(4096);
-  .rela :
-  {
-    *(.rela.data*)
-    *(.rela.got)
-    *(.rela.stab)
-  }
-  . = ALIGN(4096);
-  .dynsym   : { *(.dynsym) }
-  . = ALIGN(4096);
-  .dynstr   : { *(.dynstr) }
-  . = ALIGN(4096);
-  .ignored.reloc :
-  {
-    *(.rela.reloc)
-  }
-}
diff -Nru efitools-1.4.2/flash-var.c efitools-1.8.1/flash-var.c
--- efitools-1.4.2/flash-var.c  1970-01-01 01:00:00.000000000 +0100
+++ efitools-1.8.1/flash-var.c  2018-02-21 03:53:05.000000000 +0000
@@ -0,0 +1,209 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define __STDC_VERSION__ 199901L
+#include <efi.h>
+
+#include <version.h>
+#include <guid.h>
+#include "efiauthenticated.h"
+#include "variableformat.h"
+
+static void
+usage(const char *progname)
+{
+       printf("Usage: %s: [-l] [-g <owner guid>] [-t <timestamp>] <flashfile> 
<var> <varcontentfile>\n", progname);
+}
+
+static void
+help(const char *progname)
+{
+       usage(progname);
+       printf("Poke a variable definition into a flash file\n\n"
+              "Options:\n"
+              "\t-g <owner guid>      Variable owner GUID\n"
+              "\t-t <timestamp>       Timestamp for the authenticated 
variable\n"
+              "\t-l                    List current flash variables\n"
+              );
+}
+
+int
+main(int argc, char *argv[])
+{
+       char *progname = argv[0], *buf, *vardata, *timestampstr = NULL;
+       uint32_t attributes = EFI_VARIABLE_NON_VOLATILE
+               | EFI_VARIABLE_RUNTIME_ACCESS
+               | EFI_VARIABLE_BOOTSERVICE_ACCESS
+               | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+       int flashfile, varfile, i, offset, varlen, varfilesize, listvars = 0;
+       const int chunk = 8;
+       wchar_t var[128];
+       struct stat st;
+       EFI_GUID *owner = NULL, guid;
+       EFI_TIME timestamp;
+
+       while (argc > 1 && argv[1][0] == '-') {
+               if (strcmp("--version", argv[1]) == 0) {
+                       version(progname);
+                       exit(0);
+               } else if (strcmp("--help", argv[1]) == 0) {
+                       help(progname);
+                       exit(0);
+               } else if (strcmp(argv[1], "-g") == 0) {
+                       if (str_to_guid(argv[2], &guid)) {
+                               fprintf(stderr, "Invalid GUID %s\n", argv[2]);
+                               exit(1);
+                       }
+                       owner = &guid;
+                       argv += 2;
+                       argc -= 2;
+               } else if (strcmp("-t", argv[1]) == 0) {
+                       timestampstr = argv[2];
+                       argv += 2;
+                       argc -= 2;
+               } else if (strcmp("-l", argv[1]) == 0) {
+                       listvars = 1;
+                       argv += 1;
+                       argc -= 1;
+               } else {
+                       /* unrecognised option */
+                       break;
+               }
+       }
+
+       if ((argc != 4 && !listvars) || (argc != 2 && listvars)) {
+               usage(progname);
+               exit(1);
+       }
+
+       /* copy to wchar16_t including trailing zero */
+       for (i = 0; i < strlen(argv[2]) + 1; i++)
+               var[i] = argv[2][i];
+       varlen = i*2;           /* size of storage including zero */
+
+       if (!owner)
+               owner = get_owner_guid(argv[2]);
+       if (!owner) {
+               fprintf(stderr, "variable %s has no defined guid, one must be 
specified\n", argv[2]);
+               exit(1);
+       }
+
+
+       memset(&timestamp, 0, sizeof(timestamp));
+       time_t t;
+       struct tm *tm, tms;
+
+       memset(&tms, 0, sizeof(tms));
+
+
+       if (timestampstr) {
+               strptime(timestampstr, "%Y-%m-%d %H:%M:%S", &tms);
+               tm = &tms;
+       } else {
+               time(&t);
+               tm = localtime(&t);
+       }
+
+       /* timestamp.Year is from 0 not 1900 as tm year is */
+       timestamp.Year = tm->tm_year + 1900;
+       /* timestamp Month is 1-12 not 0-11 as tm_mon is */
+       timestamp.Month = tm->tm_mon + 1;
+       timestamp.Day = tm->tm_mday;
+       timestamp.Hour = tm->tm_hour;
+       timestamp.Minute = tm->tm_min;
+       timestamp.Second = tm->tm_sec;
+
+       printf("Timestamp is %d-%d-%d %02d:%02d:%02d\n", timestamp.Year,
+              timestamp.Month, timestamp.Day, timestamp.Hour, timestamp.Minute,
+              timestamp.Second);
+
+       flashfile = open(argv[1], O_RDWR);
+       if (flashfile < 0) {
+               fprintf(stderr, "Failed to read file %s:", argv[1]);
+               perror("");
+       }
+
+       varfile = open(argv[3], O_RDONLY);
+       if (varfile < 0) {
+               fprintf(stderr, "Failed to read file %s:", argv[1]);
+               perror("");
+       }
+       fstat(varfile, &st);
+       varfilesize = st.st_size;
+
+       vardata = malloc(varfilesize);
+       if (read(varfile, vardata, varfilesize) != varfilesize) {
+               perror("Failed to read variable file");
+               exit(1);
+       }
+       close(varfile);
+
+       buf = malloc(sizeof(EFI_GUID));
+
+       for (i = 0; ; i += chunk) {
+               lseek(flashfile, i, SEEK_SET);
+               if (read(flashfile, buf, sizeof(EFI_GUID)) != sizeof(EFI_GUID))
+                       goto eof;
+               if (memcmp(buf, &SECURE_VARIABLE_GUID, sizeof(EFI_GUID)) == 0)
+                       break;
+       }   
+       offset = i;
+       printf("Variable header found at offset 0x%x\n", offset);
+       lseek(flashfile, offset, SEEK_SET);
+       free(buf);
+       buf = malloc(sizeof(VARIABLE_STORE_HEADER));
+       read(flashfile, buf, sizeof(VARIABLE_STORE_HEADER));
+
+       VARIABLE_STORE_HEADER *vsh = (VARIABLE_STORE_HEADER *)buf;
+       if (vsh->Format != VARIABLE_STORE_FORMATTED &&
+           vsh->State != VARIABLE_STORE_HEALTHY) {
+               fprintf(stderr, "Variable store header is corrupt\n");
+               exit(1);
+       }
+       UINT32 size = vsh->Size;
+       free(buf);
+       buf = malloc(size);
+       lseek(flashfile, offset, SEEK_SET);
+       read(flashfile, buf, size);
+       vsh = (VARIABLE_STORE_HEADER *)buf;
+       printf("Variable Store Size = 0x%x\n", vsh->Size);
+
+       VARIABLE_HEADER *vh = (void *)HEADER_ALIGN(vsh + 1);
+       printf("variables begin at 0x%x\n", (int)((char *)vh - (char *)vsh));
+       for (i = 0; IsValidVariableHeader(vh); i++) {
+               vh = (void *)HEADER_ALIGN((char *)(vh + 1) + vh->NameSize + 
vh->DataSize);
+       }
+       printf("Found %d variables, now at offset %ld\n", i, (long)((char *)vh 
- (char *)vsh));
+       memset(vh, 0, sizeof(*vh));
+       vh->StartId = VARIABLE_DATA;
+       vh->State = VAR_ADDED;
+       vh->Attributes = attributes;
+       vh->NameSize = varlen;
+       vh->DataSize = varfilesize;
+       vh->TimeStamp = timestamp;
+       vh->VendorGuid = *owner;
+
+       buf = (void *)(vh + 1);
+       memcpy (buf, var, varlen);
+       buf += varlen;
+       memcpy (buf, vardata, varfilesize);
+       lseek(flashfile, offset, SEEK_SET);
+       write(flashfile, vsh, vsh->Size);
+       close(flashfile);
+       
+       exit(0);
+
+ eof:
+       printf("No variables found in file at offset 0x%x\n", i);
+       exit(2);
+}
+
diff -Nru efitools-1.4.2/.gitignore efitools-1.8.1/.gitignore
--- efitools-1.4.2/.gitignore   2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/.gitignore   2018-02-21 03:53:05.000000000 +0000
@@ -23,8 +23,10 @@
 *.cab
 hash-to-efi-sig-list
 cert-to-efi-sig-list
+cert-to-efi-hash-list
 sig-list-to-certs
 sign-efi-sig-list
 efi-keytool
 efi-readvar
 efi-updatevar
+flash-var
diff -Nru efitools-1.4.2/hash-to-efi-sig-list.c 
efitools-1.8.1/hash-to-efi-sig-list.c
--- efitools-1.4.2/hash-to-efi-sig-list.c       2013-09-19 14:14:24.000000000 
+0100
+++ efitools-1.8.1/hash-to-efi-sig-list.c       2018-02-21 03:53:05.000000000 
+0000
@@ -6,6 +6,12 @@
 #include <stdint.h>
 #define __STDC_VERSION__ 199901L
 #include <efi.h>
+#ifdef CONFIG_arm
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -17,6 +23,7 @@
 #include <unistd.h>
 #include <wchar.h>
 
+#include <PeImage.h>           /* for ALIGN_VALUE */
 #include <sha256.h>
 #include <efiauthenticated.h>
 #include <guid.h>
@@ -80,7 +87,8 @@
                        exit(1);
                }
                fstat(fdefifile, &st);
-               efifile = malloc(st.st_size);
+               efifile = malloc(ALIGN_VALUE(st.st_size, 4096));
+               memset(efifile, 0, ALIGN_VALUE(st.st_size, 4096));
                read(fdefifile, efifile, st.st_size);
                close(fdefifile);
                status = sha256_get_pecoff_digest_mem(efifile, st.st_size,
diff -Nru efitools-1.4.2/HashTool.c efitools-1.8.1/HashTool.c
--- efitools-1.4.2/HashTool.c   2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/HashTool.c   2018-02-21 03:53:05.000000000 +0000
@@ -252,9 +252,7 @@
                                        NULL
                                });
                        if (selection == 1)
-                               uefi_call_wrapper(RT->ResetSystem, 4,
-                                                 EfiResetWarm,
-                                                 EFI_SUCCESS, 0, NULL);
+                         RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
                } else if (option == exit_moktool) {
                        break;
                }
diff -Nru efitools-1.4.2/include/buildefi.h efitools-1.8.1/include/buildefi.h
--- efitools-1.4.2/include/buildefi.h   1970-01-01 01:00:00.000000000 +0100
+++ efitools-1.8.1/include/buildefi.h   2018-02-21 03:53:05.000000000 +0000
@@ -0,0 +1,15 @@
+#ifndef _BUILDEFI_H
+#define _BUILDEFI_H
+
+#ifndef BUILD_EFI
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define Print(...) printf("%ls", __VA_ARGS__)
+#define AllocatePool(x) malloc(x)
+#define CopyMem(d, s, l) memcpy(d, s, l)
+#define ZeroMem(s, l) memset(s, 0, l)
+#define FreePool(s) free(s)
+#endif
+
+#endif /* _BUILDEFI_H */
diff -Nru efitools-1.4.2/include/efiauthenticated.h 
efitools-1.8.1/include/efiauthenticated.h
--- efitools-1.4.2/include/efiauthenticated.h   2013-09-19 14:14:24.000000000 
+0100
+++ efitools-1.8.1/include/efiauthenticated.h   2018-02-21 03:53:05.000000000 
+0000
@@ -7,6 +7,11 @@
 ///
 /// The format of a signature database. 
 ///
+
+typedef UINT8  EFI_SHA256_HASH[32];
+typedef UINT8  EFI_SHA384_HASH[48];
+typedef UINT8  EFI_SHA512_HASH[64];
+
 #pragma pack(1)
 
 typedef struct {
@@ -47,6 +52,39 @@
   ///
 } EFI_SIGNATURE_LIST;
 
+typedef struct {
+  ///
+  /// The SHA256 hash of an X.509 certificate's To-Be-Signed contents.
+  ///
+  EFI_SHA256_HASH     ToBeSignedHash;
+  ///
+  /// The time that the certificate shall be considered to be revoked.
+  ///
+  EFI_TIME            TimeOfRevocation;
+} EFI_CERT_X509_SHA256;
+
+typedef struct {
+  ///
+  /// The SHA384 hash of an X.509 certificate's To-Be-Signed contents.
+  ///
+  EFI_SHA384_HASH     ToBeSignedHash;
+  ///
+  /// The time that the certificate shall be considered to be revoked.
+  ///
+  EFI_TIME            TimeOfRevocation;
+} EFI_CERT_X509_SHA384;
+
+typedef struct {
+  ///
+  /// The SHA512 hash of an X.509 certificate's To-Be-Signed contents.
+  ///
+  EFI_SHA512_HASH     ToBeSignedHash;
+  ///
+  /// The time that the certificate shall be considered to be revoked.
+  ///
+  EFI_TIME            TimeOfRevocation;
+} EFI_CERT_X509_SHA512;
+
 #pragma pack()
 
 //
@@ -72,6 +110,18 @@
     0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 
0xa7} \
   }
 
+#define EFI_CERT_X509_SHA256_GUID \
+       (EFI_GUID) { 0x3bd2a492, 0x96c0, 0x4079,                \
+                       { 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed } }
+
+#define EFI_CERT_X509_SHA384_GUID \
+       (EFI_GUID) { 0x7076876e, 0x80c2, 0x4ee6,                \
+                       { 0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b } }
+
+#define EFI_CERT_X509_SHA512_GUID \
+       (EFI_GUID) { 0x446dbf63, 0x2502, 0x4cda,                \
+                       { 0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d } }
+
 ///
 /// WIN_CERTIFICATE_UEFI_GUID.CertType
 /// 
diff -Nru efitools-1.4.2/include/guid.h efitools-1.8.1/include/guid.h
--- efitools-1.4.2/include/guid.h       2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/include/guid.h       2018-02-21 03:53:05.000000000 +0000
@@ -1,9 +1,16 @@
 #include <efi.h>
 
 #ifndef BUILD_EFI
+#ifdef CONFIG_arm
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
 const char *guid_to_str(EFI_GUID *guid);
 int str_to_guid(const char *str, EFI_GUID *guid);
 int compare_guid(EFI_GUID *g1, EFI_GUID *g2);
+EFI_GUID *get_owner_guid(char *var);
 #endif
 
 extern EFI_GUID GV_GUID;
@@ -17,3 +24,12 @@
 extern EFI_GUID MOK_OWNER;
 extern EFI_GUID SECURITY_PROTOCOL_GUID;
 extern EFI_GUID SECURITY2_PROTOCOL_GUID;
+extern EFI_GUID SECURE_VARIABLE_GUID;
+extern EFI_GUID PKCS7_VERIFY_PROTOCOL_GUID;
+extern EFI_GUID EFI_CERT_SHA1_GUID;
+extern EFI_GUID EFI_CERT_SHA224_GUID;
+extern EFI_GUID EFI_CERT_SHA384_GUID;
+extern EFI_GUID EFI_CERT_SHA512_GUID;
+extern EFI_GUID *allowed_hashes[];
+extern UINTN allowed_hashes_size;
+
diff -Nru efitools-1.4.2/include/pecoff.h efitools-1.8.1/include/pecoff.h
--- efitools-1.4.2/include/pecoff.h     2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/include/pecoff.h     2018-02-21 03:53:05.000000000 +0000
@@ -13,6 +13,11 @@
 pecoff_execute_image(EFI_FILE *file, CHAR16 *name, EFI_HANDLE image,
                     EFI_SYSTEM_TABLE *systab);
 
+EFI_STATUS
+pecoff_get_signature(PE_COFF_LOADER_IMAGE_CONTEXT *context, void *buffer,
+                    WIN_CERTIFICATE **data, int signum);
+
+
 static inline void*
 pecoff_image_address(void *image, int size, unsigned int address)
 {
diff -Nru efitools-1.4.2/include/PeImage.h efitools-1.8.1/include/PeImage.h
--- efitools-1.4.2/include/PeImage.h    2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/include/PeImage.h    2018-02-21 03:53:05.000000000 +0000
@@ -777,6 +777,7 @@
        UINTN SizeOfHeaders;
        UINT16 ImageType;
        UINT16 NumberOfSections;
+       UINT32 FileAlignment;
        EFI_IMAGE_SECTION_HEADER *FirstSection;
        EFI_IMAGE_DATA_DIRECTORY *RelocDir;
        EFI_IMAGE_DATA_DIRECTORY *SecDir;
diff -Nru efitools-1.4.2/include/pkcs7verify.h 
efitools-1.8.1/include/pkcs7verify.h
--- efitools-1.4.2/include/pkcs7verify.h        1970-01-01 01:00:00.000000000 
+0100
+++ efitools-1.8.1/include/pkcs7verify.h        2018-02-21 03:53:05.000000000 
+0000
@@ -0,0 +1,220 @@
+/** @file
+  EFI_PKCS7_VERIFY_PROTOCOL as defined in UEFI 2.5.
+  The EFI_PKCS7_VERIFY_PROTOCOL is used to verify data signed using PKCS#7
+  formatted authentication. The PKCS#7 data to be verified must be binary
+  DER encoded.
+  PKCS#7 is a general-purpose cryptographic standard (defined by RFC2315,
+  available at http://tools.ietf.org/html/rfc2315).
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available 
under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_PKCS7_VERIFY_PROTOCOL_H__
+#define __EFI_PKCS7_VERIFY_PROTOCOL_H__
+
+typedef struct _EFI_PKCS7_VERIFY_PROTOCOL EFI_PKCS7_VERIFY_PROTOCOL;
+
+
+/**
+  Processes a buffer containing binary DER-encoded PKCS7 signature.
+  The signed data content may be embedded within the buffer or separated. 
Funtion
+  verifies the signature of the content is valid and signing certificate was 
not
+  revoked and is contained within a list of trusted signers.
+
+  @param[in]     This                 Pointer to EFI_PKCS7_VERIFY_PROTOCOL 
instance.
+  @param[in]     SignedData           Points to buffer containing ASN.1 
DER-encoded PKCS7
+                                      signature.
+  @param[in]     SignedDataSize       The size of SignedData buffer in bytes.
+  @param[in]     InData               In case of detached signature, InData 
points to
+                                      buffer containing the raw message data 
previously
+                                      signed and to be verified by function. 
In case of
+                                      SignedData containing embedded data, 
InData must be
+                                      NULL.
+  @param[in]     InDataSize           When InData is used, the size of InData 
buffer in
+                                      bytes. When InData is NULL. This 
parameter must be
+                                      0.
+  @param[in]     AllowedDb            Pointer to a list of pointers to 
EFI_SIGNATURE_LIST
+                                      structures. The list is terminated by a 
null
+                                      pointer. The EFI_SIGNATURE_LIST 
structures contain
+                                      lists of X.509 certificates of approved 
signers.
+                                      Function recognizes signer certificates 
of type
+                                      EFI_CERT_X509_GUID. Any hash certificate 
in AllowedDb
+                                      list is ignored by this function. 
Function returns
+                                      success if signer of the buffer is 
within this list
+                                      (and not within RevokedDb). This 
parameter is
+                                      required.
+  @param[in]     RevokedDb            Optional pointer to a list of pointers to
+                                      EFI_SIGNATURE_LIST structures. The list 
is terminated
+                                      by a null pointer. List of X.509 
certificates of
+                                      revoked signers and revoked file hashes. 
Except as
+                                      noted in description of TimeStampDb 
signature
+                                      verification will always fail if the 
signer of the
+                                      file or the hash of the data component 
of the buffer
+                                      is in RevokedDb list. This list is 
optional and
+                                      caller may pass Null or pointer to NULL 
if not
+                                      required.
+  @param[in]     TimeStampDb          Optional pointer to a list of pointers to
+                                      EFI_SIGNATURE_LIST structures. The list 
is terminated
+                                      by a null pointer. This parameter can be 
used to pass
+                                      a list of X.509 certificates of trusted 
time stamp
+                                      signers. This list is optional and 
caller must pass
+                                      Null or pointer to NULL if not required.
+  @param[out]    Content              On input, points to an optional 
caller-allocated
+                                      buffer into which the function will copy 
the content
+                                      portion of the file after verification 
succeeds.
+                                      This parameter is optional and if NULL, 
no copy of
+                                      content from file is performed.
+  @param[in,out] ContentSize          On input, points to the size in bytes of 
the optional
+                                      buffer Content previously allocated by 
caller. On
+                                      output, if the verification succeeds, 
the value
+                                      referenced by ContentSize will contain 
the actual
+                                      size of the content from signed file. If 
ContentSize
+                                      indicates the caller-allocated buffer is 
too small
+                                      to contain content, an error is 
returned, and
+                                      ContentSize will be updated with the 
required size.
+                                      This parameter must be 0 if Content is 
Null.
+
+  @retval EFI_SUCCESS                 Content signature was verified against 
hash of
+                                      content, the signer's certificate was 
not found in
+                                      RevokedDb, and was found in AllowedDb or 
if in signer
+                                      is found in both AllowedDb and 
RevokedDb, the
+                                      signing was allowed by reference to 
TimeStampDb as
+                                      described above, and no hash matching 
content hash
+                                      was found in RevokedDb.
+  @retval EFI_SECURITY_VIOLATION      The SignedData buffer was correctly 
formatted but
+                                      signer was in RevokedDb or not in 
AllowedDb. Also
+                                      returned if matching content hash found 
in RevokedDb.
+  @retval EFI_COMPROMISED_DATA        Calculated hash differs from signed hash.
+  @retval EFI_INVALID_PARAMETER       SignedData is NULL or SignedDataSize is 
zero.
+                                      AllowedDb is NULL.
+  @retval EFI_INVALID_PARAMETER       Content is not NULL and ContentSize is 
NULL.
+  @retval EFI_ABORTED                 Unsupported or invalid format in 
TimeStampDb,
+                                      RevokedDb or AllowedDb list contents was 
detected.
+  @retval EFI_NOT_FOUND               Content not found because InData is NULL 
and no
+                                      content embedded in SignedData.
+  @retval EFI_UNSUPPORTED             The SignedData buffer was not correctly 
formatted
+                                      for processing by the function.
+  @retval EFI_UNSUPPORTED             Signed data embedded in SignedData but 
InData is not
+                                      NULL.
+  @retval EFI_BUFFER_TOO_SMALL        The size of buffer indicated by 
ContentSize is too
+                                      small to hold the content. ContentSize 
updated to
+                                      required size.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PKCS7_VERIFY_BUFFER) (
+  IN EFI_PKCS7_VERIFY_PROTOCOL    *This,
+  IN VOID                         *SignedData,
+  IN UINTN                        SignedDataSize,
+  IN VOID                         *InData          OPTIONAL,
+  IN UINTN                        InDataSize,
+  IN EFI_SIGNATURE_LIST           **AllowedDb,
+  IN EFI_SIGNATURE_LIST           **RevokedDb      OPTIONAL,
+  IN EFI_SIGNATURE_LIST           **TimeStampDb    OPTIONAL,
+  OUT VOID                        *Content         OPTIONAL,
+  IN OUT UINTN                    *ContentSize
+  );
+
+/**
+  Processes a buffer containing binary DER-encoded detached PKCS7 signature.
+  The hash of the signed data content is calculated and passed by the caller. 
Function
+  verifies the signature of the content is valid and signing certificate was 
not revoked
+  and is contained within a list of trusted signers.
+
+  @param[in]     This                 Pointer to EFI_PKCS7_VERIFY_PROTOCOL 
instance.
+  @param[in]     Signature            Points to buffer containing ASN.1 
DER-encoded PKCS
+                                      detached signature.
+  @param[in]     SignatureSize        The size of Signature buffer in bytes.
+  @param[in]     InHash               InHash points to buffer containing the 
caller
+                                      calculated hash of the data. The 
parameter may not
+                                      be NULL.
+  @param[in]     InHashSize           The size in bytes of InHash buffer.
+  @param[in]     AllowedDb            Pointer to a list of pointers to 
EFI_SIGNATURE_LIST
+                                      structures. The list is terminated by a 
null
+                                      pointer. The EFI_SIGNATURE_LIST 
structures contain
+                                      lists of X.509 certificates of approved 
signers.
+                                      Function recognizes signer certificates 
of type
+                                      EFI_CERT_X509_GUID. Any hash certificate 
in AllowedDb
+                                      list is ignored by this function. 
Function returns
+                                      success if signer of the buffer is 
within this list
+                                      (and not within RevokedDb). This 
parameter is
+                                      required.
+  @param[in]     RevokedDb            Optional pointer to a list of pointers to
+                                      EFI_SIGNATURE_LIST structures. The list 
is terminated
+                                      by a null pointer. List of X.509 
certificates of
+                                      revoked signers and revoked file hashes. 
Signature
+                                      verification will always fail if the 
signer of the
+                                      file or the hash of the data component 
of the buffer
+                                      is in RevokedDb list. This parameter is 
optional
+                                      and caller may pass Null if not required.
+  @param[in]     TimeStampDb          Optional pointer to a list of pointers to
+                                      EFI_SIGNATURE_LIST structures. The list 
is terminated
+                                      by a null pointer. This parameter can be 
used to pass
+                                      a list of X.509 certificates of trusted 
time stamp
+                                      counter-signers.
+
+  @retval EFI_SUCCESS                 Signed hash was verified against 
caller-provided
+                                      hash of content, the signer's 
certificate was not
+                                      found in RevokedDb, and was found in 
AllowedDb or
+                                      if in signer is found in both AllowedDb 
and
+                                      RevokedDb, the signing was allowed by 
reference to
+                                      TimeStampDb as described above, and no 
hash matching
+                                      content hash was found in RevokedDb.
+  @retval EFI_SECURITY_VIOLATION      The SignedData buffer was correctly 
formatted but
+                                      signer was in RevokedDb or not in 
AllowedDb. Also
+                                      returned if matching content hash found 
in RevokedDb.
+  @retval EFI_COMPROMISED_DATA        Caller provided hash differs from signed 
hash. Or,
+                                      caller and encrypted hash are different 
sizes.
+  @retval EFI_INVALID_PARAMETER       Signature is NULL or SignatureSize is 
zero. InHash
+                                      is NULL or InHashSize is zero. AllowedDb 
is NULL.
+  @retval EFI_ABORTED                 Unsupported or invalid format in 
TimeStampDb,
+                                      RevokedDb or AllowedDb list contents was 
detected.
+  @retval EFI_UNSUPPORTED             The Signature buffer was not correctly 
formatted
+                                      for processing by the function.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PKCS7_VERIFY_SIGNATURE) (
+  IN EFI_PKCS7_VERIFY_PROTOCOL   *This,
+  IN VOID                        *Signature,
+  IN UINTN                       SignatureSize,
+  IN VOID                        *InHash,
+  IN UINTN                       InHashSize,
+  IN EFI_SIGNATURE_LIST          **AllowedDb,
+  IN EFI_SIGNATURE_LIST          **RevokedDb       OPTIONAL,
+  IN EFI_SIGNATURE_LIST          **TimeStampDb     OPTIONAL
+  );
+
+///
+/// The EFI_PKCS7_VERIFY_PROTOCOL is used to verify data signed using PKCS7
+/// structure. The PKCS7 data to be verified must be ASN.1 (DER) encoded.
+/// SHA256 must be supported as digest algorithm with RSA digest encryption.
+/// Support of other hash algorithms is optional.
+///
+struct _EFI_PKCS7_VERIFY_PROTOCOL {
+  EFI_PKCS7_VERIFY_BUFFER         VerifyBuffer;
+  EFI_PKCS7_VERIFY_SIGNATURE      VerifySignature;
+};
+
+EFI_STATUS
+pkcs7verify_get_protocol(EFI_HANDLE image, EFI_PKCS7_VERIFY_PROTOCOL **p7vp, 
CHAR16 **error);
+BOOLEAN
+pkcs7verify_deny(VOID *data, UINTN len);
+EFI_SIGNATURE_LIST **
+pkcs7verify_to_cert_list(VOID *data, UINTN len);
+BOOLEAN
+pkcs7verify_allow(VOID *data, UINTN len);
+
+
+
+#endif
diff -Nru efitools-1.4.2/include/security_policy.h 
efitools-1.8.1/include/security_policy.h
--- efitools-1.4.2/include/security_policy.h    2013-09-19 14:14:24.000000000 
+0100
+++ efitools-1.8.1/include/security_policy.h    2018-02-21 03:53:05.000000000 
+0000
@@ -1,6 +1,13 @@
+typedef BOOLEAN (*POLICY_FUNCTION)(VOID *data, UINTN len);
+
 EFI_STATUS
-security_policy_install(void);
+security_policy_install(BOOLEAN (*override)(void), POLICY_FUNCTION allow, 
POLICY_FUNCTION deny);
 EFI_STATUS
 security_policy_uninstall(void);
 void
 security_protocol_set_hashes(unsigned char *esl, int len);
+
+/* three policies for MoK based on hashes only */
+BOOLEAN security_policy_mok_override(void);
+BOOLEAN security_policy_mok_deny(VOID *data, UINTN len);
+BOOLEAN security_policy_mok_allow(VOID *data, UINTN len);
diff -Nru efitools-1.4.2/include/shim_protocol.h 
efitools-1.8.1/include/shim_protocol.h
--- efitools-1.4.2/include/shim_protocol.h      1970-01-01 01:00:00.000000000 
+0100
+++ efitools-1.8.1/include/shim_protocol.h      2018-02-21 03:53:05.000000000 
+0000
@@ -0,0 +1,42 @@
+#ifndef _SHIM_PROTOCOL_H
+#define _SHIM_PROTOCOL_H
+
+#include <PeImage.h>
+#include <pkcs7verify.h>
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_VERIFY) (
+       IN VOID *buffer,
+       IN UINT32 size
+       );
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_HASH) (
+       IN char *data,
+       IN int datasize,
+       PE_COFF_LOADER_IMAGE_CONTEXT *context,
+       UINT8 *sha256hash,
+       UINT8 *sha1hash
+       );
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_CONTEXT) (
+       IN VOID *data,
+       IN unsigned int datasize,
+       PE_COFF_LOADER_IMAGE_CONTEXT *context
+       );
+
+typedef struct _SHIM_LOCK {
+       EFI_SHIM_LOCK_VERIFY Verify;
+       EFI_SHIM_LOCK_HASH Hash;
+       EFI_SHIM_LOCK_CONTEXT Context;
+} SHIM_LOCK;
+
+
+EFI_STATUS shim_protocol_install(void);
+void shim_protocol_uninstall(void);
+
+#endif /* _SHIM_PROTOCOL_H */
diff -Nru efitools-1.4.2/include/variableformat.h 
efitools-1.8.1/include/variableformat.h
--- efitools-1.4.2/include/variableformat.h     1970-01-01 01:00:00.000000000 
+0100
+++ efitools-1.8.1/include/variableformat.h     2018-02-21 03:53:05.000000000 
+0000
@@ -0,0 +1,120 @@
+#ifndef _INC_VARIABLEFORMAT_H
+#define _INC_VARIABLEFORMAT_H
+///
+/// Alignment of Variable Data Header in Variable Store region.
+///
+#define HEADER_ALIGNMENT  4
+#define HEADER_ALIGN(Header)  (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & 
(~(HEADER_ALIGNMENT - 1)))
+
+///
+/// Status of Variable Store Region.
+///
+typedef enum {
+  EfiRaw,
+  EfiValid,
+  EfiInvalid,
+  EfiUnknown
+} VARIABLE_STORE_STATUS;
+
+#pragma pack(1)
+
+#define VARIABLE_STORE_SIGNATURE  EFI_AUTHENTICATED_VARIABLE_GUID
+
+///
+/// Variable Store Header Format and State.
+///
+#define VARIABLE_STORE_FORMATTED          0x5a
+#define VARIABLE_STORE_HEALTHY            0xfe
+
+///
+/// Variable Store region header.
+///
+typedef struct {
+  ///
+  /// Variable store region signature.
+  ///
+  EFI_GUID  Signature;
+  ///
+  /// Size of entire variable store, 
+  /// including size of variable store header but not including the size of 
FvHeader.
+  ///
+  UINT32  Size;
+  ///
+  /// Variable region format state.
+  ///
+  UINT8   Format;
+  ///
+  /// Variable region healthy state.
+  ///
+  UINT8   State;
+  UINT16  Reserved;
+  UINT32  Reserved1;
+} VARIABLE_STORE_HEADER;
+
+///
+/// Variable data start flag.
+///
+#define VARIABLE_DATA                     0x55AA
+
+///
+/// Variable State flags.
+///
+#define VAR_IN_DELETED_TRANSITION     0xfe  ///< Variable is in obsolete 
transition.
+#define VAR_DELETED                   0xfd  ///< Variable is obsolete.
+#define VAR_HEADER_VALID_ONLY         0x7f  ///< Variable header has been 
valid.
+#define VAR_ADDED                     0x3f  ///< Variable has been completely 
added.
+
+///
+/// Single Variable Data Header Structure.
+///
+typedef struct {
+  ///
+  /// Variable Data Start Flag.
+  ///
+  UINT16      StartId;
+  ///
+  /// Variable State defined above.
+  ///
+  UINT8       State;
+  UINT8       Reserved;
+  ///
+  /// Attributes of variable defined in UEFI specification.
+  ///
+  UINT32      Attributes;
+  ///
+  /// Associated monotonic count value against replay attack.
+  ///
+  UINT64      MonotonicCount;
+  ///
+  /// Associated TimeStamp value against replay attack. 
+  ///
+  EFI_TIME    TimeStamp;
+  ///
+  /// Index of associated public key in database.
+  ///
+  UINT32      PubKeyIndex;
+  ///
+  /// Size of variable null-terminated Unicode string name.
+  ///
+  UINT32      NameSize;
+  ///
+  /// Size of the variable data without this header.
+  ///
+  UINT32      DataSize;
+  ///
+  /// A unique identifier for the vendor that produces and consumes this 
varaible.
+  ///
+  EFI_GUID    VendorGuid;
+} VARIABLE_HEADER;
+
+#pragma pack()
+
+inline BOOLEAN
+IsValidVariableHeader (VARIABLE_HEADER   *vh) {
+       if (vh == NULL || vh->StartId != VARIABLE_DATA)
+               return FALSE;
+       return TRUE;
+}
+
+
+#endif
diff -Nru efitools-1.4.2/include/variables.h efitools-1.8.1/include/variables.h
--- efitools-1.4.2/include/variables.h  2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/include/variables.h  2018-02-21 03:53:05.000000000 +0000
@@ -27,7 +27,8 @@
 EFI_STATUS
 find_in_variable_esl(CHAR16* var, EFI_GUID owner, UINT8 *key, UINTN keylen);
 
-#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI       0x0000000000000001
+#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION        0x0000000000000002
 
 UINT64
 GetOSIndications(void);
@@ -43,3 +44,7 @@
 EFI_STATUS
 variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
                    void **out, int *outlen);
+int
+hashes_in_esl(UINT8 *Data, UINTN DataSize, EFI_GUID *hashes[]);
+int
+hashes_in_variable(CHAR16* var, EFI_GUID owner, EFI_GUID *hashes[]);
diff -Nru efitools-1.4.2/include/version.h efitools-1.8.1/include/version.h
--- efitools-1.4.2/include/version.h    2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/include/version.h    2018-02-21 03:53:05.000000000 +0000
@@ -1,4 +1,4 @@
-#define VERSION "1.4.1"
+#define VERSION "1.8.1"
 
 static void
 version(const char *progname)
diff -Nru efitools-1.4.2/KeyTool.c efitools-1.8.1/KeyTool.c
--- efitools-1.4.2/KeyTool.c    2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/KeyTool.c    2018-02-21 03:53:05.000000000 +0000
@@ -16,7 +16,7 @@
 #include <efiauthenticated.h>
 
 static EFI_HANDLE im;
-static UINT8 SetupMode, SecureBoot;
+static UINT8 SetupMode, SecureBoot, display_dbt;
 
 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
@@ -25,6 +25,7 @@
        KEY_KEK,
        KEY_DB,
        KEY_DBX,
+       KEY_DBT,
        KEY_MOK,
        MAX_KEYS
 };
@@ -64,6 +65,13 @@
                .authenticated = 1,
                .hash = 1,
        },
+       [KEY_DBT] = {
+               .name = L"dbt",
+               .text = L"The Timestamp Signatures Database (dbt)",
+               .guid = &SIG_DB,
+               .authenticated = 1,
+               .hash = 0,
+       },
        [KEY_MOK] = {
                .name = L"MokList",
                .text = L"The Machine Owner Key List (MokList)",
@@ -87,6 +95,15 @@
        { .guid = &EFI_CERT_SHA256_GUID,
          .name = L"SHA256 signature",
        },
+       { .guid = &EFI_CERT_X509_SHA256_GUID,
+         .name = L"X509 SHA256 signature",
+       },
+       { .guid = &EFI_CERT_X509_SHA384_GUID,
+         .name = L"X509 SHA384 signature",
+       },
+       { .guid = &EFI_CERT_X509_SHA384_GUID,
+         .name = L"X509 SHA256 signature",
+       },
 };
 static const int signatures_size = ARRAY_SIZE(signatures);
 
@@ -152,12 +169,11 @@
                status = SetSecureVariable(keyinfo[key].name, esl, size,
                                           *keyinfo[key].guid, options, 0);
        } else {
-               status = uefi_call_wrapper(RT->SetVariable, 5,
-                                          keyinfo[key].name, keyinfo[key].guid,
-                                          EFI_VARIABLE_NON_VOLATILE
-                                          | EFI_VARIABLE_BOOTSERVICE_ACCESS
-                                          | options,
-                                          size, esl);
+         status = RT->SetVariable(keyinfo[key].name, keyinfo[key].guid,
+                                  EFI_VARIABLE_NON_VOLATILE
+                                  | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                  | options,
+                                  size, esl);
        }
        if (status != EFI_SUCCESS) {
                console_error(L"Failed to update variable", status);
@@ -176,7 +192,7 @@
                return 1;
        }
        while (len > 0) {
-               int i, found;
+               int i, found = 0;
 
                for (i = 0; i < maxlen; i++) {
                        if (str[i] == c)
@@ -220,11 +236,10 @@
                                           DataSize,
                                           *keyinfo[key].guid, 0, 0);
        else
-               status = uefi_call_wrapper(RT->SetVariable, 5,
-                                          keyinfo[key].name, keyinfo[key].guid,
-                                          EFI_VARIABLE_NON_VOLATILE
-                                          | EFI_VARIABLE_BOOTSERVICE_ACCESS,
-                                          DataSize, Data);
+               status = RT->SetVariable(keyinfo[key].name, keyinfo[key].guid,
+                                        EFI_VARIABLE_NON_VOLATILE
+                                        | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                        DataSize, Data);
 
        if (status != EFI_SUCCESS)
                console_error(L"Failed to delete key", status);
@@ -290,6 +305,17 @@
                title[++c] = L"Issuer:";
                for (i = 0; i < sp; i++)
                        title[++c] = tmpbuf1[i];
+       } else if (CompareGuid(&CertList->SignatureType, 
&EFI_CERT_X509_SHA256_GUID) == 0) {
+               EFI_CERT_X509_SHA256 *tmp = (void *)Cert->SignatureData;
+               StrCpy(str2, L"Hash: ");
+               sha256_StrCat_hash(str2, Cert->SignatureData);
+               title[++c] = str2;
+               EFI_TIME timestamp = tmp->TimeOfRevocation;
+               SPrint(buf, sizeof(buf),
+                      L"Revocation Timestamp: %d-%d-%d %02d:%02d:%02d\n",
+                      timestamp.Year, timestamp.Month, timestamp.Day,
+                      timestamp.Hour, timestamp.Minute, timestamp.Second);
+               title[++c] = buf;
        }
        title[++c] = NULL;
 
@@ -444,28 +470,15 @@
 static void
 save_key_internal(int key, EFI_HANDLE vol, CHAR16 *error)
 {
-       CHAR16 *variables[] = { 
-               [KEY_PK] = L"PK",
-               [KEY_KEK] = L"KEK",
-               [KEY_DB] = L"db",
-               [KEY_DBX] = L"dbx",
-               [KEY_MOK] = L"MokList"
-       };
-       EFI_GUID owners[] = { 
-               [KEY_PK] = GV_GUID,
-               [KEY_KEK] = GV_GUID,
-               [KEY_DB] = SIG_DB,
-               [KEY_DBX] = SIG_DB,
-               [KEY_MOK] = MOK_OWNER
-       };
        EFI_STATUS status;
        EFI_FILE *file;
        UINT8 *data;
        UINTN len;
        CHAR16 file_name[512];
 
-       StrCpy(error, variables[key]);
-       status = get_variable(variables[key], &data, &len, owners[key]);
+       StrCpy(error, keyinfo[key].name);
+       status = get_variable(keyinfo[key].name, &data, &len,
+                             *keyinfo[key].guid);
        if (status != EFI_SUCCESS) {
                if (status == EFI_NOT_FOUND)
                        StrCat(error, L": Variable has no entries");
@@ -475,7 +488,7 @@
                return;
        }
        StrCpy(file_name, L"\\");
-       StrCat(file_name, variables[key]);
+       StrCat(file_name, keyinfo[key].name);
        StrCat(file_name, L".esl");
        status = simple_file_open(vol, file_name, &file,
                                  EFI_FILE_MODE_READ
@@ -541,7 +554,7 @@
 
        UINT8 *Data;
        UINTN DataSize = 0, Size;
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, keyinfo[key].name, 
keyinfo[key].guid, NULL, &DataSize, NULL);
+       efi_status = RT->GetVariable(keyinfo[key].name, keyinfo[key].guid, 
NULL, &DataSize, NULL);
        if (efi_status != EFI_BUFFER_TOO_SMALL && efi_status != EFI_NOT_FOUND) {
                console_error(L"Failed to get DataSize", efi_status);
                return;
@@ -555,7 +568,7 @@
                return;
        }
 
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, keyinfo[key].name, 
keyinfo[key].guid, NULL, &DataSize, Data);
+       efi_status = RT->GetVariable(keyinfo[key].name, keyinfo[key].guid, 
NULL, &DataSize, Data);
        if (efi_status == EFI_NOT_FOUND) {
                int t = 2;
                title[t++] = L"Variable is Empty";
@@ -624,12 +637,17 @@
 static void
 select_key(void)
 {
-       int i;
+       int i, j;
+       int keymap[keyinfo_size + 1];
        CHAR16 *keys[keyinfo_size + 1];
 
-       for (i = 0; i < keyinfo_size; i++)
-               keys[i] = keyinfo[i].text;
-       keys[i] = NULL;
+       for (i = 0, j = 0; i < keyinfo_size; i++) {
+               if (i == KEY_DBT && !display_dbt)
+                       continue;
+               keys[j] = keyinfo[i].text;
+               keymap[j++] = i;
+       }
+       keys[j] = NULL;
 
        i = 0;
 
@@ -637,7 +655,7 @@
                i = console_select( (CHAR16 *[]){ L"Select Key to Manipulate", 
NULL }, keys, i);
                if (i == -1)
                        break;
-               manipulate_key(i);
+               manipulate_key(keymap[i]);
        }
 }
 
@@ -670,6 +688,8 @@
        title[t_c++] = L"";
 
        for (i = 0; i < MAX_KEYS; i++) {
+               if (i == KEY_DBT && !display_dbt)
+                       continue;
                save_key_internal(i, vol, &buf[b_c]);
                title[t_c++] = &buf[b_c];
                b_c += StrLen(&buf[b_c]) + 1;
@@ -678,6 +698,45 @@
        console_alertbox(title);
 }
 
+static void
+execute_binary()
+{
+       CHAR16 *bin_name;
+       EFI_HANDLE h = NULL;
+       EFI_HANDLE ih;
+       EFI_DEVICE_PATH *devpath;
+       EFI_STATUS status;
+
+       simple_file_selector(&h, (CHAR16 *[]) {
+                       L"Select Binary to Execute",
+                       L"",
+                       NULL
+               }, L"\\",
+               NULL, &bin_name);
+       if (!bin_name) {
+               /* user pressed ESC */
+               return;
+       }
+
+       /* the execute() call is designed to construct handles from
+        * local resources on the image.  We have a handle and a full
+        * path name, so we follow proper process here */
+
+       devpath = FileDevicePath(h, bin_name);
+
+       status = BS->LoadImage(FALSE, im, devpath, NULL, 0, &ih);
+       if (status != EFI_SUCCESS) {
+               console_error(L"Image failed to load", status);
+               return;
+       }
+
+       status = BS->StartImage(ih, NULL, NULL);
+       BS->UnloadImage(ih);
+
+       if (status != EFI_SUCCESS)
+               console_error(L"Execution returned error", status);
+}
+
 EFI_STATUS
 efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
 {
@@ -689,7 +748,10 @@
 
        InitializeLib(image, systab);
 
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", 
&GV_GUID, NULL, &DataSize, &SetupMode);
+       if (GetOSIndications() & EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION)
+               display_dbt = 1;
+
+       efi_status = RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, 
&SetupMode);
 
        if (efi_status != EFI_SUCCESS) {
                Print(L"No SetupMode variable ... is platform secure boot 
enabled?\n");         return EFI_SUCCESS;
@@ -710,7 +772,13 @@
                StrCat(line3, SecureBoot ? L"on" : L"off");
                title =  (CHAR16 *[]){L"KeyTool main menu", L"", line2, line3, 
NULL };
 
-               option = console_select(title, (CHAR16 *[]){ L"Save Keys", 
L"Edit Keys", L"Exit", NULL }, option);
+               option = console_select(title, (CHAR16 *[]){ 
+                               L"Save Keys",
+                               L"Edit Keys",
+                               L"Execute Binary",
+                               L"Exit",
+                               NULL },
+                       option);
 
                switch (option) {
                case 0:
@@ -720,6 +788,9 @@
                        select_key();
                        break;
                case 2:
+                       execute_binary();
+                       break;
+               case 3:
                        /* exit from programme */
                        return EFI_SUCCESS;
                default:
diff -Nru efitools-1.4.2/lib/asn1/Makefile efitools-1.8.1/lib/asn1/Makefile
--- efitools-1.4.2/lib/asn1/Makefile    2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/asn1/Makefile    2018-02-21 03:53:05.000000000 +0000
@@ -8,7 +8,14 @@
 libasn1-efi.a: $(EFILIBFILES)
 
 test.o: test.c ../../include/x509.h
-       $(CC) -I../../include -c -o $@ $<
+       $(CC) $(ARCH3264) -I../../include -c -o $@ $<
 
 test: test.o libasn1.a
-       $(CC) -o $@ $< libasn1.a
+       $(CC) $(ARCH3264) -o $@ $< libasn1.a
+
+clean:
+       rm -f libasn1.a
+       rm -f libasn1-efi.a
+       rm -f test test.o
+       rm -f $(LIBFILES)
+       rm -f $(EFILIBFILES)
diff -Nru efitools-1.4.2/lib/asn1/oid.h efitools-1.8.1/lib/asn1/oid.h
--- efitools-1.4.2/lib/asn1/oid.h       2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/asn1/oid.h       2018-02-21 03:53:05.000000000 +0000
@@ -5,6 +5,8 @@
  * Do not edit manually!
  */
 
+#include <sys/types.h>
+
 #ifndef OID_H_
 #define OID_H_
 
diff -Nru efitools-1.4.2/lib/console.c efitools-1.8.1/lib/console.c
--- efitools-1.4.2/lib/console.c        2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/console.c        2018-02-21 03:53:05.000000000 +0000
@@ -42,8 +42,8 @@
        EFI_INPUT_KEY key;
        UINTN EventIndex;
 
-       uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, 
&EventIndex);
-       uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
+       BS->WaitForEvent(1, &ST->ConIn->WaitForKey, &EventIndex);
+       ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
 
        return key;
 }
@@ -61,7 +61,7 @@
         * it */
 
        for(;;) {
-               status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, 
ST->ConIn, &k);
+         status = ST->ConIn->ReadKeyStroke(ST->ConIn, &k);
 
                if (status != EFI_SUCCESS)
                        break;
@@ -83,7 +83,7 @@
        if (lines == 0)
                return;
 
-       uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows);
+       co->QueryMode(co, co->Mode->Mode, &cols, &rows);
 
        /* last row on screen is unusable without scrolling, so ignore it */
        rows--;
@@ -126,8 +126,8 @@
        Line[0] = BOXDRAW_DOWN_RIGHT;
        Line[size_cols - 1] = BOXDRAW_DOWN_LEFT;
        Line[size_cols] = L'\0';
-       uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, start_row);
-       uefi_call_wrapper(co->OutputString, 2, co, Line);
+       co->SetCursorPosition(co, start_col, start_row);
+       co->OutputString(co, Line);
 
        int start;
        if (offset == 0)
@@ -140,7 +140,6 @@
                /* from top */
                start = start_row + offset;
                
-
        for (i = start_row + 1; i < size_rows + start_row - 1; i++) {
                int line = i - start;
 
@@ -159,19 +158,19 @@
                        CopyMem(Line + col + 1, s, min(len, size_cols - 2)*2);
                }
                if (line >= 0 && line == highlight) 
-                       uefi_call_wrapper(co->SetAttribute, 2, co, 
EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
-               uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i);
-               uefi_call_wrapper(co->OutputString, 2, co, Line);
+                       co->SetAttribute(co, EFI_LIGHTGRAY | 
EFI_BACKGROUND_BLACK);
+               co->SetCursorPosition(co, start_col, i);
+               co->OutputString(co, Line);
                if (line >= 0 && line == highlight) 
-                       uefi_call_wrapper(co->SetAttribute, 2, co, 
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+                       co->SetAttribute(co, EFI_LIGHTGRAY | 
EFI_BACKGROUND_BLUE);
 
        }
        SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL);
        Line[0] = BOXDRAW_UP_RIGHT;
        Line[size_cols - 1] = BOXDRAW_UP_LEFT;
        Line[size_cols] = L'\0';
-       uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i);
-       uefi_call_wrapper(co->OutputString, 2, co, Line);
+       co->SetCursorPosition(co, start_col, i);
+       co->OutputString(co, Line);
 
        FreePool (Line);
 
@@ -183,19 +182,19 @@
        SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
        SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
        CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
-       uefi_call_wrapper(co->EnableCursor, 2, co, FALSE);
-       uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | 
EFI_BACKGROUND_BLUE);
+       co->EnableCursor(co, FALSE);
+       co->SetAttribute(co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
 
        console_print_box_at(str_arr, highlight, 0, 0, -1, -1, 0,
                             count_lines(str_arr));
 
        console_get_keystroke();
 
-       uefi_call_wrapper(co->EnableCursor, 2, co, 
SavedConsoleMode.CursorVisible);
+       co->EnableCursor(co, SavedConsoleMode.CursorVisible);
 
-       uefi_call_wrapper(co->EnableCursor, 2, co, 
SavedConsoleMode.CursorVisible);
-       uefi_call_wrapper(co->SetCursorPosition, 3, co, 
SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
-       uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute);
+       co->EnableCursor(co, SavedConsoleMode.CursorVisible);
+       co->SetCursorPosition(co, SavedConsoleMode.CursorColumn, 
SavedConsoleMode.CursorRow);
+       co->SetAttribute(co, SavedConsoleMode.Attribute);
 }
 
 int
@@ -209,9 +208,10 @@
        int selector_max_cols = 0;
        int i, offs_col, offs_row, size_cols, size_rows, lines;
        int selector_offset;
+       int title_lines = count_lines(title);
        UINTN cols, rows;
 
-       uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows);
+       co->QueryMode(co, co->Mode->Mode, &cols, &rows);
 
        for (i = 0; i < selector_lines; i++) {
                int len = StrLen(selectors[i]);
@@ -228,13 +228,12 @@
        offs_col = - selector_max_cols - 4;
        size_cols = selector_max_cols + 4;
 
-       if (selector_lines > rows - 10) {
-               int title_lines = count_lines(title);
-               offs_row =  title_lines + 1;
-               size_rows = rows - 3 - title_lines;
+       if (selector_lines > rows - 6 - title_lines) {
+               offs_row =  title_lines + 2;
+               size_rows = rows - 4 - title_lines;
                lines = size_rows - 2;
        } else {
-               offs_row = - selector_lines - 4;
+               offs_row = (rows + title_lines - 1 - selector_lines)/2;
                size_rows = selector_lines + 2;
                lines = selector_lines;
        }
@@ -248,8 +247,8 @@
        }
 
        CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
-       uefi_call_wrapper(co->EnableCursor, 2, co, FALSE);
-       uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | 
EFI_BACKGROUND_BLUE);
+       co->EnableCursor(co, FALSE);
+       co->SetAttribute(co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
 
        console_print_box_at(title, -1, 0, 0, -1, -1, 1, count_lines(title));
 
@@ -282,11 +281,11 @@
        } while (!(k.ScanCode == SCAN_NULL
                   && k.UnicodeChar == CHAR_CARRIAGE_RETURN));
 
-       uefi_call_wrapper(co->EnableCursor, 2, co, 
SavedConsoleMode.CursorVisible);
+       co->EnableCursor(co, SavedConsoleMode.CursorVisible);
 
-       uefi_call_wrapper(co->EnableCursor, 2, co, 
SavedConsoleMode.CursorVisible);
-       uefi_call_wrapper(co->SetCursorPosition, 3, co, 
SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
-       uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute);
+       co->EnableCursor(co, SavedConsoleMode.CursorVisible);
+       co->SetCursorPosition(co, SavedConsoleMode.CursorColumn, 
SavedConsoleMode.CursorRow);
+       co->SetAttribute(co, SavedConsoleMode.Attribute);
 
        if (selector < 0)
                /* ESC pressed */
@@ -406,8 +405,8 @@
 {
        SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
 
-       uefi_call_wrapper(co->Reset, 2, co, TRUE);
+       co->Reset(co, TRUE);
        /* set mode 0 - required to be 80x25 */
-       uefi_call_wrapper(co->SetMode, 2, co, 0);
-       uefi_call_wrapper(co->ClearScreen, 1, co);
+       co->SetMode(co, 0);
+       co->ClearScreen(co);
 }
diff -Nru efitools-1.4.2/lib/execute.c efitools-1.8.1/lib/execute.c
--- efitools-1.4.2/lib/execute.c        2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/execute.c        2018-02-21 03:53:05.000000000 +0000
@@ -102,8 +102,7 @@
        EFI_DEVICE_PATH *devpath;
        CHAR16 *PathName;
 
-       status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
-                                  &IMAGE_PROTOCOL, &li);
+       status = BS->HandleProtocol(image, &IMAGE_PROTOCOL, (VOID **)&li);
        if (status != EFI_SUCCESS)
                return status;
 
@@ -112,13 +111,12 @@
        if (status != EFI_SUCCESS)
                return status;
 
-       status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image,
-                                  devpath, NULL, 0, &h);
+       status = BS->LoadImage(FALSE, image, devpath, NULL, 0, &h);
        if (status != EFI_SUCCESS)
                goto out;
        
-       status = uefi_call_wrapper(BS->StartImage, 3, h, NULL, NULL);
-       uefi_call_wrapper(BS->UnloadImage, 1, h);
+       status = BS->StartImage(h, NULL, NULL);
+       BS->UnloadImage(h);
 
  out:
        FreePool(PathName);
diff -Nru efitools-1.4.2/lib/guid.c efitools-1.8.1/lib/guid.c
--- efitools-1.4.2/lib/guid.c   2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/guid.c   2018-02-21 03:53:05.000000000 +0000
@@ -6,6 +6,9 @@
 
 #include <guid.h>
 #include <stdio.h>
+#include <buildefi.h>
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
 #ifndef BUILD_EFI
 /* EFI has %g for this, so it's only needed in platform c */
@@ -40,8 +43,28 @@
 {
        return memcmp(g1, g2, sizeof(*g1));
 }
+
+EFI_GUID *
+get_owner_guid(char *var)
+{
+       char *variables[] = { "PK", "KEK", "db", "dbx", "dbt", "MokList" };
+       EFI_GUID *owners[] = { &GV_GUID, &GV_GUID, &SIG_DB, &SIG_DB, &SIG_DB, 
&MOK_OWNER };
+       EFI_GUID *owner = NULL;
+       int i;
+
+       for(i = 0; i < ARRAY_SIZE(variables); i++) {
+               if (strcmp(var, variables[i]) == 0) {
+                       owner = owners[i];
+                       break;
+               }
+       }
+
+       return owner;
+}
 #endif
 
+
+
 /* all the necessary guids */
 EFI_GUID GV_GUID = EFI_GLOBAL_VARIABLE;
 EFI_GUID SIG_DB = { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0,  0xe, 
0x67, 0x65, 0x6f }};
@@ -55,3 +78,19 @@
 EFI_GUID MOK_OWNER = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 
0x10, 0xdd, 0x8b, 0x23} };
 EFI_GUID SECURITY_PROTOCOL_GUID = { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 
0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } };
 EFI_GUID SECURITY2_PROTOCOL_GUID = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 
0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
+EFI_GUID SECURE_VARIABLE_GUID = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 
0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } };
+EFI_GUID PKCS7_VERIFY_PROTOCOL_GUID = { 0x47889fb2, 0xd671, 0x4fab, {0xa0, 
0xca, 0xdf, 0x0e, 0x44, 0xdf, 0x70, 0xd6 } };
+EFI_GUID EFI_CERT_SHA1_GUID = { 0x826ca512, 0xcf10, 0x4ac9, { 0xb1, 0x87, 
0xbe, 0x01, 0x49, 0x66, 0x31, 0xbd } };
+EFI_GUID EFI_CERT_SHA224_GUID = { 0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x07, 
0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd} };
+EFI_GUID EFI_CERT_SHA384_GUID = { 0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 
0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x01}};
+EFI_GUID EFI_CERT_SHA512_GUID = { 0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 
0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} };
+
+EFI_GUID *allowed_hashes[] = {
+  &EFI_CERT_SHA1_GUID,
+  &EFI_CERT_SHA224_GUID,
+  &EFI_CERT_SHA256_GUID,
+  &EFI_CERT_SHA384_GUID,
+  &EFI_CERT_SHA512_GUID,
+};
+
+UINTN allowed_hashes_size = ARRAY_SIZE(allowed_hashes);
diff -Nru efitools-1.4.2/lib/kernel_efivars.c 
efitools-1.8.1/lib/kernel_efivars.c
--- efitools-1.4.2/lib/kernel_efivars.c 2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/kernel_efivars.c 2018-02-21 03:53:05.000000000 +0000
@@ -66,10 +66,10 @@
        while (ptr < buf + st.st_size) {
                int count;
 
-               sscanf(ptr, "%*s on %s type %s %*s\n%n", path, type, &count);
+               sscanf(ptr, "%*s on %s type %s %*[^\n]\n%n", path, type, 
&count);
                ptr += count;
-               if (strcmp(type, "efivarfs") != 0)
-                       continue;
+               if (strcmp(type, "efivarfs") == 0)
+                       break;
        }
        if (strcmp(type, "efivarfs") != 0) {
                fprintf(stderr, "No efivarfs filesystem is mounted\n");
@@ -205,7 +205,8 @@
        /* FIXME: currently timestamp is one year into future because of
         * the way we set up the secure environment  */
        Time->Year = tm.tm_year + 1900 + 1;
-       Time->Month = tm.tm_mon;
+       /* EFI_TIME Month is 1-12; Unix tm_mon is 0-11 */
+       Time->Month = tm.tm_mon + 1;
        Time->Day = tm.tm_mday;
        Time->Hour = tm.tm_hour;
        Time->Minute = tm.tm_min;
diff -Nru efitools-1.4.2/lib/Makefile efitools-1.8.1/lib/Makefile
--- efitools-1.4.2/lib/Makefile 2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/Makefile 2018-02-21 03:53:05.000000000 +0000
@@ -1,5 +1,7 @@
 FILES = simple_file.o pecoff.o guid.o sha256.o console.o \
-       security_policy.o execute.o configtable.o shell.o
+       execute.o configtable.o shell.o security_policy.o \
+       shim_protocol.o pkcs7verify.o
+
 LIBFILES = $(FILES) kernel_efivars.o
 EFILIBFILES = $(patsubst %.o,%.efi.o,$(FILES)) variables.o 
 
@@ -10,5 +12,7 @@
 
 clean:
        rm -f lib.a
+       rm -f lib-efi.a
        rm -f $(LIBFILES)
+       rm -f $(EFILIBFILES)
 
diff -Nru efitools-1.4.2/lib/pecoff.c efitools-1.8.1/lib/pecoff.c
--- efitools-1.4.2/lib/pecoff.c 2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/pecoff.c 2018-02-21 03:53:05.000000000 +0000
@@ -50,6 +50,14 @@
 
 #include <efi.h>
 #include <efilib.h>
+#ifdef CONFIG_arm
+#ifndef BUILD_EFI
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
+#endif
 
 #include <pecoff.h>
 #include <guid.h>
@@ -57,13 +65,8 @@
 #include <variables.h>
 #include <sha256.h>
 #include <errors.h>
-
-#ifndef BUILD_EFI
-#define Print(...) do { } while(0)
-#define AllocatePool(x) malloc(x)
-#define CopyMem(d, s, l) memcpy(d, s, l)
-#define ZeroMem(s, l) memset(s, 0, l)
-#endif
+#include <execute.h>
+#include <buildefi.h>
 
 EFI_STATUS
 pecoff_read_header(PE_COFF_LOADER_IMAGE_CONTEXT *context, void *data)
@@ -84,21 +87,34 @@
                return EFI_UNSUPPORTED;
        }
 
-       if (PEHdr->Pe32.OptionalHeader.Magic != 
EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
-               Print(L"Only 64-bit images supported\n");
+       if (PEHdr->Pe32.OptionalHeader.Magic != 
EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC &&
+           PEHdr->Pe32.OptionalHeader.Magic != 
EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+               Print(L"Only IA32 or X64 images supported\n");
                return EFI_UNSUPPORTED;
        }
 
        context->PEHdr = PEHdr;
-       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;
+       if (PEHdr->Pe32.OptionalHeader.Magic == 
EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+               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->SecDir = (EFI_IMAGE_DATA_DIRECTORY *) 
&PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
+               context->FileAlignment = 
PEHdr->Pe32Plus.OptionalHeader.FileAlignment;
+
+       } else if (PEHdr->Pe32.OptionalHeader.Magic == 
EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+               context->ImageAddress = PEHdr->Pe32.OptionalHeader.ImageBase;
+               context->ImageSize = 
(UINT64)PEHdr->Pe32.OptionalHeader.SizeOfImage;
+               context->SizeOfHeaders = 
PEHdr->Pe32.OptionalHeader.SizeOfHeaders;
+               context->EntryPoint = 
PEHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
+               context->RelocDir = 
&PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+               context->NumberOfRvaAndSizes = 
PEHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes;
+               context->SecDir = (EFI_IMAGE_DATA_DIRECTORY *) 
&PEHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
+               context->FileAlignment = 
PEHdr->Pe32.OptionalHeader.FileAlignment;      }
        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];
 
        if (context->SecDir->VirtualAddress >= context->ImageSize) {
                Print(L"Malformed security header\n");
@@ -120,10 +136,8 @@
 
        for (i = 0; i < context->NumberOfSections; i++) {
                s = &context->FirstSection[i];
-               size = s->Misc.VirtualSize;
-       
-               if (size > s->SizeOfRawData)
-                       size = s->SizeOfRawData;
+               size = ALIGN_VALUE(s->SizeOfRawData, context->FileAlignment);
+
                base = pecoff_image_address(buffer, context->ImageSize, 
s->VirtualAddress);
                end = pecoff_image_address(buffer, context->ImageSize, 
s->VirtualAddress + size - 1);
 
@@ -165,7 +179,11 @@
                return efi_status;
        }
 
-       context->PEHdr->Pe32Plus.OptionalHeader.ImageBase = (UINT64)*data;
+       if (context->PEHdr->Pe32.OptionalHeader.Magic == 
EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+               context->PEHdr->Pe32Plus.OptionalHeader.ImageBase = 
(UINT64)*data;
+       } else if (context->PEHdr->Pe32.OptionalHeader.Magic == 
EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+               context->PEHdr->Pe32.OptionalHeader.ImageBase = 
(UINT32)(long)*data;
+       }
 
        if (context->NumberOfRvaAndSizes <= 
EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
                Print(L"Image has no relocation entry\n");
@@ -255,6 +273,32 @@
        return EFI_SUCCESS;
 }
 
+EFI_STATUS
+pecoff_get_signature(PE_COFF_LOADER_IMAGE_CONTEXT *context, void *buffer,
+                    WIN_CERTIFICATE **data, int signum)
+{
+       WIN_CERTIFICATE *cert;
+       UINT32 offset;
+       int i;
+
+       if (!context->SecDir->Size)
+               return EFI_NOT_FOUND;
+
+       offset = context->SecDir->VirtualAddress;
+       cert = (WIN_CERTIFICATE *)(buffer + offset);
+       for (i = 0; i < signum; i++) {
+               offset += ALIGN_VALUE(cert->dwLength, 8);
+               cert = (WIN_CERTIFICATE *)(buffer + offset);
+               if (offset >= context->SecDir->VirtualAddress + 
context->SecDir->Size)
+                       break;
+       }
+       if (i != signum)
+               return EFI_NOT_FOUND;
+
+       *data = cert;
+       return EFI_SUCCESS;
+}
+
 #ifdef BUILD_EFI
 EFI_STATUS
 pecoff_check_mok(EFI_HANDLE image, CHAR16 *name)
@@ -319,21 +363,19 @@
        EFI_HANDLE h;
        EFI_FILE *file;
 
-       status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
-                                  &IMAGE_PROTOCOL, &li);
+       status = BS->HandleProtocol(image, &IMAGE_PROTOCOL, (VOID **)&li);
        if (status != EFI_SUCCESS)
                return status;
        status = generate_path(name, li, &loadpath, &PathName);
        if (status != EFI_SUCCESS)
                return status;
-       status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image,
-                                  loadpath, NULL, 0, &h);
+       status = BS->LoadImage(FALSE, image, loadpath, NULL, 0, &h);
        if (status == EFI_SECURITY_VIOLATION || status == EFI_ACCESS_DENIED)
                status = pecoff_check_mok(image, name);
        if (status != EFI_SUCCESS)
                /* this will fail if signature validation fails */
                return status;
-       uefi_call_wrapper(BS->UnloadImage, 1, h);
+       BS->UnloadImage(h);
 
        status = simple_file_open(image, name, &file, EFI_FILE_MODE_READ);
        if (status != EFI_SUCCESS)
@@ -381,7 +423,7 @@
                goto out;
        }
 
-       efi_status = uefi_call_wrapper(entry_point, 2, image, systab);
+       efi_status = entry_point(image, systab);
 
  out:
        FreePool(buffer);
diff -Nru efitools-1.4.2/lib/pkcs7verify.c efitools-1.8.1/lib/pkcs7verify.c
--- efitools-1.4.2/lib/pkcs7verify.c    1970-01-01 01:00:00.000000000 +0100
+++ efitools-1.8.1/lib/pkcs7verify.c    2018-02-21 03:53:05.000000000 +0000
@@ -0,0 +1,250 @@
+#include <efi.h>
+#include <efilib.h>
+
+#include <efiauthenticated.h>
+#include <guid.h>
+#include <pkcs7verify.h>
+#include <variables.h>
+#include <execute.h>
+#include <pecoff.h>
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static CHAR16 *p7bin = L"\\Pkcs7VerifyDxe.efi";
+static EFI_PKCS7_VERIFY_PROTOCOL *pkcs7verifyprotocol;
+
+EFI_STATUS
+pkcs7verify_get_protocol(EFI_HANDLE image, EFI_PKCS7_VERIFY_PROTOCOL **p7vp, 
CHAR16 **error)
+{
+       EFI_LOADED_IMAGE *li;
+       EFI_DEVICE_PATH *loadpath = NULL;
+       CHAR16 *PathName = NULL;
+       EFI_HANDLE loader_handle;
+       EFI_STATUS status;
+
+       status = BS->LocateProtocol(&PKCS7_VERIFY_PROTOCOL_GUID,
+                                   NULL, (VOID **)p7vp);
+
+       if (status == EFI_SUCCESS)
+               return status;
+
+       Print(L"Platform doesn't provide PKCS7_VERIFY protocol, trying to 
load\n");
+
+       status = BS->HandleProtocol(image, &IMAGE_PROTOCOL, (VOID **)&li);
+       if (status != EFI_SUCCESS) {
+               *error = L"Can't find loaded image protocol";
+               return status;
+       }
+
+       status = generate_path(p7bin, li, &loadpath, &PathName);
+       if (status != EFI_SUCCESS) {
+               *error = L"generate_path failed";
+               return status;
+       }
+
+       status = BS->LoadImage(FALSE, image, loadpath, NULL, 0, &loader_handle);
+       if (status != EFI_SUCCESS) {
+               *error = L"LoadImage failed for external module";
+               return status;
+       }
+
+       status = BS->StartImage(loader_handle, NULL, NULL);
+       if (status != EFI_SUCCESS) {
+               *error = L"StartImage failed for external module (loaded OK)";
+               return status;
+       }
+
+       status = BS->LocateProtocol(&PKCS7_VERIFY_PROTOCOL_GUID,
+                                   NULL, (VOID **)p7vp);
+
+       if (status != EFI_SUCCESS)
+               *error = L"Loaded module but it didn't provide the pkcs7Verify 
protocol";
+       else
+               pkcs7verifyprotocol = *p7vp;
+
+       return status;
+}
+
+/*
+ * Checks the variable for the binary hash.  Returns 1 if found, 0 if
+ * not and -1 on error.
+ */
+static int
+pkcs7verify_is_hash_present(CHAR16 *var, EFI_GUID owner, VOID *data, UINTN len)
+{
+       EFI_GUID **hashes;
+       UINT8 *hash;
+       int count, i;
+       int present  = -1;
+
+       hashes = AllocatePool(allowed_hashes_size * sizeof(EFI_GUID *));
+       if (!hashes)
+               goto out;
+
+       count = hashes_in_variable(var, owner, hashes);
+       if (count < 0)
+               goto out;
+
+       for (i = 0; i < count; i++) {
+               if (CompareGuid(hashes[i], &EFI_CERT_SHA256_GUID) == 0) {
+                       hash = AllocatePool(SHA256_DIGEST_SIZE);
+                       if (!hash)
+                               goto out;
+                       if (sha256_get_pecoff_digest_mem(data, len, hash) != 
EFI_SUCCESS) {
+                               FreePool(hash);
+                               goto out;
+                       }
+                       if (find_in_variable_esl(var, owner, hash, 
SHA256_DIGEST_SIZE) == EFI_SUCCESS) {
+                               present = 1;
+                               FreePool(hash);
+                               goto out;
+                       }
+                       FreePool(hash);
+               } else {
+                       Print(L"FIXME: found an unrecognised hash algorithm 
%g\n",
+                             hashes[i]);
+                       goto out;
+               }
+       }
+       present = 0;
+ out:
+       if (hashes)
+               FreePool(hashes);
+       return present;
+}
+
+
+BOOLEAN
+pkcs7verify_deny(VOID *data, UINTN len)
+{
+       int deny;
+
+       deny = pkcs7verify_is_hash_present(L"dbx", SIG_DB, data, len);
+       if (deny == 1 || deny < 0) {
+               deny = 1;
+               goto out;
+       }
+       deny = pkcs7verify_is_hash_present(L"MokListX", MOK_OWNER, data, len);
+       if (deny == 1 || deny < 0)
+               deny = 1;
+ out:
+       return deny ? TRUE : FALSE;
+}
+
+/*
+ * The Plcs7Verify protocol doesn't take raw signature lists and lengths,
+ * it takes a null terminated list of pointers to signature lists, so
+ * make the conversion
+ */
+EFI_SIGNATURE_LIST **
+pkcs7verify_to_cert_list(VOID *data, UINTN len)
+{
+       EFI_SIGNATURE_LIST  *CertList, **retval;
+       
+       int size, count=0;
+
+       if (!data)
+               return data;
+
+       certlist_for_each_certentry(CertList, data, size, len)
+               count++;
+
+       retval = AllocatePool((count + 1) * sizeof(void *));
+       if (!retval)
+               return NULL;
+       count = 0;
+       certlist_for_each_certentry(CertList, data, size, len)
+               retval[count++] = CertList;
+       retval[count] = NULL;
+
+       return retval;
+}
+
+BOOLEAN
+pkcs7verify_allow(VOID *data, UINTN len)
+{
+       PE_COFF_LOADER_IMAGE_CONTEXT context;
+       UINT8 hash[SHA256_DIGEST_SIZE];
+       BOOLEAN allow = FALSE;
+       CHAR16 *check[] = { L"MokList", L"db" };
+       CHAR16 *forbid[] = { L"MokListX", L"dbx" };
+       EFI_GUID owners[] = { MOK_OWNER, SIG_DB };
+       EFI_STATUS status;
+       int i;
+
+       status = pecoff_read_header(&context, data);
+       if (status != EFI_SUCCESS)
+               goto out;
+
+       /* FIXME: this is technically wrong, because the hash
+        * could be non-sha256, but it isn't a security breach
+        * because we'll refuse a binary we should have accepted */
+       status = sha256_get_pecoff_digest_mem(data, len, hash);
+       if (status != EFI_SUCCESS)
+               goto out;
+
+       /* first look up the hashes because the verify protocol can't
+        * do this anyway */
+
+       if (find_in_variable_esl(L"MokList", MOK_OWNER, hash, 
SHA256_DIGEST_SIZE) == EFI_SUCCESS || 
+           find_in_variable_esl(L"db", SIG_DB, hash, SHA256_DIGEST_SIZE) == 
EFI_SUCCESS) {
+               allow = TRUE;
+               goto out;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(check); i++) {
+               VOID *db = NULL, *dbx = NULL;
+               EFI_SIGNATURE_LIST **dblist = NULL, **dbxlist = NULL;
+               UINTN db_len = 0, dbx_len = 0;
+               int j;
+
+               status = get_variable(check[i], (UINT8 **)&db, &db_len, 
owners[i]);
+               if (status != EFI_SUCCESS)
+                       goto next;
+               status = get_variable(forbid[i], (UINT8 **)&dbx, &dbx_len, 
owners[i]);
+               if (status != EFI_SUCCESS && status != EFI_NOT_FOUND)
+                       goto next;
+               dblist = pkcs7verify_to_cert_list(db, db_len);
+               if (status != EFI_NOT_FOUND)
+                       dbxlist = pkcs7verify_to_cert_list(dbx, dbx_len);
+               if ((db_len != 0 && dblist == NULL) ||
+                   (dbx_len != 0 && dbxlist == NULL))
+                       goto next;
+               for (j = 0; ; j++) {
+                       WIN_CERTIFICATE *cert;
+
+                       status = pecoff_get_signature(&context, data,
+                                                     &cert, j);
+                       if (status != EFI_SUCCESS)
+                               break;
+
+                       status = pkcs7verifyprotocol->
+                               VerifySignature(pkcs7verifyprotocol,
+                                               (VOID *)(cert + 1),
+                                               cert->dwLength - sizeof(*cert),
+                                               hash, sizeof(hash),
+                                               dblist, dbxlist, NULL);
+
+                       if (status == EFI_SUCCESS) {
+                               allow = TRUE;
+                               break;
+                       }
+               }
+       next:
+               if (dblist)
+                       FreePool(dblist);
+               if (dbxlist)
+                       FreePool(dbxlist);
+               if (db)
+                       FreePool(db);
+               if (dbx)
+                       FreePool(dbx);
+               if (allow)
+                       break;
+       }
+
+ out:
+       return allow;
+
+
+}
diff -Nru efitools-1.4.2/lib/security_policy.c 
efitools-1.8.1/lib/security_policy.c
--- efitools-1.4.2/lib/security_policy.c        2013-09-19 14:14:24.000000000 
+0100
+++ efitools-1.8.1/lib/security_policy.c        2018-02-21 03:53:05.000000000 
+0000
@@ -51,16 +51,14 @@
 static UINT8 *security_policy_esl = NULL;
 static UINTN security_policy_esl_len;
 
-static EFI_STATUS
-security_policy_check_mok(void *data, UINTN len)
+BOOLEAN security_policy_mok_override(void)
 {
-       EFI_STATUS status;
-       UINT8 hash[SHA256_DIGEST_SIZE];
-       UINT32 attr;
        UINT8 *VarData;
        UINTN VarLen;
+       UINT32 attr;
+       EFI_STATUS status;
 
-       /* first check is MokSBState.  If we're in insecure mode, boot
+       /* Secure Boot Override: MokSBState.  If we're in insecure mode, boot
         * anyway regardless of dbx contents */
        status = get_variable_attr(L"MokSBState", &VarData, &VarLen,
                                   MOK_OWNER, &attr);
@@ -70,17 +68,44 @@
                FreePool(VarData);
                if ((attr & EFI_VARIABLE_RUNTIME_ACCESS) == 0
                    && MokSBState)
-                       return EFI_SUCCESS;
+                       return TRUE;
        }
+       return FALSE;
+}
+
+BOOLEAN security_policy_mok_deny(VOID *data, UINTN len)
+{
+       EFI_STATUS status;
+       UINT8 hash[SHA256_DIGEST_SIZE];
 
        status = sha256_get_pecoff_digest_mem(data, len, hash);
        if (status != EFI_SUCCESS)
-               return status;
+               return TRUE;
 
        if (find_in_variable_esl(L"dbx", SIG_DB, hash, SHA256_DIGEST_SIZE)
            == EFI_SUCCESS)
                /* MOK list cannot override dbx */
-               return EFI_SECURITY_VIOLATION;
+               return FALSE;
+
+       if (find_in_variable_esl(L"MokListX", SIG_DB, hash, SHA256_DIGEST_SIZE)
+           == EFI_SUCCESS)
+               return TRUE;
+
+       return FALSE;
+}
+
+BOOLEAN security_policy_mok_allow(VOID *data, UINTN len)
+{
+       EFI_STATUS status;
+       UINT8 hash[SHA256_DIGEST_SIZE];
+       UINT32 attr;
+       UINT8 *VarData;
+       UINTN VarLen;
+
+
+       status = sha256_get_pecoff_digest_mem(data, len, hash);
+       if (status != EFI_SUCCESS)
+               return TRUE;
 
        status = get_variable_attr(L"MokList", &VarData, &VarLen, MOK_OWNER,
                                   &attr);
@@ -93,37 +118,26 @@
                goto check_tmplist;
 
        if (find_in_variable_esl(L"MokList", MOK_OWNER, hash, 
SHA256_DIGEST_SIZE) == EFI_SUCCESS)
-               return EFI_SUCCESS;
+               return TRUE;
 
  check_tmplist:
        if (security_policy_esl
            && find_in_esl(security_policy_esl, security_policy_esl_len, hash,
                           SHA256_DIGEST_SIZE) == EFI_SUCCESS)
-               return EFI_SUCCESS;
+               return TRUE;
 
-       return EFI_SECURITY_VIOLATION;
+       return FALSE;
 }
 
-static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
-static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
+static EFIAPI EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
+static EFIAPI EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
 
-static EFI_STATUS thunk_security_policy_authentication(
-       const EFI_SECURITY_PROTOCOL *This,
-       UINT32 AuthenticationStatus,
-       const EFI_DEVICE_PATH_PROTOCOL *DevicePath
-                                                      ) 
-__attribute__((unused));
+static BOOLEAN(*sp_override)(void) = NULL;
+static POLICY_FUNCTION sp_allow = NULL;
+static POLICY_FUNCTION sp_deny = NULL;
 
-static EFI_STATUS thunk_security2_policy_authentication(
-       const EFI_SECURITY2_PROTOCOL *This,
-       const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
-       VOID *FileBuffer,
-       UINTN FileSize,
-       BOOLEAN BootPolicy
-                                                      ) 
-__attribute__((unused));
-
-static __attribute__((used)) EFI_STATUS
+EFI_STATUS
+EFIAPI
 security2_policy_authentication (
        const EFI_SECURITY2_PROTOCOL *This,
        const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
@@ -132,29 +146,31 @@
        BOOLEAN BootPolicy
                                 )
 {
-       EFI_STATUS status, auth;
+       EFI_STATUS status;
+
+       if (sp_override && sp_override())
+               return EFI_SUCCESS;
+
+       /* if policy would deny, fail now  */
+       if (sp_deny && sp_deny(FileBuffer, FileSize))
+               return EFI_SECURITY_VIOLATION;
 
        /* Chain original security policy */
 
-       status = uefi_call_wrapper(es2fa, 5, This, DevicePath, FileBuffer,
-                                  FileSize, BootPolicy);
+       status = es2fa(This, DevicePath, FileBuffer, FileSize, BootPolicy);
 
-       /* if OK, don't bother with MOK check */
+       /* if OK, don't bother with allow check */
        if (status == EFI_SUCCESS)
                return status;
 
-       auth = security_policy_check_mok(FileBuffer, FileSize);
-
-       if (auth == EFI_SECURITY_VIOLATION || auth == EFI_ACCESS_DENIED)
-               /* return previous status, which is the correct one
-                * for the platform: may be either EFI_ACCESS_DENIED
-                * or EFI_SECURITY_VIOLATION */
-               return status;
+       if (sp_allow && sp_allow(FileBuffer, FileSize))
+               return EFI_SUCCESS;
 
-       return auth;
+       return status;
 }
 
-static __attribute__((used)) EFI_STATUS
+EFI_STATUS
+EFIAPI
 security_policy_authentication (
        const EFI_SECURITY_PROTOCOL *This,
        UINT32 AuthenticationStatus,
@@ -171,21 +187,17 @@
        UINTN FileSize;
        CHAR16* DevPathStr;
 
-       /* Chain original security policy */
-       status = uefi_call_wrapper(esfas, 3, This, AuthenticationStatus,
-                                  DevicePathConst);
+       if (sp_override && sp_override())
+               return EFI_SUCCESS;
 
-       /* if OK avoid checking MOK: It's a bit expensive to
-        * read the whole file in again (esfas already did this) */
-       if (status == EFI_SUCCESS)
-               goto out;
+       /* Chain original security policy */
+       status = esfas(This, AuthenticationStatus, DevicePathConst);
 
        /* capture failure status: may be either EFI_ACCESS_DENIED or
         * EFI_SECURITY_VIOLATION */
        fail_status = status;
 
-       status = uefi_call_wrapper(BS->LocateDevicePath, 3,
-                                  &SIMPLE_FS_PROTOCOL, &DevPath, &h);
+       status = BS->LocateDevicePath(&SIMPLE_FS_PROTOCOL, &DevPath, &h);
        if (status != EFI_SUCCESS)
                goto out;
 
@@ -202,117 +214,38 @@
        if (status != EFI_SUCCESS)
                goto out;
 
-       status = security_policy_check_mok(FileBuffer, FileSize);
-       FreePool(FileBuffer);
+       status = EFI_SECURITY_VIOLATION;
+       if (sp_deny && sp_deny(FileBuffer, FileSize))
+               goto out;
+
+       status = fail_status;
+       if (status == EFI_SUCCESS)
+               goto out;
+
+       /* fail status is platform security failure now */
+
+       if (sp_allow && sp_allow(FileBuffer, FileSize))
+               status = EFI_SUCCESS;
 
-       if (status == EFI_ACCESS_DENIED || status == EFI_SECURITY_VIOLATION)
-               /* return what the platform originally said */
-               status = fail_status;
  out:
-       FreePool(OrigDevPath);
+       if (FileBuffer)
+               FreePool(FileBuffer);
+       if (OrigDevPath)
+               FreePool(OrigDevPath);
        return status;
 }
 
-
-/* Nasty: ELF and EFI have different calling conventions.  Here is the map for
- * calling ELF -> EFI
- *
- *   1) rdi -> rcx (32 saved)
- *   2) rsi -> rdx (32 saved)
- *   3) rdx -> r8 ( 32 saved)
- *   4) rcx -> r9 (32 saved)
- *   5) r8 -> 32(%rsp) (48 saved)
- *   6) r9 -> 40(%rsp) (48 saved)
- *   7) pad+0(%rsp) -> 48(%rsp) (64 saved)
- *   8) pad+8(%rsp) -> 56(%rsp) (64 saved)
- *   9) pad+16(%rsp) -> 64(%rsp) (80 saved)
- *  10) pad+24(%rsp) -> 72(%rsp) (80 saved)
- *  11) pad+32(%rsp) -> 80(%rsp) (96 saved)
-
- *
- * So for a five argument callback, the map is ignore the first two arguments
- * and then map (EFI -> ELF) assuming pad = 0.
- *
- * ARG4  -> ARG1
- * ARG3  -> ARG2
- * ARG5  -> ARG3
- * ARG6  -> ARG4
- * ARG11 -> ARG5
- *
- * Calling conventions also differ over volatile and preserved registers in
- * MS: RBX, RBP, RDI, RSI, R12, R13, R14, and R15 are considered nonvolatile .
- * In ELF: Registers %rbp, %rbx and %r12 through %r15 “belong” to the 
calling
- * function and the called function is required to preserve their values.
- *
- * This means when accepting a function callback from MS -> ELF, we have to do
- * separate preservation on %rdi, %rsi before swizzling the arguments and
- * handing off to the ELF function.
- */
-
-asm (
-".type security2_policy_authentication,@function\n"
-"thunk_security2_policy_authentication:\n\t"
-       "mov    0x28(%rsp), %r10        # ARG5\n\t"
-       "push   %rdi\n\t"
-       "push   %rsi\n\t"
-       "mov    %r10, %rdi\n\t"
-       "subq   $8, %rsp        # space for storing stack pad\n\t"
-       "mov    $0x08, %rax\n\t"
-       "mov    $0x10, %r10\n\t"
-       "and    %rsp, %rax\n\t"
-       "cmovnz %rax, %r11\n\t"
-       "cmovz  %r10, %r11\n\t"
-       "subq   %r11, %rsp\n\t"
-       "addq   $8, %r11\n\t"
-       "mov    %r11, (%rsp)\n\t"
-"# five argument swizzle\n\t"
-       "mov    %rdi, %r10\n\t"
-       "mov    %rcx, %rdi\n\t"
-       "mov    %rdx, %rsi\n\t"
-       "mov    %r8, %rdx\n\t"
-       "mov    %r9, %rcx\n\t"
-       "mov    %r10, %r8\n\t"
-       "callq  security2_policy_authentication@PLT\n\t"
-       "mov    (%rsp), %r11\n\t"
-       "addq   %r11, %rsp\n\t"
-       "pop    %rsi\n\t"
-       "pop    %rdi\n\t"
-       "ret\n"
-);
-
-asm (
-".type security_policy_authentication,@function\n"
-"thunk_security_policy_authentication:\n\t"
-       "push   %rdi\n\t"
-       "push   %rsi\n\t"
-       "subq   $8, %rsp        # space for storing stack pad\n\t"
-       "mov    $0x08, %rax\n\t"
-       "mov    $0x10, %r10\n\t"
-       "and    %rsp, %rax\n\t"
-       "cmovnz %rax, %r11\n\t"
-       "cmovz  %r10, %r11\n\t"
-       "subq   %r11, %rsp\n\t"
-       "addq   $8, %r11\n\t"
-       "mov    %r11, (%rsp)\n\t"
-"# three argument swizzle\n\t"
-       "mov    %rcx, %rdi\n\t"
-       "mov    %rdx, %rsi\n\t"
-       "mov    %r8, %rdx\n\t"
-       "callq  security_policy_authentication@PLT\n\t"
-       "mov    (%rsp), %r11\n\t"
-       "addq   %r11, %rsp\n\t"
-       "pop    %rsi\n\t"
-       "pop    %rdi\n\t"
-       "ret\n"
-);
-
 EFI_STATUS
-security_policy_install(void)
+security_policy_install(BOOLEAN (*override)(void), POLICY_FUNCTION allow, 
POLICY_FUNCTION deny)
 {
        EFI_SECURITY_PROTOCOL *security_protocol;
        EFI_SECURITY2_PROTOCOL *security2_protocol = NULL;
        EFI_STATUS status;
 
+       sp_override = override;
+       sp_allow = allow;
+       sp_deny = deny;
+
        if (esfas)
                /* Already Installed */
                return EFI_ALREADY_STARTED;
@@ -320,13 +253,11 @@
        /* Don't bother with status here.  The call is allowed
         * to fail, since SECURITY2 was introduced in PI 1.2.1
         * If it fails, use security2_protocol == NULL as indicator */
-       uefi_call_wrapper(BS->LocateProtocol, 3,
-                         &SECURITY2_PROTOCOL_GUID, NULL,
-                         &security2_protocol);
-
-       status = uefi_call_wrapper(BS->LocateProtocol, 3,
-                                          &SECURITY_PROTOCOL_GUID, NULL,
-                                          &security_protocol);
+       BS->LocateProtocol(&SECURITY2_PROTOCOL_GUID, NULL,
+                          (VOID **)&security2_protocol);
+
+       status = BS->LocateProtocol(&SECURITY_PROTOCOL_GUID, NULL,
+                                   (VOID **)&security_protocol);
        if (status != EFI_SUCCESS)
                /* This one is mandatory, so there's a serious problem */
                return status;
@@ -334,19 +265,19 @@
        if (security2_protocol) {
                es2fa = security2_protocol->FileAuthentication;
                security2_protocol->FileAuthentication = 
-                       thunk_security2_policy_authentication;
+                       security2_policy_authentication;
                /* check for security policy in write protected memory */
                if (security2_protocol->FileAuthentication
-                   !=  thunk_security2_policy_authentication)
+                   !=  security2_policy_authentication)
                        return EFI_ACCESS_DENIED;
        }
 
        esfas = security_protocol->FileAuthenticationState;
        security_protocol->FileAuthenticationState =
-               thunk_security_policy_authentication;
+               security_policy_authentication;
        /* check for security policy in write protected memory */
        if (security_protocol->FileAuthenticationState
-           !=  thunk_security_policy_authentication)
+           !=  security_policy_authentication)
                return EFI_ACCESS_DENIED;
 
        return EFI_SUCCESS;
@@ -360,9 +291,8 @@
        if (esfas) {
                EFI_SECURITY_PROTOCOL *security_protocol;
 
-               status = uefi_call_wrapper(BS->LocateProtocol, 3,
-                                          &SECURITY_PROTOCOL_GUID, NULL,
-                                          &security_protocol);
+               status = BS->LocateProtocol(&SECURITY_PROTOCOL_GUID, NULL,
+                                           (VOID **)&security_protocol);
 
                if (status != EFI_SUCCESS)
                        return status;
@@ -377,9 +307,8 @@
        if (es2fa) {
                EFI_SECURITY2_PROTOCOL *security2_protocol;
 
-               status = uefi_call_wrapper(BS->LocateProtocol, 3,
-                                          &SECURITY2_PROTOCOL_GUID, NULL,
-                                          &security2_protocol);
+               status = BS->LocateProtocol(&SECURITY2_PROTOCOL_GUID, NULL,
+                                           (VOID **)&security2_protocol);
 
                if (status != EFI_SUCCESS)
                        return status;
diff -Nru efitools-1.4.2/lib/sha256.c efitools-1.8.1/lib/sha256.c
--- efitools-1.4.2/lib/sha256.c 2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/sha256.c 2018-02-21 03:53:05.000000000 +0000
@@ -20,18 +20,19 @@
 
 #include <efi/efi.h>
 #include <efi/efilib.h>
+#ifdef CONFIG_arm
+#ifndef BUILD_EFI
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
+#endif
 
 #include <sha256.h>
 #include <pecoff.h>
 #include <simple_file.h>
-
-#ifndef BUILD_EFI
-#define Print(...) do { } while(0)
-#define AllocatePool(x) malloc(x)
-#define CopyMem(d, s, l) memcpy(d, s, l)
-#define ZeroMem(s, l) memset(s, 0, l)
-#define FreePool(s) free(s)
-#endif
+#include <buildefi.h>
 
 #define GET_UINT32(n,b,i)                       \
 {                                               \
@@ -281,8 +282,13 @@
        unsigned int hashsize;
        EFI_IMAGE_SECTION_HEADER *section;
        EFI_IMAGE_SECTION_HEADER **sections;
-       int  i, sum_of_bytes;
+       int  i, sum_of_bytes, checksum_size;
        EFI_STATUS efi_status;
+       void *checksum_ptr;
+
+       /* add extra end alignment; rely on data buffer being zero
+        * filled to the end of the page */
+       DataSize = ALIGN_VALUE(DataSize, 8);
 
        efi_status = pecoff_read_header(&context, buffer);
        if (efi_status != EFI_SUCCESS) {
@@ -290,7 +296,15 @@
                return efi_status;
        }
                
-       sections = AllocatePool(context.PEHdr->Pe32.FileHeader.NumberOfSections 
* sizeof(*sections));
+       if (context.PEHdr->Pe32.OptionalHeader.Magic == 
EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+               checksum_ptr = &context.PEHdr->Pe32Plus.OptionalHeader.CheckSum;
+               checksum_size = 
sizeof(context.PEHdr->Pe32Plus.OptionalHeader.CheckSum);
+       } else {
+               checksum_ptr = &context.PEHdr->Pe32.OptionalHeader.CheckSum;
+               checksum_size = 
sizeof(context.PEHdr->Pe32.OptionalHeader.CheckSum);
+       }
+
+       sections = AllocatePool(context.NumberOfSections * sizeof(*sections));
        if (!sections)
                return EFI_OUT_OF_RESOURCES;
 
@@ -298,27 +312,26 @@
 
        /* hash start to checksum */
        hashbase = buffer;
-       hashsize = (void *)&context.PEHdr->Pe32.OptionalHeader.CheckSum - 
buffer;
+       hashsize = checksum_ptr - buffer;
                
        sha256_update(&ctx, hashbase, hashsize);
 
        /* hash post-checksum to start of certificate table */
-       hashbase = (void *)&context.PEHdr->Pe32.OptionalHeader.CheckSum + 
sizeof (int);
+       hashbase = checksum_ptr + checksum_size;
        hashsize = (void *)context.SecDir - hashbase;
 
        sha256_update(&ctx, hashbase, hashsize);
                
        /* Hash end of certificate table to end of image header */
-       hashbase = 
&context.PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
 + 1];
-       hashsize = context.PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders -
-         (int) ((void *) 
(&context.PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY
 + 1]) - buffer);
+       hashbase = context.SecDir + 1;
+       hashsize = context.SizeOfHeaders -
+         (int) (hashbase - buffer);
 
        sha256_update(&ctx, hashbase, hashsize);
-       sum_of_bytes = context.PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
+       sum_of_bytes = context.SizeOfHeaders;
        section = (EFI_IMAGE_SECTION_HEADER *) ((char *)context.PEHdr + sizeof 
(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + 
context.PEHdr->Pe32.FileHeader.SizeOfOptionalHeader);
-
        /* Sort the section headers by their data pointers */
-       for (i = 0; i < context.PEHdr->Pe32.FileHeader.NumberOfSections; i++) {
+       for (i = 0; i < context.NumberOfSections; i++) {
                int p = i;
                while (p > 0 && section->PointerToRawData < sections[p - 
1]->PointerToRawData) {
                        sections[p] = sections[p-1];
@@ -327,10 +340,11 @@
                sections[p] = section++;
        }
        /* hash the sorted sections */
-       for (i = 0; i < context.PEHdr->Pe32.FileHeader.NumberOfSections; i++) {
+       for (i = 0; i < context.NumberOfSections; i++) {
                section = sections[i];
                hashbase  = pecoff_image_address(buffer, DataSize, 
section->PointerToRawData);
-               hashsize  = (unsigned int) section->SizeOfRawData;
+               hashsize  = (unsigned int) ALIGN_VALUE(section->SizeOfRawData,
+                                                      context.FileAlignment);
                if (hashsize == 0)
                        continue;
                sha256_update(&ctx, hashbase, hashsize);
@@ -340,7 +354,7 @@
        if (DataSize > sum_of_bytes) {
                /* stuff at end to hash */
                hashbase = buffer + sum_of_bytes;
-               hashsize = (unsigned int)(DataSize - 
context.PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size
 - sum_of_bytes);
+               hashsize = (unsigned int)(DataSize - context.SecDir->Size - 
sum_of_bytes);
                sha256_update(&ctx, hashbase, hashsize);
        }
        sha256_finish(&ctx, hash);
diff -Nru efitools-1.4.2/lib/shell.c efitools-1.8.1/lib/shell.c
--- efitools-1.4.2/lib/shell.c  2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/shell.c  2018-02-21 03:53:05.000000000 +0000
@@ -20,7 +20,7 @@
 
        *argc = 0;
 
-       status = uefi_call_wrapper(BS->HandleProtocol, 3, image, 
&LoadedImageProtocol, (VOID **) &info);
+       status = BS->HandleProtocol(image, &LoadedImageProtocol, (VOID **) 
&info);
        if (EFI_ERROR(status)) {
                Print(L"Failed to get arguments\n");
                return status;
diff -Nru efitools-1.4.2/lib/shim_protocol.c efitools-1.8.1/lib/shim_protocol.c
--- efitools-1.4.2/lib/shim_protocol.c  1970-01-01 01:00:00.000000000 +0100
+++ efitools-1.8.1/lib/shim_protocol.c  2018-02-21 03:53:05.000000000 +0000
@@ -0,0 +1,54 @@
+#include <efi.h>
+#include <efilib.h>
+
+#include <guid.h>
+#include <pecoff.h>
+#include <sha256.h>
+#include <efiauthenticated.h>
+#include <pkcs7verify.h>
+#include <variables.h>
+#include <shim_protocol.h>
+#include <console.h>
+
+static EFI_STATUS shimprotocol_context(void *data, unsigned int size,
+                                      PE_COFF_LOADER_IMAGE_CONTEXT *context)
+{
+       return pecoff_read_header(context, data);
+}
+
+static EFI_STATUS shimprotocol_verify(void *buffer, UINT32 size)
+{
+       EFI_STATUS status;
+
+       if (!variable_is_secureboot() || variable_is_setupmode())
+               return EFI_SUCCESS;
+
+       if (pkcs7verify_deny(buffer, size))
+               return EFI_ACCESS_DENIED;
+
+       if (pkcs7verify_allow(buffer, size))
+               return EFI_SUCCESS;
+
+       return EFI_ACCESS_DENIED;
+
+
+       return status;
+}
+
+static SHIM_LOCK shim_protocol_interface = {
+       .Verify = shimprotocol_verify,
+       .Context = shimprotocol_context,
+};
+static EFI_HANDLE shim_protocol_handle;
+
+EFI_STATUS
+shim_protocol_install(void)
+{
+       return BS->InstallProtocolInterface(&shim_protocol_handle, &MOK_OWNER, 
EFI_NATIVE_INTERFACE, &shim_protocol_interface);
+}
+
+void
+shim_protocol_uninstall(void)
+{
+       BS->UninstallProtocolInterface(shim_protocol_handle, &MOK_OWNER, 
&shim_protocol_interface);
+}
diff -Nru efitools-1.4.2/lib/simple_file.c efitools-1.8.1/lib/simple_file.c
--- efitools-1.4.2/lib/simple_file.c    2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/simple_file.c    2018-02-21 03:53:05.000000000 +0000
@@ -7,6 +7,7 @@
 #include <efi.h>
 #include <efilib.h>
 
+#include <PeImage.h>           /* for ALIGN_VALUE */
 #include <console.h>
 #include <simple_file.h>
 #include <efiauthenticated.h>
@@ -24,23 +25,21 @@
        EFI_FILE_IO_INTERFACE *drive;
        EFI_FILE *root;
 
-       efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
-                                      &SIMPLE_FS_PROTOCOL, &drive);
+       efi_status = BS->HandleProtocol(device, &SIMPLE_FS_PROTOCOL, (VOID 
**)&drive);
 
        if (efi_status != EFI_SUCCESS) {
                Print(L"Unable to find simple file protocol (%d)\n", 
efi_status);
                goto error;
        }
 
-       efi_status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
+       efi_status = drive->OpenVolume(drive, &root);
 
        if (efi_status != EFI_SUCCESS) {
                Print(L"Failed to open drive volume (%d)\n", efi_status);
                goto error;
        }
 
-       efi_status = uefi_call_wrapper(root->Open, 5, root, file, name,
-                                      mode, 0);
+       efi_status = root->Open(root, file, name, mode, 0);
 
  error:
        return efi_status;
@@ -55,8 +54,7 @@
        EFI_DEVICE_PATH *loadpath = NULL;
        CHAR16 *PathName = NULL;
 
-       efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
-                                      &IMAGE_PROTOCOL, &li);
+       efi_status = BS->HandleProtocol(image, &IMAGE_PROTOCOL, (VOID **)&li);
 
        if (efi_status != EFI_SUCCESS)
                return simple_file_open_by_handle(image, name, file, mode);
@@ -87,8 +85,7 @@
        UINTN size = sizeof(buf);
        EFI_FILE_INFO *fi = (void *)buf;
        
-       status = uefi_call_wrapper(file->GetInfo, 4, file, &FILE_INFO,
-                                  &size, fi);
+       status = file->GetInfo(file, &FILE_INFO, &size, fi);
        if (status != EFI_SUCCESS) {
                Print(L"Failed to get file info\n");
                goto out;
@@ -102,13 +99,13 @@
        *count = 0;
        for (;;) {
                UINTN len = sizeof(buf);
-               status = uefi_call_wrapper(file->Read, 3, file, &len, buf);
+               status = file->Read(file, &len, buf);
                if (status != EFI_SUCCESS || len == 0)
                        break;
                (*count)++;
                size += len;
        }
-       uefi_call_wrapper(file->SetPosition, 2, file, 0);
+       file->SetPosition(file, 0);
 
        char *ptr = AllocatePool(size);
        *entries = (EFI_FILE_INFO *)ptr;
@@ -116,8 +113,8 @@
                return EFI_OUT_OF_RESOURCES;
        int i;
        for (i = 0; i < *count; i++) {
-               int len = size;
-               uefi_call_wrapper(file->Read, 3, file, &len, ptr);
+               UINTN len = size;
+               file->Read(file, &len, ptr);
                ptr += len;
                size -= len;
        }
@@ -158,8 +155,7 @@
        fi = (void *)buf;
        
 
-       efi_status = uefi_call_wrapper(file->GetInfo, 4, file, &FILE_INFO,
-                                      size, fi);
+       efi_status = file->GetInfo(file, &FILE_INFO, size, fi);
        if (efi_status != EFI_SUCCESS) {
                Print(L"Failed to get file info\n");
                return efi_status;
@@ -167,12 +163,13 @@
 
        *size = fi->FileSize;
 
-       *buffer = AllocatePool(*size);
+       /* might use memory mapped, so align up to nearest page */
+       *buffer = AllocateZeroPool(ALIGN_VALUE(*size, 4096));
        if (!*buffer) {
                Print(L"Failed to allocate buffer of size %d\n", *size);
                return EFI_OUT_OF_RESOURCES;
        }
-       efi_status = uefi_call_wrapper(file->Read, 3, file, size, *buffer);
+       efi_status = file->Read(file, size, *buffer);
 
        return efi_status;
 }
@@ -183,7 +180,7 @@
 {
        EFI_STATUS efi_status;
 
-       efi_status = uefi_call_wrapper(file->Write, 3, file, &size, buffer);
+       efi_status = file->Write(file, &size, buffer);
 
        return efi_status;
 }
@@ -191,7 +188,7 @@
 void
 simple_file_close(EFI_FILE *file)
 {
-       uefi_call_wrapper(file->Close, 1, file);
+       file->Close(file);
 }
 
 EFI_STATUS
@@ -203,8 +200,8 @@
        CHAR16 **entries;
        int val;
 
-       uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol,
-                         &SIMPLE_FS_PROTOCOL, NULL, &count, &vol_handles);
+       BS->LocateHandleBuffer(ByProtocol, &SIMPLE_FS_PROTOCOL, NULL,
+                              &count, &vol_handles);
 
        if (!count || !vol_handles)
                return EFI_NOT_FOUND;
@@ -221,18 +218,17 @@
                CHAR16 *name;
                EFI_FILE_IO_INTERFACE *drive;
 
-               status = uefi_call_wrapper(BS->HandleProtocol, 3,
-                                          vol_handles[i],
-                                          &SIMPLE_FS_PROTOCOL, &drive);
+               status = BS->HandleProtocol(vol_handles[i],
+                                           &SIMPLE_FS_PROTOCOL,
+                                           (VOID **)&drive);
                if (status != EFI_SUCCESS || !drive)
                        continue;
 
-               status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
+               status = drive->OpenVolume(drive, &root);
                if (status != EFI_SUCCESS)
                        continue;
 
-               status = uefi_call_wrapper(root->GetInfo, 4, root, &FS_INFO,
-                                          &size, fi);
+               status = root->GetInfo(root, &FS_INFO, &size, fi);
                if (status != EFI_SUCCESS)
                        continue;
 
diff -Nru efitools-1.4.2/lib/variables.c efitools-1.8.1/lib/variables.c
--- efitools-1.4.2/lib/variables.c      2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/lib/variables.c      2018-02-21 03:53:05.000000000 +0000
@@ -30,6 +30,7 @@
 #include <sha256.h>
 #include <errors.h>
 
+
 EFI_STATUS
 variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
                    void **out, int *outlen)
@@ -99,7 +100,7 @@
   DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData);
 
   ZeroMem (&Time, sizeof (EFI_TIME));
-  Status = uefi_call_wrapper(RT->GetTime,2, &Time, NULL);
+  Status = RT->GetTime(&Time, NULL);
   if (EFI_ERROR (Status)) {
     FreePool(NewData);
     return Status;
@@ -164,13 +165,13 @@
                return efi_status;
        }
 
-       efi_status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner,
-                                      EFI_VARIABLE_NON_VOLATILE
-                                      | EFI_VARIABLE_RUNTIME_ACCESS 
-                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS
-                                      | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
-                                      | options,
-                                      DataSize, Cert);
+       efi_status = RT->SetVariable(var, &owner,
+                                    EFI_VARIABLE_NON_VOLATILE
+                                    | EFI_VARIABLE_RUNTIME_ACCESS 
+                                    | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                    | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
+                                    | options,
+                                    DataSize, Cert);
 
        return efi_status;
 }
@@ -182,7 +183,7 @@
        UINTN DataSize = sizeof(indications);
        EFI_STATUS efi_status;
 
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, 
L"OsIndicationsSupported", &GV_GUID, NULL, &DataSize, &indications);
+       efi_status = RT->GetVariable(L"OsIndicationsSupported", &GV_GUID, NULL, 
&DataSize, &indications);
        if (efi_status != EFI_SUCCESS)
                return 0;
 
@@ -195,17 +196,17 @@
        UINTN DataSize = sizeof(indications);
        EFI_STATUS efi_status;
 
-       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"OsIndications",
-                                      &GV_GUID,
-                                      EFI_VARIABLE_NON_VOLATILE
-                                      | EFI_VARIABLE_RUNTIME_ACCESS 
-                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS,
-                                      DataSize, &indications);
+       efi_status = RT->SetVariable(L"OsIndications",
+                                    &GV_GUID,
+                                    EFI_VARIABLE_NON_VOLATILE
+                                    | EFI_VARIABLE_RUNTIME_ACCESS 
+                                    | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                                    DataSize, &indications);
 
        if (efi_status != EFI_SUCCESS)
                return efi_status;
 
-       uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0, 
NULL);
+       RT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
        /* does not return */
 
        return EFI_SUCCESS;
@@ -219,8 +220,7 @@
 
        *len = 0;
 
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
-                                      NULL, len, NULL);
+       efi_status = RT->GetVariable(var, &owner, NULL, len, NULL);
        if (efi_status != EFI_BUFFER_TOO_SMALL)
                return efi_status;
 
@@ -228,8 +228,7 @@
        if (!data)
                return EFI_OUT_OF_RESOURCES;
        
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
-                                      attributes, len, *data);
+       efi_status = RT->GetVariable(var, &owner, attributes, len, *data);
 
        if (efi_status != EFI_SUCCESS) {
                FreePool(*data);
@@ -280,14 +279,61 @@
 }
 
 int
+hashes_in_esl(UINT8 *Data, UINTN DataSize, EFI_GUID *hashes[])
+{
+       int count = 0;
+       EFI_SIGNATURE_LIST *CertList;
+
+       certlist_for_each_certentry(CertList, Data, DataSize, DataSize) {
+               int i;
+
+               for (i = 0; i < count; i++) {
+                       if (CompareGuid(&CertList->SignatureType, hashes[i]) == 
0)
+                           goto found_skip;
+               }
+
+               for (i = 0; i < allowed_hashes_size; i++) {
+                       if (CompareGuid(&CertList->SignatureType, 
allowed_hashes[i]) == 0)
+                               goto found;
+               }
+       found_skip:
+               continue;
+
+       found:
+               hashes[count++] = allowed_hashes[i];
+       }
+       return count;
+}
+
+int
+hashes_in_variable(CHAR16* var, EFI_GUID owner, EFI_GUID *hashes[])
+{
+       UINTN DataSize;
+       UINT8 *Data;
+       EFI_STATUS status;
+       int count;
+
+       status = get_variable(var, &Data, &DataSize, owner);
+       if (status == EFI_NOT_FOUND)
+               return 0;
+       if (status != EFI_SUCCESS)
+               return -1;
+
+       count = hashes_in_esl(Data, DataSize, hashes);
+
+       FreePool(Data);
+
+       return count;
+}
+
+int
 variable_is_setupmode(void)
 {
        /* set to 1 because we return true if SetupMode doesn't exist */
        UINT8 SetupMode = 1;
        UINTN DataSize = sizeof(SetupMode);
 
-       uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", &GV_GUID, NULL,
-                         &DataSize, &SetupMode);
+       RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, &SetupMode);
 
        return SetupMode;
 }
@@ -300,8 +346,7 @@
        UINTN DataSize;
 
        DataSize = sizeof(SecureBoot);
-       uefi_call_wrapper(RT->GetVariable, 5, L"SecureBoot", &GV_GUID, NULL,
-                         &DataSize, &SecureBoot);
+       RT->GetVariable(L"SecureBoot", &GV_GUID, NULL, &DataSize, &SecureBoot);
 
        return SecureBoot;
 }
@@ -331,10 +376,10 @@
                status = SetSecureVariable(var, sig, sizeof(sig), owner,
                                           EFI_VARIABLE_APPEND_WRITE, 0);
        else
-               status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner,
-                                          EFI_VARIABLE_NON_VOLATILE
-                                          | EFI_VARIABLE_BOOTSERVICE_ACCESS
-                                          | EFI_VARIABLE_APPEND_WRITE,
-                                          sizeof(sig), sig);
+               status = RT->SetVariable(var, &owner,
+                                        EFI_VARIABLE_NON_VOLATILE
+                                        | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                        | EFI_VARIABLE_APPEND_WRITE,
+                                        sizeof(sig), sig);
        return status;
 }
diff -Nru efitools-1.4.2/Loader.c efitools-1.8.1/Loader.c
--- efitools-1.4.2/Loader.c     2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/Loader.c     2018-02-21 03:53:05.000000000 +0000
@@ -16,6 +16,7 @@
 #include <console.h>
 #include <efiauthenticated.h>
 #include <guid.h>
+#include <execute.h>
 
 CHAR16 *loader = L"\\linux-loader.efi";
 
@@ -65,7 +66,7 @@
 
        InitializeLib(image, systab);
 
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"SecureBoot", 
&GV_GUID, NULL, &DataSize, &SecureBoot);
+       efi_status = RT->GetVariable(L"SecureBoot", &GV_GUID, NULL, &DataSize, 
&SecureBoot);
 
        if (efi_status != EFI_SUCCESS) {
                Print(L"Not a Secure Boot Platform %d\n", efi_status);
@@ -74,10 +75,9 @@
                DataSize = sizeof(SetupMode);
        }
 
-       uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", &GV_GUID, NULL, 
&DataSize, &SetupMode);
+       RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, &SetupMode);
 
-       efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
-                                      &IMAGE_PROTOCOL, &li);
+       efi_status = BS->HandleProtocol(image, &IMAGE_PROTOCOL, (VOID **)&li);
        if (efi_status != EFI_SUCCESS) {
                Print(L"Failed to init loaded image protocol: %d\n", 
efi_status);
                return efi_status;
@@ -91,13 +91,13 @@
        }
 
        if (!SetupMode) {
-               efi_status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image,
-                                              loadpath, NULL, 0, 
&loader_handle);
+               efi_status = BS->LoadImage(FALSE, image, loadpath, NULL,
+                                          0, &loader_handle);
                if (efi_status == EFI_SUCCESS) {
                        /* Image validates - start it */
                        Print(L"Starting file via StartImage\n");
-                       uefi_call_wrapper(BS->StartImage, 3, loader_handle, 
NULL, NULL);
-                       uefi_call_wrapper(BS->UnloadImage, 1, loader_handle);
+                       BS->StartImage(loader_handle, NULL, NULL);
+                       BS->UnloadImage(loader_handle);
                        return EFI_SUCCESS;
                } else {
                        Print(L"Failed to load the image: %d\n", efi_status);
diff -Nru efitools-1.4.2/LockDown.c efitools-1.8.1/LockDown.c
--- efitools-1.4.2/LockDown.c   2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/LockDown.c   2018-02-21 03:53:05.000000000 +0000
@@ -22,7 +22,7 @@
 
        InitializeLib(image, systab);
 
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", 
&GV_GUID, NULL, &DataSize, &SetupMode);
+       efi_status = RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, 
&SetupMode);
 
        if (efi_status != EFI_SUCCESS) {
                Print(L"No SetupMode variable ... is platform secure boot 
enabled?\n");
@@ -36,23 +36,23 @@
 
        Print(L"Platform is in Setup Mode\n");
 
-       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"KEK", &GV_GUID,
-                                      EFI_VARIABLE_NON_VOLATILE
-                                      | EFI_VARIABLE_RUNTIME_ACCESS 
-                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS
-                                      | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
-                                      KEK_auth_len, KEK_auth);
+       efi_status = RT->SetVariable(L"KEK", &GV_GUID,
+                                    EFI_VARIABLE_NON_VOLATILE
+                                    | EFI_VARIABLE_RUNTIME_ACCESS 
+                                    | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                    | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+                                    KEK_auth_len, KEK_auth);
        if (efi_status != EFI_SUCCESS) {
                Print(L"Failed to enroll KEK: %d\n", efi_status);
                return efi_status;
        }
        Print(L"Created KEK Cert\n");
-       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"db", &SIG_DB,
-                                      EFI_VARIABLE_NON_VOLATILE
-                                      | EFI_VARIABLE_RUNTIME_ACCESS 
-                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS
-                                      | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
-                                      DB_auth_len, DB_auth);
+       efi_status = RT->SetVariable(L"db", &SIG_DB,
+                                    EFI_VARIABLE_NON_VOLATILE
+                                    | EFI_VARIABLE_RUNTIME_ACCESS 
+                                    | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                    | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+                                    DB_auth_len, DB_auth);
        if (efi_status != EFI_SUCCESS) {
                Print(L"Failed to enroll db: %d\n", efi_status);
                return efi_status;
@@ -68,12 +68,12 @@
        }
 #endif
        /* PK must be updated with a signed copy of itself */
-       efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"PK", &GV_GUID,
-                                      EFI_VARIABLE_NON_VOLATILE
-                                      | EFI_VARIABLE_RUNTIME_ACCESS 
-                                      | EFI_VARIABLE_BOOTSERVICE_ACCESS
-                                      | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
-                                      PK_auth_len, PK_auth);
+       efi_status = RT->SetVariable(L"PK", &GV_GUID,
+                                    EFI_VARIABLE_NON_VOLATILE
+                                    | EFI_VARIABLE_RUNTIME_ACCESS 
+                                    | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                    | 
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+                                    PK_auth_len, PK_auth);
 
        
        if (efi_status != EFI_SUCCESS) {
@@ -82,7 +82,7 @@
        }
        Print(L"Created PK Cert\n");
        /* enrolling the PK should put us in SetupMode; check this */
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", 
&GV_GUID, NULL, &DataSize, &SetupMode);
+       efi_status = RT->GetVariable(L"SetupMode", &GV_GUID, NULL, &DataSize, 
&SetupMode);
        if (efi_status != EFI_SUCCESS) {
                Print(L"Failed to get SetupMode variable: %d\n", efi_status);
                return efi_status;
@@ -91,7 +91,7 @@
 
        /* finally, check that SecureBoot is enabled */
 
-       efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"SecureBoot", 
&GV_GUID, NULL, &DataSize, &SecureBoot);
+       efi_status = RT->GetVariable(L"SecureBoot", &GV_GUID, NULL, &DataSize, 
&SecureBoot);
 
        if (efi_status != EFI_SUCCESS) {
                Print(L"Failed to get SecureBoot variable: %d\n", efi_status);
diff -Nru efitools-1.4.2/Makefile efitools-1.8.1/Makefile
--- efitools-1.4.2/Makefile     2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/Makefile     2018-02-21 03:53:05.000000000 +0000
@@ -1,7 +1,25 @@
 EFIFILES = HelloWorld.efi LockDown.efi Loader.efi ReadVars.efi UpdateVars.efi \
-       KeyTool.efi HashTool.efi PreLoader.efi SetNull.efi
+       KeyTool.efi HashTool.efi SetNull.efi ShimReplace.efi
 BINARIES = cert-to-efi-sig-list sig-list-to-certs sign-efi-sig-list \
-       hash-to-efi-sig-list efi-readvar efi-updatevar
+       hash-to-efi-sig-list efi-readvar efi-updatevar cert-to-efi-hash-list \
+       flash-var
+
+ifeq ($(ARCH),x86_64)
+EFIFILES += PreLoader.efi
+endif
+
+MSGUID = 77FA9ABD-0359-4D32-BD60-28F4E78F784B
+
+KEYS = PK KEK DB
+EXTRAKEYS = DB1 DB2
+EXTERNALKEYS = ms-uefi ms-kek
+
+ALLKEYS = $(KEYS) $(EXTRAKEYS) $(EXTERNALKEYS)
+
+KEYAUTH = $(ALLKEYS:=.auth)
+KEYUPDATEAUTH = $(ALLKEYS:=-update.auth) $(ALLKEYS:=-pkupdate.auth)
+KEYBLACKLISTAUTH = $(ALLKEYS:=-blacklist.auth)
+KEYHASHBLACKLISTAUTH = $(ALLKEYS:=-hash-blacklist.auth)
 
 export TOPDIR  := $(shell pwd)/
 
@@ -9,7 +27,9 @@
 
 EFISIGNED = $(patsubst %.efi,%-signed.efi,$(EFIFILES))
 
-all: $(EFISIGNED) $(BINARIES) $(MANPAGES) noPK.auth
+all: $(EFISIGNED) $(BINARIES) $(MANPAGES) noPK.auth $(KEYAUTH) \
+       $(KEYUPDATEAUTH) $(KEYBLACKLISTAUTH) $(KEYHASHBLACKLISTAUTH)
+
 
 install: all
        $(INSTALL) -m 755 -d $(MANDIR)
@@ -30,9 +50,6 @@
 
 .SUFFIXES: .crt
 
-PK.crt KEK.crt DB.crt:
-       openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$*/" -keyout $*.key 
-out $@ -days 3650 -nodes -sha256
-
 .KEEP: PK.crt KEK.crt DB.crt PK.key KEK.key DB.key PK.esl DB.esl KEK.esl \
        $(EFIFILES)
 
@@ -49,16 +66,10 @@
        > noPK.esl
 
 noPK.auth: noPK.esl PK.crt sign-efi-sig-list
-       ./sign-efi-sig-list -c PK.crt -k PK.key PK $< $@
-
-PK.auth: PK.esl PK.crt sign-efi-sig-list
-       ./sign-efi-sig-list -c PK.crt -k PK.key PK $< $@
-
-KEK.auth: KEK.esl PK.crt sign-efi-sig-list
-       ./sign-efi-sig-list -c PK.crt -k PK.key KEK $< $@
+       ./sign-efi-sig-list -t "$(shell date --date='1 second' +'%Y-%m-%d 
%H:%M:%S')" -c PK.crt -k PK.key PK $< $@
 
-DB.auth: DB.esl KEK.crt sign-efi-sig-list
-       ./sign-efi-sig-list -c KEK.crt -k KEK.key db $< $@
+ms-%.esl: ms-%.crt cert-to-efi-sig-list
+       ./cert-to-efi-sig-list -g $(MSGUID) $< $@
 
 hashlist.h: HashTool.hash
        cat $^ > /tmp/tmp.hash
@@ -74,32 +85,41 @@
 HashTool.so: lib/lib-efi.a
 PreLoader.so: lib/lib-efi.a
 HelloWorld.so: lib/lib-efi.a
+ShimReplace.so: lib/lib-efi.a
 
 cert-to-efi-sig-list: cert-to-efi-sig-list.o lib/lib.a
-       $(CC) -o $@ $< -lcrypto lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
 
 sig-list-to-certs: sig-list-to-certs.o lib/lib.a
-       $(CC) -o $@ $< -lcrypto lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
 
 sign-efi-sig-list: sign-efi-sig-list.o lib/lib.a
-       $(CC) -o $@ $< -lcrypto lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
 
 hash-to-efi-sig-list: hash-to-efi-sig-list.o lib/lib.a
-       $(CC) -o $@ $< lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< lib/lib.a
+
+cert-to-efi-hash-list: cert-to-efi-hash-list.o lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
 
 efi-keytool: efi-keytool.o lib/lib.a
-       $(CC) -o $@ $< lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< lib/lib.a
 
 efi-readvar: efi-readvar.o lib/lib.a
-       $(CC) -o $@ $< -lcrypto lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
 
 efi-updatevar: efi-updatevar.o lib/lib.a
-       $(CC) -o $@ $< -lcrypto lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< -lcrypto lib/lib.a
+
+flash-var: flash-var.o lib/lib.a
+       $(CC) $(ARCH3264) -o $@ $< lib/lib.a
 
 clean:
        rm -f PK.* KEK.* DB.* $(EFIFILES) $(EFISIGNED) $(BINARIES) *.o *.so
+       rm -f noPK.*
        rm -f doc/*.1
        $(MAKE) -C lib clean
+       $(MAKE) -C lib/asn1 clean
 
 FORCE:
 
diff -Nru efitools-1.4.2/Make.rules efitools-1.8.1/Make.rules
--- efitools-1.4.2/Make.rules   2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/Make.rules   2018-02-21 03:53:05.000000000 +0000
@@ -1,21 +1,32 @@
 EFISIGNED = $(patsubst %.efi,%-signed.efi,$(EFIFILES))
 MANPAGES = $(patsubst doc/%.1.in,doc/%.1,$(wildcard doc/*.1.in))
 HELP2MAN = help2man
-ARCH   = $(shell uname -m)
+ARCH    = $(shell uname -m | sed 's/i.86/ia32/;s/arm.*/arm/')
+ifeq ($(ARCH),ia32)
+ARCH3264 = -m32
+else ifeq ($(ARCH),x86_64)
+ARCH3264 =
+else ifeq ($(ARCH),aarch64)
+ARCH3264 =
+else ifeq ($(ARCH),arm)
+ARCH3264 =
+else
+$(error unknown architecture $(ARCH))
+endif
 INCDIR    = -I$(TOPDIR)include/ -I/usr/include/efi -I/usr/include/efi/$(ARCH) 
-I/usr/include/efi/protocol
 CPPFLAGS   = -DCONFIG_$(ARCH)
-CFLAGS    = -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing 
-fno-merge-constants -mno-red-zone -fno-stack-protector -g
+CFLAGS    = -O2 -g $(ARCH3264) -fpic -Wall -fshort-wchar -fno-strict-aliasing 
-fno-merge-constants -fno-stack-protector -ffreestanding -fno-stack-check
 LDFLAGS           = -nostdlib
 CRTOBJ         = crt0-efi-$(ARCH).o
-CRTPATHS       = /lib /lib64 /lib/efi /lib64/efi /usr/lib /usr/lib64 
/usr/lib/efi /usr/lib64/efi
+CRTPATHS       = /lib /lib64 /lib/efi /lib64/efi /usr/lib /usr/lib64 
/usr/lib/efi /usr/lib64/efi /usr/lib/gnuefi /usr/lib64/gnuefi
 CRTPATH                = $(shell for f in $(CRTPATHS); do if [ -e 
$$f/$(CRTOBJ) ]; then echo $$f; break; fi; done)
 CRTOBJS                = $(CRTPATH)/$(CRTOBJ)
 # there's a bug in the gnu tools ... the .reloc section has to be
 # aligned otherwise the file alignment gets screwed up
-LDSCRIPT       = $(TOPDIR)/elf_$(ARCH)_efi.lds
-LDFLAGS                += -T $(LDSCRIPT) -shared -Bsymbolic $(CRTOBJS) -L 
$(CRTPATH)
-LOADLIBES      = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
-FORMAT         = efi-app-$(ARCH)
+LDSCRIPT       = elf_$(ARCH)_efi.lds
+LDFLAGS                += -shared -Bsymbolic $(CRTOBJS) -L $(CRTPATH) -L 
/usr/lib -L /usr/lib64 -T $(LDSCRIPT)
+LOADLIBES      = -lefi -lgnuefi $(shell $(CC) $(ARCH3264) 
-print-libgcc-file-name)
+FORMAT         = --target=efi-app-$(ARCH)
 OBJCOPY                = objcopy
 MYGUID         = 11111111-2222-3333-4444-123456789abc
 INSTALL                = install
@@ -24,14 +35,31 @@
 EFIDIR         = $(DESTDIR)/usr/share/efitools/efi
 DOCDIR         = $(DESTDIR)/usr/share/efitools
 
+# globally use EFI calling conventions (requires gcc >= 4.7)
+CFLAGS += -DGNU_EFI_USE_MS_ABI
+
 ifeq ($(ARCH),x86_64)
-  CFLAGS += -DEFI_FUNCTION_WRAPPER
+  CFLAGS += -DEFI_FUNCTION_WRAPPER -mno-red-zone
 endif
 
-%.efi: %.so
-       $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
-               -j .rela -j .reloc --target=$(FORMAT) $*.so $@
+ifeq ($(ARCH),ia32)
+  CFLAGS += -mno-red-zone
+endif
 
+ifeq ($(ARCH),arm)
+  LDFLAGS += --defsym=EFI_SUBSYSTEM=0x0a
+  FORMAT = -O binary
+endif
+
+ifeq ($(ARCH),aarch64)
+  LDFLAGS += --defsym=EFI_SUBSYSTEM=0x0a
+  FORMAT = -O binary
+endif
+
+%.efi: %.so
+       $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
+                  -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
+                  -j .reloc $(FORMAT) $*.so $@
 %.so: %.o
        $(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES)
        # check we have no undefined symbols
@@ -43,9 +71,33 @@
 %.hash: %.efi hash-to-efi-sig-list
        ./hash-to-efi-sig-list $< $@
 
+%-blacklist.esl: %.crt cert-to-efi-hash-list
+       ./cert-to-efi-sig-list $< $@
+
+%-hash-blacklist.esl: %.crt cert-to-efi-hash-list
+       ./cert-to-efi-hash-list $< $@
+
 %.esl: %.crt cert-to-efi-sig-list
        ./cert-to-efi-sig-list -g $(MYGUID) $< $@
 
+getcert = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo "-c PK.crt 
-k PK.key"; else echo "-c KEK.crt -k KEK.key"; fi)
+getvar = $(shell if [ "$(1)" = "PK" -o "$(1)" = "KEK" ]; then echo $(1); else 
echo db; fi)
+
+%.auth: %.esl PK.crt KEK.crt sign-efi-sig-list
+       ./sign-efi-sig-list $(call getcert,$*) $(call getvar,$*) $< $@
+
+%-update.auth: %.esl PK.crt KEK.crt sign-efi-sig-list
+       ./sign-efi-sig-list -a $(call getcert,$*) $(call getvar,$*) $< $@
+
+%-pkupdate.auth: %.esl PK.crt sign-efi-sig-list
+       ./sign-efi-sig-list -a -c PK.crt -k PK.key $(call getvar,$*) $< $@
+
+%-blacklist.auth: %-blacklist.esl KEK.crt sign-efi-sig-list
+       ./sign-efi-sig-list -a -c KEK.crt -k KEK.key dbx $< $@
+
+%-pkblacklist.auth: %-blacklist.esl PK.crt sign-efi-sig-list
+       ./sign-efi-sig-list -a -c PK.crt -k PK.key dbx $< $@
+
 %.o: %.c
        $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
 
@@ -55,6 +107,8 @@
 %.efi.s: %.c
        $(CC) -S $(INCDIR) $(CFLAGS) $(CPPFLAGS) -fno-toplevel-reorder 
-DBUILD_EFI -c $< -o $@
 
+%.crt:
+       openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$*/" -keyout $*.key 
-out $@ -days 3650 -nodes -sha256
 
 %.cer: %.crt
        openssl x509 -in $< -out $@ -outform DER
diff -Nru efitools-1.4.2/ms-kek.crt efitools-1.8.1/ms-kek.crt
--- efitools-1.4.2/ms-kek.crt   1970-01-01 01:00:00.000000000 +0100
+++ efitools-1.8.1/ms-kek.crt   2018-02-21 03:53:05.000000000 +0000
@@ -0,0 +1,121 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            61:0a:d1:88:00:00:00:00:00:03
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, 
CN=Microsoft Corporation Third Party Marketplace Root
+        Validity
+            Not Before: Jun 24 20:41:29 2011 GMT
+            Not After : Jun 24 20:51:29 2026 GMT
+        Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, 
CN=Microsoft Corporation KEK CA 2011
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c4:e8:b5:8a:bf:ad:57:26:b0:26:c3:ea:e7:fb:
+                    57:7a:44:02:5d:07:0d:da:4a:e5:74:2a:e6:b0:0f:
+                    ec:6d:eb:ec:7f:b9:e3:5a:63:32:7c:11:17:4f:0e:
+                    e3:0b:a7:38:15:93:8e:c6:f5:e0:84:b1:9a:9b:2c:
+                    e7:f5:b7:91:d6:09:e1:e2:c0:04:a8:ac:30:1c:df:
+                    48:f3:06:50:9a:64:a7:51:7f:c8:85:4f:8f:20:86:
+                    ce:fe:2f:e1:9f:ff:82:c0:ed:e9:cd:ce:f4:53:6a:
+                    62:3a:0b:43:b9:e2:25:fd:fe:05:f9:d4:c4:14:ab:
+                    11:e2:23:89:8d:70:b7:a4:1d:4d:ec:ae:e5:9c:fa:
+                    16:c2:d7:c1:cb:d4:e8:c4:2f:e5:99:ee:24:8b:03:
+                    ec:8d:f2:8b:ea:c3:4a:fb:43:11:12:0b:7e:b5:47:
+                    92:6c:dc:e6:04:89:eb:f5:33:04:eb:10:01:2a:71:
+                    e5:f9:83:13:3c:ff:25:09:2f:68:76:46:ff:ba:4f:
+                    be:dc:ad:71:2a:58:aa:fb:0e:d2:79:3d:e4:9b:65:
+                    3b:cc:29:2a:9f:fc:72:59:a2:eb:ae:92:ef:f6:35:
+                    13:80:c6:02:ec:e4:5f:cc:9d:76:cd:ef:63:92:c1:
+                    af:79:40:84:79:87:7f:e3:52:a8:e8:9d:7b:07:69:
+                    8f:15
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            1.3.6.1.4.1.311.21.1: 
+                ...
+            X509v3 Subject Key Identifier: 
+                62:FC:43:CD:A0:3E:A4:CB:67:12:D2:5B:D9:55:AC:7B:CC:B6:8A:5F
+            1.3.6.1.4.1.311.20.2: 
+                .
+.S.u.b.C.A
+            X509v3 Key Usage: 
+                Digital Signature, Certificate Sign, CRL Sign
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Authority Key Identifier: 
+                
keyid:45:66:52:43:E1:7E:58:11:BF:D6:4E:9E:23:55:08:3B:3A:22:6A:A8
+
+            X509v3 CRL Distribution Points: 
+
+                Full Name:
+                  
URI:http://crl.microsoft.com/pki/crl/products/MicCorThiParMarRoo_2010-10-05.crl
+
+            Authority Information Access: 
+                CA Issuers - 
URI:http://www.microsoft.com/pki/certs/MicCorThiParMarRoo_2010-10-05.crt
+
+    Signature Algorithm: sha256WithRSAEncryption
+         d4:84:88:f5:14:94:18:02:ca:2a:3c:fb:2a:92:1c:0c:d7:a0:
+         d1:f1:e8:52:66:a8:ee:a2:b5:75:7a:90:00:aa:2d:a4:76:5a:
+         ea:79:b7:b9:37:6a:51:7b:10:64:f6:e1:64:f2:02:67:be:f7:
+         a8:1b:78:bd:ba:ce:88:58:64:0c:d6:57:c8:19:a3:5f:05:d6:
+         db:c6:d0:69:ce:48:4b:32:b7:eb:5d:d2:30:f5:c0:f5:b8:ba:
+         78:07:a3:2b:fe:9b:db:34:56:84:ec:82:ca:ae:41:25:70:9c:
+         6b:e9:fe:90:0f:d7:96:1f:e5:e7:94:1f:b2:2a:0c:8d:4b:ff:
+         28:29:10:7b:f7:d7:7c:a5:d1:76:b9:05:c8:79:ed:0f:90:92:
+         9c:c2:fe:df:6f:7e:6c:0f:7b:d4:c1:45:dd:34:51:96:39:0f:
+         e5:5e:56:d8:18:05:96:f4:07:a6:42:b3:a0:77:fd:08:19:f2:
+         71:56:cc:9f:86:23:a4:87:cb:a6:fd:58:7e:d4:69:67:15:91:
+         7e:81:f2:7f:13:e5:0d:8b:8a:3c:87:84:eb:e3:ce:bd:43:e5:
+         ad:2d:84:93:8e:6a:2b:5a:7c:44:fa:52:aa:81:c8:2d:1c:bb:
+         e0:52:df:00:11:f8:9a:3d:c1:60:b0:e1:33:b5:a3:88:d1:65:
+         19:0a:1a:e7:ac:7c:a4:c1:82:87:4e:38:b1:2f:0d:c5:14:87:
+         6f:fd:8d:2e:bc:39:b6:e7:e6:c3:e0:e4:cd:27:84:ef:94:42:
+         ef:29:8b:90:46:41:3b:81:1b:67:d8:f9:43:59:65:cb:0d:bc:
+         fd:00:92:4f:f4:75:3b:a7:a9:24:fc:50:41:40:79:e0:2d:4f:
+         0a:6a:27:76:6e:52:ed:96:69:7b:af:0f:f7:87:05:d0:45:c2:
+         ad:53:14:81:1f:fb:30:04:aa:37:36:61:da:4a:69:1b:34:d8:
+         68:ed:d6:02:cf:6c:94:0c:d3:cf:6c:22:79:ad:b1:f0:bc:03:
+         a2:46:60:a9:c4:07:c2:21:82:f1:fd:f2:e8:79:32:60:bf:d8:
+         ac:a5:22:14:4b:ca:c1:d8:4b:eb:7d:3f:57:35:b2:e6:4f:75:
+         b4:b0:60:03:22:53:ae:91:79:1d:d6:9b:41:1f:15:86:54:70:
+         b2:de:0d:35:0f:7c:b0:34:72:ba:97:60:3b:f0:79:eb:a2:b2:
+         1c:5d:a2:16:b8:87:c5:e9:1b:f6:b5:97:25:6f:38:9f:e3:91:
+         fa:8a:79:98:c3:69:0e:b7:a3:1c:20:05:97:f8:ca:14:ae:00:
+         d7:c4:f3:c0:14:10:75:6b:34:a0:1b:b5:99:60:f3:5c:b0:c5:
+         57:4e:36:d2:32:84:bf:9e
+-----BEGIN CERTIFICATE-----
+MIIF6DCCA9CgAwIBAgIKYQrRiAAAAAAAAzANBgkqhkiG9w0BAQsFADCBkTELMAkG
+A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
+HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE7MDkGA1UEAxMyTWljcm9z
+b2Z0IENvcnBvcmF0aW9uIFRoaXJkIFBhcnR5IE1hcmtldHBsYWNlIFJvb3QwHhcN
+MTEwNjI0MjA0MTI5WhcNMjYwNjI0MjA1MTI5WjCBgDELMAkGA1UEBhMCVVMxEzAR
+BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
+Y3Jvc29mdCBDb3Jwb3JhdGlvbjEqMCgGA1UEAxMhTWljcm9zb2Z0IENvcnBvcmF0
+aW9uIEtFSyBDQSAyMDExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+xOi1ir+tVyawJsPq5/tXekQCXQcN2krldCrmsA/sbevsf7njWmMyfBEXTw7jC6c4
+FZOOxvXghLGamyzn9beR1gnh4sAEqKwwHN9I8wZQmmSnUX/IhU+PIIbO/i/hn/+C
+wO3pzc70U2piOgtDueIl/f4F+dTEFKsR4iOJjXC3pB1N7K7lnPoWwtfBy9ToxC/l
+me4kiwPsjfKL6sNK+0MREgt+tUeSbNzmBInr9TME6xABKnHl+YMTPP8lCS9odkb/
+uk++3K1xKliq+w7SeT3km2U7zCkqn/xyWaLrrpLv9jUTgMYC7ORfzJ12ze9jksGv
+eUCEeYd/41Ko6J17B2mPFQIDAQABo4IBTzCCAUswEAYJKwYBBAGCNxUBBAMCAQAw
+HQYDVR0OBBYEFGL8Q82gPqTLZxLSW9lVrHvMtopfMBkGCSsGAQQBgjcUAgQMHgoA
+UwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY
+MBaAFEVmUkPhflgRv9ZOniNVCDs6ImqoMFwGA1UdHwRVMFMwUaBPoE2GS2h0dHA6
+Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY0NvclRoaVBh
+ck1hclJvb18yMDEwLTEwLTA1LmNybDBgBggrBgEFBQcBAQRUMFIwUAYIKwYBBQUH
+MAKGRGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljQ29yVGhp
+UGFyTWFyUm9vXzIwMTAtMTAtMDUuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQDUhIj1
+FJQYAsoqPPsqkhwM16DR8ehSZqjuorV1epAAqi2kdlrqebe5N2pRexBk9uFk8gJn
+vveoG3i9us6IWGQM1lfIGaNfBdbbxtBpzkhLMrfrXdIw9cD1uLp4B6Mr/pvbNFaE
+7ILKrkElcJxr6f6QD9eWH+XnlB+yKgyNS/8oKRB799d8pdF2uQXIee0PkJKcwv7f
+b35sD3vUwUXdNFGWOQ/lXlbYGAWW9AemQrOgd/0IGfJxVsyfhiOkh8um/Vh+1Gln
+FZF+gfJ/E+UNi4o8h4Tr4869Q+WtLYSTjmorWnxE+lKqgcgtHLvgUt8AEfiaPcFg
+sOEztaOI0WUZChrnrHykwYKHTjixLw3FFIdv/Y0uvDm25+bD4OTNJ4TvlELvKYuQ
+RkE7gRtn2PlDWWXLDbz9AJJP9HU7p6kk/FBBQHngLU8Kaid2blLtlml7rw/3hwXQ
+RcKtUxSBH/swBKo3NmHaSmkbNNho7dYCz2yUDNPPbCJ5rbHwvAOiRmCpxAfCIYLx
+/fLoeTJgv9ispSIUS8rB2EvrfT9XNbLmT3W0sGADIlOukXkd1ptBHxWGVHCy3g01
+D3ywNHK6l2A78HnrorIcXaIWuIfF6Rv2tZclbzif45H6inmYw2kOt6McIAWX+MoU
+rgDXxPPAFBB1azSgG7WZYPNcsMVXTjbSMoS/ng==
+-----END CERTIFICATE-----
diff -Nru efitools-1.4.2/ms-uefi.crt efitools-1.8.1/ms-uefi.crt
--- efitools-1.4.2/ms-uefi.crt  1970-01-01 01:00:00.000000000 +0100
+++ efitools-1.8.1/ms-uefi.crt  2018-02-21 03:53:05.000000000 +0000
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGEDCCA/igAwIBAgIKYQjTxAAAAAAABDANBgkqhkiG9w0BAQsFADCBkTELMAkG
+A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
+HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE7MDkGA1UEAxMyTWljcm9z
+b2Z0IENvcnBvcmF0aW9uIFRoaXJkIFBhcnR5IE1hcmtldHBsYWNlIFJvb3QwHhcN
+MTEwNjI3MjEyMjQ1WhcNMjYwNjI3MjEzMjQ1WjCBgTELMAkGA1UEBhMCVVMxEzAR
+BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
+Y3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IENvcnBvcmF0
+aW9uIFVFRkkgQ0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AKUIbEzHRQlqSwykwId/BnUMQwFUZOAWfwftkn0LsnO/DArGSkVhoMUWLZbT9Sug
++01Jm0GAkDy5VP3mvNGdxKQYin9BilxZg2gyu4xHye5xvCFPmop8/0Q/jY8ysiZI
+rnW17slMHkoZfuSCmh14d00MsL32D9MW07z6K6VROF31+7rbeALb/+wKG5bVg7gZ
+E+m2wHtAe+EfKCfJ+u9WXhzmfpR+wPBEsnk55dqyYotNvzhw4mgkFMkzpAg31Vhp
+XtN87cEEUwjnTrAqh2MIYW9jFVnqsit51wxhZ4pb/V6th3+6hmdPcVgSIgQiIs6L
+71RxAM5QNVh2lQjuarGiAdUCAwEAAaOCAXYwggFyMBIGCSsGAQQBgjcVAQQFAgMB
+AAEwIwYJKwYBBAGCNxUCBBYEFPjBa7d/d1NK8yU3HU6hJnsPIHCAMB0GA1UdDgQW
+BBQTrb9DCb2CcJyM1U8xbtUimIob1DAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMA
+QTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRFZlJD
+4X5YEb/WTp4jVQg7OiJqqDBcBgNVHR8EVTBTMFGgT6BNhktodHRwOi8vY3JsLm1p
+Y3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNDb3JUaGlQYXJNYXJSb29f
+MjAxMC0xMC0wNS5jcmwwYAYIKwYBBQUHAQEEVDBSMFAGCCsGAQUFBzAChkRodHRw
+Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY0NvclRoaVBhck1hclJv
+b18yMDEwLTEwLTA1LmNydDANBgkqhkiG9w0BAQsFAAOCAgEANQhC/zDMzvd2DK0Q
+aFg1KUYydid87xJBJ0IbSqptgThIWRNV8+lYNKYWC4KqXa2C2oCDQQaPtB3yA7nz
+Gl0b8VCQ+bNVhEIoHCC9sq5RFMXArJeVIRyQ2w/8d56Vc5GIyr29UrkFUA3fV56g
+Ye0N5W0l2UAPF0DIzqNKwk2vmhIdCFSPvce8uSs9SSsfMvxqIWlPm8h+QjT8NgYX
+i48gQMCzmiV1J83JA6P2XdHnNlR6uVC10xLRB7+7dN/cHo+A1e0Y9C8UFmsv3maM
+sCPlx4TY7erBM4KtVksYLfFolQfNz/By8K673YaFmCwhTDMr8A9K8GiHtZJVMnWh
+aoJqPKMlEaTtrdcErsvYQFmghNGVTGKRIhp0HYw9Rw5EpuSwmzQ1sfq2U6gsgeyk
+BXHInbi66BtEZuRHVA6OVn+znxaYsobQaD6QI7UvXo9QhY3GjYJfQaH0Lg3gmdJs
+deS2abUhhvoH0fbiTdHarSx3Ux4lMjfHbFJylYaw8TVhahn1sjuBUFamMi3+oon5
+QoYnGFWhgspam/gwmFQUpkeWJS/IJuRBlBpcAj/lluOFWzw+P7tHFnJV4iUisdl7
+5wMGKqP3HpBGwwAN1hmJ4w41J2IDcRWm79AnoKBZN2D4OJS44Hhw+LpMhoeU9uCu
+AkXuZcK2o35pFnUHkpv1prxZg1g=
+-----END CERTIFICATE-----
diff -Nru efitools-1.4.2/PreLoader.c efitools-1.8.1/PreLoader.c
--- efitools-1.4.2/PreLoader.c  2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/PreLoader.c  2018-02-21 03:53:05.000000000 +0000
@@ -30,8 +30,8 @@
 
        console_reset();
 
-       status = uefi_call_wrapper(RT->GetVariable, 5, L"SecureBoot",
-                                  &GV_GUID, NULL, &DataSize, &SecureBoot);
+       status = RT->GetVariable(L"SecureBoot",
+                                &GV_GUID, NULL, &DataSize, &SecureBoot);
        if (status != EFI_SUCCESS) {
                Print(L"Not a Secure Boot Platform %d\n", status);
                goto override;
@@ -42,7 +42,9 @@
                goto override;
        }
 
-       status = security_policy_install();
+       status = security_policy_install(security_policy_mok_override,
+                                        security_policy_mok_allow,
+                                        security_policy_mok_deny);
        if (status != EFI_SUCCESS) {
                console_error(L"Failed to install override security policy",
                              status);
diff -Nru efitools-1.4.2/ReadVars.c efitools-1.8.1/ReadVars.c
--- efitools-1.4.2/ReadVars.c   2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/ReadVars.c   2018-02-21 03:53:05.000000000 +0000
@@ -16,8 +16,6 @@
 #include <sha256.h>
 #include "efiauthenticated.h"
 
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
 void
 parse_db(UINT8 *data, UINTN len, EFI_HANDLE image, CHAR16 *name, int save_file)
 {
@@ -101,8 +99,8 @@
 efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
 {
        EFI_STATUS status;
-       CHAR16 *variables[] = { L"PK", L"KEK", L"db", L"dbx", L"MokList" };
-       EFI_GUID owners[] = { GV_GUID, GV_GUID, SIG_DB, SIG_DB, MOK_OWNER };
+       CHAR16 **variables;
+       EFI_GUID *owners;
        CHAR16 **ARGV, *progname;
        UINT8 *data;
        UINTN len;
@@ -110,6 +108,14 @@
 
        InitializeLib(image, systab);
 
+       if (GetOSIndications() & EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION) {
+               variables = (CHAR16 *[]){ L"PK", L"KEK", L"db", L"dbx", L"dbt", 
L"MokList" , NULL};
+               owners = (EFI_GUID []){ GV_GUID, GV_GUID, SIG_DB, SIG_DB, 
SIG_DB, MOK_OWNER };
+       } else {
+               variables = (CHAR16 *[]){ L"PK", L"KEK", L"db", L"dbx", 
L"MokList" , NULL};
+               owners = (EFI_GUID []){ GV_GUID, GV_GUID, SIG_DB, SIG_DB, 
MOK_OWNER };
+       }
+
        status = argsplit(image, &argc, &ARGV);
 
        if (status != EFI_SUCCESS) {
@@ -139,7 +145,7 @@
        }
 
        if (argc == 1) {
-               for (i = 0; i < ARRAY_SIZE(owners); i++) {
+               for (i = 0; variables[i] != NULL; i++) {
                        status = get_variable(variables[i], &data, &len, 
owners[i]);
                        if (status == EFI_NOT_FOUND) {
                                Print(L"Variable %s has no entries\n", 
variables[i]);
@@ -154,14 +160,14 @@
        } else {
                CHAR16 *var = ARGV[1];
                
-               for(i = 0; i < ARRAY_SIZE(variables); i++) {
+               for(i = 0; variables[i] != NULL; i++) {
                        if (StrCmp(var, variables[i]) == 0) {
                                break;
                        }
                }
-               if (i == ARRAY_SIZE(variables)) {
+               if (variables[i]== NULL) {
                        Print(L"Invalid Variable %s\nVariable must be one of: 
", var);
-                       for (i = 0; i < ARRAY_SIZE(variables); i++)
+                       for (i = 0; variables[i] != NULL; i++)
                                Print(L"%s ", variables[i]);
                        Print(L"\n");
                        return EFI_INVALID_PARAMETER;
diff -Nru efitools-1.4.2/ShimReplace.c efitools-1.8.1/ShimReplace.c
--- efitools-1.4.2/ShimReplace.c        1970-01-01 01:00:00.000000000 +0100
+++ efitools-1.8.1/ShimReplace.c        2018-02-21 03:53:05.000000000 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 <[email protected]>
+ *
+ * see COPYING file
+ *
+ * Replacement for shim.efi which is signed by your own key
+ * and installs the shim protocol verifier for grub to use
+ * so the secure boot chain is unbroken
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <console.h>
+#include <guid.h>
+#include <efiauthenticated.h>
+#include <execute.h>
+#include <shim_protocol.h>
+#include <pkcs7verify.h>
+
+static const CHAR16 *loader = L"\\grub.efi";
+static const CHAR16 *fallback = L"\\fallback.efi";
+
+EFI_STATUS
+efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
+{
+       EFI_STATUS efi_status;
+       EFI_PKCS7_VERIFY_PROTOCOL *p7vp;
+       CHAR16 *error;
+       void *ptr;
+
+       InitializeLib(image, systab);
+
+       efi_status = pkcs7verify_get_protocol(image, &p7vp, &error);
+
+       if (efi_status != EFI_SUCCESS) {
+               console_error(error, efi_status);
+               return efi_status;
+       }
+
+       efi_status = shim_protocol_install();
+       if (efi_status != EFI_SUCCESS)
+               console_error(L"Failed to install shim protocol", efi_status);
+
+
+       efi_status = BS->LocateProtocol(&MOK_OWNER,
+                                   NULL, &ptr);
+       if (efi_status != EFI_SUCCESS)
+               console_error(L"Failed to locate shim protocol", efi_status);
+
+       efi_status = execute(image, loader);
+       if (efi_status == EFI_SUCCESS)
+               return efi_status;
+
+       console_error(L"Failed to start primary loader", efi_status);
+
+       efi_status = execute(image, fallback);
+
+       if (efi_status != EFI_SUCCESS)
+               console_error(L"Failed to start fallback loader", efi_status);
+
+       return efi_status;
+}
diff -Nru efitools-1.4.2/sig-list-to-certs.c efitools-1.8.1/sig-list-to-certs.c
--- efitools-1.4.2/sig-list-to-certs.c  2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/sig-list-to-certs.c  2018-02-21 03:53:05.000000000 +0000
@@ -6,6 +6,12 @@
 #include <stdint.h>
 #define __STDC_VERSION__ 199901L
 #include <efi.h>
+#ifdef CONFIG_arm
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -25,17 +31,25 @@
 int
 main(int argc, char *argv[])
 {
-       char *certfile, *efifile, *name;
+       char *certfile, *efifile, *name, *esl_name;
        const char *progname = argv[0];
+       int output_esl = 0;
 
-       if (argc != 3) {
+       if (argc != 3 && argc != 4) {
                printf("Usage: %s <efi sig list file> <cert file base name>\n", 
progname);
                exit(1);
        }
 
+       if (strcmp("-e", argv[1]) == 0) {
+               output_esl = 1;
+               argc--;
+               argv++;
+       }
+
        efifile = argv[1];
        certfile = argv[2];
        name = malloc(strlen(certfile)+10);
+       esl_name = malloc(strlen(certfile)+10);
 
        int fd = open(efifile, O_RDONLY);
        if (fd < 0) {
@@ -74,6 +88,8 @@
 
                certentry_for_each_cert(sd, sl) {
 
+                       FILE *g;
+
                        if (memcmp(&sl->SignatureType, &EFI_CERT_X509_GUID, 
sizeof(EFI_GUID)) == 0) {
                                printf("X509 ");
                                ext = "der";
@@ -95,10 +111,17 @@
 
                        EFI_GUID *guid = &sd->SignatureOwner;
 
+                       sprintf(esl_name, "%s-%d.esl",certfile,count);
                        sprintf(name, "%s-%d.%s",certfile,count++,ext);
                        printf("file %s: Guid %s\n", name, guid_to_str(guid));
 
-                       FILE *g = fopen(name, "w");
+                       if (output_esl) {
+                               g = fopen(esl_name, "w");
+                               fwrite(sl, 1, sl->SignatureListSize, g);
+                               fclose(g);
+                       }
+
+                       g = fopen(name, "w");
                        fwrite(sd->SignatureData, 1, sl->SignatureSize - 
OFFSET_OF(EFI_SIGNATURE_DATA, SignatureData), g);
                        printf("Written %d bytes\n", sl->SignatureSize - 
(UINT32)OFFSET_OF(EFI_SIGNATURE_DATA, SignatureData));
                        fclose(g);
diff -Nru efitools-1.4.2/sign-efi-sig-list.c efitools-1.8.1/sign-efi-sig-list.c
--- efitools-1.4.2/sign-efi-sig-list.c  2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/sign-efi-sig-list.c  2018-02-21 03:53:05.000000000 +0000
@@ -6,6 +6,12 @@
 #include <stdint.h>
 #define __STDC_VERSION__ 199901L
 #include <efi.h>
+#ifdef CONFIG_arm
+/* FIXME:
+ * arm efi leaves a visibilit pragma pushed that won't work for
+ * non efi programs, so eliminate it */
+#pragma GCC visibility pop
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -151,23 +157,37 @@
        time_t t;
        struct tm *tm, tms;
 
+       memset(&tms, 0, sizeof(tms));
+
        if (timestampstr) {
-               strptime(timestampstr, "%c", &tms);
+               strptime(timestampstr, "%Y-%m-%d %H:%M:%S", &tms);
+               tm = &tms;
+               /* timestamp.Year is from 0 not 1900 as tm year is */
+               tm->tm_year += 1900;
+               tm->tm_mon += 1; /* tm_mon is 0-11 not 1-12 */
+       } else if (attributes & EFI_VARIABLE_APPEND_WRITE) {
+               /* for append update timestamp should be zero */
+               memset(&tms, 0, sizeof(tms));
                tm = &tms;
        } else {
                time(&t);
-               tm = gmtime(&t);
+               tm = localtime(&t);
+               /* timestamp.Year is from 0 not 1900 as tm year is */
+               tm->tm_year += 1900;
+               tm->tm_mon += 1; /* tm_mon is 0-11 not 1-12 */
        }
 
-       /* FIXME: currently timestamp is one year into future because of
-        * the way we set up the secure environment  */
-       timestamp.Year = tm->tm_year + 1900 + 1;
+       timestamp.Year = tm->tm_year;
        timestamp.Month = tm->tm_mon;
        timestamp.Day = tm->tm_mday;
        timestamp.Hour = tm->tm_hour;
        timestamp.Minute = tm->tm_min;
        timestamp.Second = tm->tm_sec;
 
+       printf("Timestamp is %d-%d-%d %02d:%02d:%02d\n", timestamp.Year,
+              timestamp.Month, timestamp.Day, timestamp.Hour, timestamp.Minute,
+              timestamp.Second);
+
        /* Warning: don't use any glibc wchar functions.  We're building
         * with -fshort-wchar which breaks the glibc ABI */
        i = 0;
@@ -231,6 +251,11 @@
                ERR_load_crypto_strings();
                OpenSSL_add_all_digests();
                OpenSSL_add_all_ciphers();
+               /* here we may get highly unlikely failures or we'll get a
+                * complaint about FIPS signatures (usually becuase the FIPS
+                * module isn't present).  In either case ignore the errors
+                * (malloc will cause other failures out lower down */
+               ERR_clear_error();
 
                BIO *cert_bio = BIO_new_file(certfile, "r");
                X509 *cert = PEM_read_bio_X509(cert_bio, NULL, NULL, NULL);
@@ -248,10 +273,10 @@
 
                BIO *bio_data = BIO_new_mem_buf(signbuf, signbuflen);
        
-               p7 = PKCS7_sign(NULL, NULL, NULL, bio_data, 
PKCS7_BINARY|PKCS7_PARTIAL|PKCS7_DETACHED);
+               p7 = PKCS7_sign(NULL, NULL, NULL, bio_data, 
PKCS7_BINARY|PKCS7_PARTIAL|PKCS7_DETACHED|PKCS7_NOATTR);
                const EVP_MD *md = EVP_get_digestbyname("SHA256");
-               PKCS7_sign_add_signer(p7, cert, pkey, md, 
PKCS7_BINARY|PKCS7_DETACHED);
-               PKCS7_final(p7, bio_data, PKCS7_BINARY|PKCS7_DETACHED);
+               PKCS7_sign_add_signer(p7, cert, pkey, md, 
PKCS7_BINARY|PKCS7_DETACHED|PKCS7_NOATTR);
+               PKCS7_final(p7, bio_data, 
PKCS7_BINARY|PKCS7_DETACHED|PKCS7_NOATTR);
 
 
                sigsize = i2d_PKCS7(p7, NULL);
@@ -271,6 +296,7 @@
                sigbuf = var_auth->AuthInfo.CertData;
        } else {
                sigbuf = var_auth->AuthInfo.CertData;
+               printf("Signature at: %ld\n", sigbuf - (unsigned char 
*)var_auth);
                i2d_PKCS7(p7, &sigbuf);
                ERR_print_errors_fp(stdout);
        }
diff -Nru efitools-1.4.2/UpdateVars.c efitools-1.8.1/UpdateVars.c
--- efitools-1.4.2/UpdateVars.c 2013-09-19 14:14:24.000000000 +0100
+++ efitools-1.8.1/UpdateVars.c 2018-02-21 03:53:05.000000000 +0000
@@ -16,8 +16,6 @@
 #include <shell.h>
 #include "efiauthenticated.h"
 
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
 EFI_STATUS
 efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
 {
@@ -28,12 +26,19 @@
        void *buf;
        UINTN size, options = 0;
        EFI_GUID *owner;
-       CHAR16 *variables[] = { L"PK", L"KEK", L"db", L"dbx", L"MokList" };
-       EFI_GUID *owners[] = { &GV_GUID, &GV_GUID, &SIG_DB, &SIG_DB,
-                              &MOK_OWNER };
+       CHAR16 **variables;
+       EFI_GUID **owners;
 
        InitializeLib(image, systab);
 
+       if (GetOSIndications() & EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION) {
+               variables = (CHAR16 *[]){ L"PK", L"KEK", L"db", L"dbx", L"dbt", 
L"MokList" , NULL};
+               owners = (EFI_GUID *[]){ &GV_GUID, &GV_GUID, &SIG_DB, &SIG_DB, 
&SIG_DB, &MOK_OWNER };
+       } else {
+               variables = (CHAR16 *[]){ L"PK", L"KEK", L"db", L"dbx", 
L"MokList" , NULL};
+               owners = (EFI_GUID *[]){ &GV_GUID, &GV_GUID, &SIG_DB, &SIG_DB, 
&MOK_OWNER };
+       }
+
        status = argsplit(image, &argc, &ARGV);
 
        if (status != EFI_SUCCESS) {
@@ -74,15 +79,15 @@
        var = ARGV[1];
        name = ARGV[2];
 
-       for(i = 0; i < ARRAY_SIZE(variables); i++) {
+       for(i = 0; variables[i] != NULL; i++) {
                if (StrCmp(var, variables[i]) == 0) {
                        owner = owners[i];
                        break;
                }
        }
-       if (i == ARRAY_SIZE(variables)) {
+       if (variables[i] == NULL) {
                Print(L"Invalid Variable %s\nVariable must be one of: ", var);
-               for (i = 0; i < ARRAY_SIZE(variables); i++)
+               for (i = 0; variables[i] != NULL; i++)
                        Print(L"%s ", variables[i]);
                Print(L"\n");
                return EFI_INVALID_PARAMETER;
@@ -129,11 +134,11 @@
        } else if (esl_mode) {
                status = SetSecureVariable(var, buf, size, *owner, options, 0);
        } else {
-               status = uefi_call_wrapper(RT->SetVariable, 5, var, owner,
-                                          EFI_VARIABLE_NON_VOLATILE
-                                          | EFI_VARIABLE_BOOTSERVICE_ACCESS
-                                          | options,
-                                          size, buf);
+               status = RT->SetVariable(var, owner,
+                                        EFI_VARIABLE_NON_VOLATILE
+                                        | EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                        | options,
+                                        size, buf);
        }
 
        if (status != EFI_SUCCESS) {

Reply via email to