diff --git a/.pc/applied-patches b/.pc/applied-patches
index bf02a35..93f1acf 100644
--- a/.pc/applied-patches
+++ b/.pc/applied-patches
@@ -2,3 +2,4 @@ prototypes
second-stage-path
sbsigntool-not-pesign
gcc-5.diff
+gcc5-includes-stdarg.patch
diff --git a/.pc/gcc5-includes-stdarg.patch/.timestamp b/.pc/gcc5-includes-stdarg.patch/.timestamp
new file mode 100644
index 0000000..e69de29
diff --git a/.pc/gcc5-includes-stdarg.patch/Cryptlib/Include/OpenSslSupport.h b/.pc/gcc5-includes-stdarg.patch/Cryptlib/Include/OpenSslSupport.h
new file mode 100644
index 0000000..9e56ced
--- /dev/null
+++ b/.pc/gcc5-includes-stdarg.patch/Cryptlib/Include/OpenSslSupport.h
@@ -0,0 +1,269 @@
+/** @file
+ Root include file to support building OpenSSL Crypto Library.
+
+Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which 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 __OPEN_SSL_SUPPORT_H__
+#define __OPEN_SSL_SUPPORT_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define CONST const
+
+//
+// File operations are not required for building Open SSL,
+// so FILE is mapped to VOID * to pass build
+//
+typedef VOID *FILE;
+
+//
+// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
+//
+#if !defined(__CC_ARM) // if va_list is not already defined
+/*
+ * These are now unconditionally #defined by GNU_EFI's efistdarg.h,
+ * so we should #undef them here before providing a new definition.
+ */
+#undef va_arg
+#undef va_start
+#undef va_end
+
+#define va_list VA_LIST
+#define va_arg VA_ARG
+#define va_start VA_START
+#define va_end VA_END
+typedef __builtin_va_list VA_LIST;
+
+#define VA_START(Marker, Parameter) __builtin_va_start (Marker, Parameter)
+
+#define VA_ARG(Marker, TYPE) ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))
+
+#define VA_END(Marker) __builtin_va_end (Marker)
+
+#define VA_COPY(Dest, Start) __builtin_va_copy (Dest, Start)
+
+#else // __CC_ARM
+#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
+#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
+#define va_end(Marker) ((void)0)
+#endif
+
+//
+// #defines from EFI Application Toolkit required to buiild Open SSL
+//
+#define ENOMEM 12 /* Cannot allocate memory */
+#define EINVAL 22 /* Invalid argument */
+#define BUFSIZ 1024 /* size of buffer used by setbuf */
+#define INT_MAX 2147483647 /* max value for an int */
+#define INT_MIN (-2147483647-1) /* min value for an int */
+#define LONG_MAX 2147483647L /* max value for a long */
+#define LONG_MIN (-2147483647-1) /* min value for a long */
+#define ULONG_MAX 0xffffffff /* max value for an unsigned long */
+#define LOG_DAEMON (3<<3) /* system daemons */
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but significant condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+#define LOG_PID 0x01 /* log the pid with each message */
+#define LOG_CONS 0x02 /* log on the console if errors in sending */
+
+//
+// Macros from EFI Application Toolkit required to buiild Open SSL
+//
+/* The offsetof() macro calculates the offset of a structure member
+ in its structure. Unfortunately this cannot be written down
+ portably, hence it is provided by a Standard C header file.
+ For pre-Standard C compilers, here is a version that usually works
+ (but watch out!): */
+#define offsetof(type, member) ( (int) & ((type*)0) -> member )
+
+//
+// Basic types from EFI Application Toolkit required to buiild Open SSL
+//
+typedef UINTN size_t;
+typedef INTN ssize_t;
+typedef INT64 off_t;
+typedef UINT16 mode_t;
+typedef long time_t;
+typedef unsigned long clock_t;
+typedef UINT32 uid_t;
+typedef UINT32 gid_t;
+typedef UINT32 ino_t;
+typedef UINT32 dev_t;
+typedef UINT16 nlink_t;
+typedef int pid_t;
+typedef void *DIR;
+typedef void __sighandler_t (int);
+
+//
+// Structures from EFI Application Toolkit required to buiild Open SSL
+//
+struct tm {
+ int tm_sec; /* seconds after the minute [0-60] */
+ int tm_min; /* minutes after the hour [0-59] */
+ int tm_hour; /* hours since midnight [0-23] */
+ int tm_mday; /* day of the month [1-31] */
+ int tm_mon; /* months since January [0-11] */
+ int tm_year; /* years since 1900 */
+ int tm_wday; /* days since Sunday [0-6] */
+ int tm_yday; /* days since January 1 [0-365] */
+ int tm_isdst; /* Daylight Savings Time flag */
+ long tm_gmtoff; /* offset from CUT in seconds */
+ char *tm_zone; /* timezone abbreviation */
+};
+
+struct dirent {
+ UINT32 d_fileno; /* file number of entry */
+ UINT16 d_reclen; /* length of this record */
+ UINT8 d_type; /* file type, see below */
+ UINT8 d_namlen; /* length of string in d_name */
+ char d_name[255 + 1]; /* name must be no longer than this */
+};
+
+struct stat {
+ dev_t st_dev; /* inode's device */
+ ino_t st_ino; /* inode's number */
+ mode_t st_mode; /* inode protection mode */
+ nlink_t st_nlink; /* number of hard links */
+ uid_t st_uid; /* user ID of the file's owner */
+ gid_t st_gid; /* group ID of the file's group */
+ dev_t st_rdev; /* device type */
+ time_t st_atime; /* time of last access */
+ long st_atimensec; /* nsec of last access */
+ time_t st_mtime; /* time of last data modification */
+ long st_mtimensec; /* nsec of last data modification */
+ time_t st_ctime; /* time of last file status change */
+ long st_ctimensec; /* nsec of last file status change */
+ off_t st_size; /* file size, in bytes */
+ INT64 st_blocks; /* blocks allocated for file */
+ UINT32 st_blksize; /* optimal blocksize for I/O */
+ UINT32 st_flags; /* user defined flags for file */
+ UINT32 st_gen; /* file generation number */
+ INT32 st_lspare;
+ INT64 st_qspare[2];
+};
+
+//
+// Externs from EFI Application Toolkit required to buiild Open SSL
+//
+extern int errno;
+
+//
+// Function prototypes from EFI Application Toolkit required to buiild Open SSL
+//
+void *malloc (size_t);
+void *realloc (void *, size_t);
+void free (void *);
+int isdigit (int);
+int isspace (int);
+int tolower (int);
+int isupper (int);
+int isxdigit (int);
+int isalnum (int);
+void *memcpy (void *, const void *, size_t);
+void *memset (void *, int, size_t);
+void *memchr (const void *, int, size_t);
+int memcmp (const void *, const void *, size_t);
+void *memmove (void *, const void *, size_t);
+int strcmp (const char *, const char *);
+int strncmp (const char *, const char *, size_t);
+char *strcpy (char *, const char *);
+char *strncpy (char *, const char *, size_t);
+size_t strlen (const char *);
+char *strcat (char *, const char *);
+char *strchr (const char *, int);
+int strcasecmp (const char *, const char *);
+int strncasecmp (const char *, const char *, size_t);
+char *strncpy (char *, const char *, size_t);
+int strncmp (const char *, const char *, size_t);
+char *strrchr (const char *, int);
+unsigned long strtoul (const char *, char **, int);
+long strtol (const char *, char **, int);
+int printf (const char *, ...);
+int sscanf (const char *, const char *, ...);
+int open (const char *, int, ...);
+int chmod (const char *, mode_t);
+int stat (const char *, struct stat *);
+off_t lseek (int, off_t, int);
+ssize_t read (int, void *, size_t);
+ssize_t write (int, const void *, size_t);
+int close (int);
+FILE *fopen (const char *, const char *);
+size_t fread (void *, size_t, size_t, FILE *);
+size_t fwrite (const void *, size_t, size_t, FILE *);
+char *fgets (char *, int, FILE *);
+int fputs (const char *, FILE *);
+int fprintf (FILE *, const char *, ...);
+int vfprintf (FILE *, const char *, VA_LIST);
+int fflush (FILE *);
+int fclose (FILE *);
+DIR *opendir (const char *);
+struct dirent *readdir (DIR *);
+int closedir (DIR *);
+void openlog (const char *, int, int);
+void closelog (void);
+void syslog (int, const char *, ...);
+time_t time (time_t *);
+struct tm *localtime (const time_t *);
+struct tm *gmtime (const time_t *);
+struct tm *gmtime_r (const time_t *, struct tm *);
+uid_t getuid (void);
+uid_t geteuid (void);
+gid_t getgid (void);
+gid_t getegid (void);
+void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+char *getenv (const char *);
+void exit (int);
+void abort (void);
+__sighandler_t *signal (int, __sighandler_t *);
+
+//
+// Global variables from EFI Application Toolkit required to buiild Open SSL
+//
+extern FILE *stderr;
+extern FILE *stdin;
+extern FILE *stdout;
+
+#define AsciiStrLen(x) strlena(x)
+#define AsciiStrnCmp(s1, s2, len) strncmpa(s1, s2, len)
+
+//
+// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
+//
+#define memcpy(dest,source,count) ( {CopyMem(dest,source,(UINTN)(count)); dest; })
+#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch))
+#define memchr(buf,ch,count) ScanMem8(buf,(UINTN)(count),(UINT8)ch)
+#define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count)))
+#define memmove(dest,source,count) CopyMem(dest,source,(UINTN)(count))
+#define strcmp strcmpa
+#define strncmp(string1,string2,count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
+#define strcpy(strDest,strSource) AsciiStrCpy(strDest,strSource)
+#define strncpy(strDest,strSource,count) AsciiStrnCpy(strDest,strSource,(UINTN)count)
+#define strlen(str) (size_t)(AsciiStrLen(str))
+#define strcat(strDest,strSource) AsciiStrCat(strDest,strSource)
+#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)
+#define abort() ASSERT (FALSE)
+#define assert(expression)
+#define localtime(timer) NULL
+#define gmtime_r(timer,result) (result = NULL)
+
+#endif
diff --git a/.pc/gcc5-includes-stdarg.patch/Cryptlib/Makefile b/.pc/gcc5-includes-stdarg.patch/Cryptlib/Makefile
new file mode 100644
index 0000000..e930656
--- /dev/null
+++ b/.pc/gcc5-includes-stdarg.patch/Cryptlib/Makefile
@@ -0,0 +1,45 @@
+
+EFI_INCLUDES = -IInclude -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
+
+CFLAGS = -std=gnu89 -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar \
+ -Wall $(EFI_INCLUDES)
+
+ifeq ($(ARCH),x86_64)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \
+ -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
+endif
+ifeq ($(ARCH),ia32)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args -m32
+endif
+LDFLAGS = -nostdlib -znocombreloc
+
+TARGET = libcryptlib.a
+OBJS = Hash/CryptMd4.o \
+ Hash/CryptMd5.o \
+ Hash/CryptSha1.o \
+ Hash/CryptSha256.o \
+ Hmac/CryptHmacMd5.o \
+ Hmac/CryptHmacSha1.o \
+ Cipher/CryptAes.o \
+ Cipher/CryptTdes.o \
+ Cipher/CryptArc4.o \
+ Rand/CryptRand.o \
+ Pk/CryptRsaBasic.o \
+ Pk/CryptRsaExtNull.o \
+ Pk/CryptPkcs7SignNull.o \
+ Pk/CryptPkcs7Verify.o \
+ Pk/CryptDhNull.o \
+ Pk/CryptX509.o \
+ Pk/CryptAuthenticode.o \
+ Pem/CryptPem.o \
+ SysCall/CrtWrapper.o \
+ SysCall/TimerWrapper.o \
+ SysCall/BaseMemAllocation.o \
+ SysCall/BaseStrings.o
+
+all: $(TARGET)
+
+libcryptlib.a: $(OBJS)
+ ar rcs libcryptlib.a $(OBJS)
+clean:
+ rm -f $(TARGET) $(OBJS)
diff --git a/.pc/gcc5-includes-stdarg.patch/Cryptlib/OpenSSL/Makefile b/.pc/gcc5-includes-stdarg.patch/Cryptlib/OpenSSL/Makefile
new file mode 100644
index 0000000..f5b7e4f
--- /dev/null
+++ b/.pc/gcc5-includes-stdarg.patch/Cryptlib/OpenSSL/Makefile
@@ -0,0 +1,531 @@
+
+EFI_INCLUDES = -I../Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
+
+CFLAGS = -std=gnu89 -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc \
+ -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
+
+ifeq ($(ARCH),x86_64)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \
+ -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DSIXTY_FOUR_BIT_LONG
+endif
+ifeq ($(ARCH),ia32)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \
+ -m32 -DTHIRTY_TWO_BIT
+endif
+ifeq ($(ARCH),aarch64)
+ CFLAGS += -O2 -DSIXTY_FOUR_BIT_LONG -ffreestanding -I$(shell $(CC) -print-file-name=include)
+endif
+ifeq ($(ARCH),arm)
+ CFLAGS += -O2 -DTHIRTY_TWO_BIT -ffreestanding -I$(shell $(CC) -print-file-name=include)
+endif
+LDFLAGS = -nostdlib -znocombreloc
+
+TARGET = libopenssl.a
+OBJS = crypto/cryptlib.o \
+ crypto/dyn_lck.o \
+ crypto/mem.o \
+ crypto/mem_clr.o \
+ crypto/mem_dbg.o \
+ crypto/cversion.o \
+ crypto/ex_data.o \
+ crypto/cpt_err.o \
+ crypto/ebcdic.o \
+ crypto/uid.o \
+ crypto/o_time.o \
+ crypto/o_str.o \
+ crypto/o_dir.o \
+ crypto/o_init.o \
+ crypto/fips_err.o \
+ crypto/md2/md2_dgst.o \
+ crypto/md2/md2_one.o \
+ crypto/md4/md4_dgst.o \
+ crypto/md4/md4_one.o \
+ crypto/md5/md5_dgst.o \
+ crypto/md5/md5_one.o \
+ crypto/sha/sha_dgst.o \
+ crypto/sha/sha1dgst.o \
+ crypto/sha/sha_one.o \
+ crypto/sha/sha1_one.o \
+ crypto/sha/sha256.o \
+ crypto/sha/sha512.o \
+ crypto/hmac/hmac.o \
+ crypto/ripemd/rmd_dgst.o \
+ crypto/ripemd/rmd_one.o \
+ crypto/des/des_lib.o \
+ crypto/des/set_key.o \
+ crypto/des/ecb_enc.o \
+ crypto/des/cbc_enc.o \
+ crypto/des/ecb3_enc.o \
+ crypto/des/cfb64enc.o \
+ crypto/des/cfb64ede.o \
+ crypto/des/cfb_enc.o \
+ crypto/des/ofb64ede.o \
+ crypto/des/enc_read.o \
+ crypto/des/enc_writ.o \
+ crypto/des/ofb64enc.o \
+ crypto/des/ofb_enc.o \
+ crypto/des/str2key.o \
+ crypto/des/pcbc_enc.o \
+ crypto/des/qud_cksm.o \
+ crypto/des/rand_key.o \
+ crypto/des/des_enc.o \
+ crypto/des/fcrypt_b.o \
+ crypto/des/fcrypt.o \
+ crypto/des/xcbc_enc.o \
+ crypto/des/rpc_enc.o \
+ crypto/des/cbc_cksm.o \
+ crypto/des/ede_cbcm_enc.o \
+ crypto/des/des_old.o \
+ crypto/des/des_old2.o \
+ crypto/des/read2pwd.o \
+ crypto/rc2/rc2_ecb.o \
+ crypto/rc2/rc2_skey.o \
+ crypto/rc2/rc2_cbc.o \
+ crypto/rc2/rc2cfb64.o \
+ crypto/rc2/rc2ofb64.o \
+ crypto/rc4/rc4_enc.o \
+ crypto/rc4/rc4_skey.o \
+ crypto/rc4/rc4_fblk.o \
+ crypto/idea/i_cbc.o \
+ crypto/idea/i_cfb64.o \
+ crypto/idea/i_ofb64.o \
+ crypto/idea/i_ecb.o \
+ crypto/idea/i_skey.o \
+ crypto/bf/bf_skey.o \
+ crypto/bf/bf_ecb.o \
+ crypto/bf/bf_enc.o \
+ crypto/bf/bf_cfb64.o \
+ crypto/bf/bf_ofb64.o \
+ crypto/cast/c_skey.o \
+ crypto/cast/c_ecb.o \
+ crypto/cast/c_enc.o \
+ crypto/cast/c_cfb64.o \
+ crypto/cast/c_ofb64.o \
+ crypto/aes/aes_misc.o \
+ crypto/aes/aes_ecb.o \
+ crypto/aes/aes_cfb.o \
+ crypto/aes/aes_ofb.o \
+ crypto/aes/aes_ctr.o \
+ crypto/aes/aes_ige.o \
+ crypto/aes/aes_wrap.o \
+ crypto/aes/aes_core.o \
+ crypto/aes/aes_cbc.o \
+ crypto/bn/bn_add.o \
+ crypto/bn/bn_div.o \
+ crypto/bn/bn_exp.o \
+ crypto/bn/bn_lib.o \
+ crypto/bn/bn_ctx.o \
+ crypto/bn/bn_mul.o \
+ crypto/bn/bn_mod.o \
+ crypto/bn/bn_print.o \
+ crypto/bn/bn_rand.o \
+ crypto/bn/bn_shift.o \
+ crypto/bn/bn_word.o \
+ crypto/bn/bn_blind.o \
+ crypto/bn/bn_kron.o \
+ crypto/bn/bn_sqrt.o \
+ crypto/bn/bn_gcd.o \
+ crypto/bn/bn_prime.o \
+ crypto/bn/bn_err.o \
+ crypto/bn/bn_sqr.o \
+ crypto/bn/bn_asm.o \
+ crypto/bn/bn_recp.o \
+ crypto/bn/bn_mont.o \
+ crypto/bn/bn_mpi.o \
+ crypto/bn/bn_exp2.o \
+ crypto/bn/bn_gf2m.o \
+ crypto/bn/bn_nist.o \
+ crypto/bn/bn_depr.o \
+ crypto/bn/bn_x931p.o \
+ crypto/bn/bn_const.o \
+ crypto/bn/bn_opt.o \
+ crypto/rsa/rsa_eay.o \
+ crypto/rsa/rsa_gen.o \
+ crypto/rsa/rsa_lib.o \
+ crypto/rsa/rsa_sign.o \
+ crypto/rsa/rsa_saos.o \
+ crypto/rsa/rsa_err.o \
+ crypto/rsa/rsa_pk1.o \
+ crypto/rsa/rsa_ssl.o \
+ crypto/rsa/rsa_none.o \
+ crypto/rsa/rsa_oaep.o \
+ crypto/rsa/rsa_chk.o \
+ crypto/rsa/rsa_null.o \
+ crypto/rsa/rsa_pss.o \
+ crypto/rsa/rsa_x931.o \
+ crypto/rsa/rsa_x931g.o \
+ crypto/rsa/rsa_asn1.o \
+ crypto/rsa/rsa_depr.o \
+ crypto/rsa/rsa_eng.o \
+ crypto/dsa/dsa_gen.o \
+ crypto/dsa/dsa_key.o \
+ crypto/dsa/dsa_lib.o \
+ crypto/dsa/dsa_asn1.o \
+ crypto/dsa/dsa_vrf.o \
+ crypto/dsa/dsa_sign.o \
+ crypto/dsa/dsa_err.o \
+ crypto/dsa/dsa_ossl.o \
+ crypto/dsa/dsa_depr.o \
+ crypto/dsa/dsa_utl.o \
+ crypto/dso/dso_dl.o \
+ crypto/dso/dso_dlfcn.o \
+ crypto/dso/dso_err.o \
+ crypto/dso/dso_lib.o \
+ crypto/dso/dso_null.o \
+ crypto/dso/dso_openssl.o \
+ crypto/dso/dso_win32.o \
+ crypto/dso/dso_vms.o \
+ crypto/dh/dh_asn1.o \
+ crypto/dh/dh_gen.o \
+ crypto/dh/dh_key.o \
+ crypto/dh/dh_lib.o \
+ crypto/dh/dh_check.o \
+ crypto/dh/dh_err.o \
+ crypto/dh/dh_depr.o \
+ crypto/ec/ec_lib.o \
+ crypto/ec/ecp_smpl.o \
+ crypto/ec/ecp_mont.o \
+ crypto/ec/ecp_nist.o \
+ crypto/ec/ec_cvt.o \
+ crypto/ec/ec_mult.o \
+ crypto/ec/ec_err.o \
+ crypto/ec/ec_curve.o \
+ crypto/ec/ec_check.o \
+ crypto/ec/ec_print.o \
+ crypto/ec/ec_asn1.o \
+ crypto/ec/ec_key.o \
+ crypto/ec/ec2_smpl.o \
+ crypto/ec/ec2_mult.o \
+ crypto/ecdh/ech_lib.o \
+ crypto/ecdh/ech_ossl.o \
+ crypto/ecdh/ech_key.o \
+ crypto/ecdh/ech_err.o \
+ crypto/ecdsa/ecs_lib.o \
+ crypto/ecdsa/ecs_asn1.o \
+ crypto/ecdsa/ecs_ossl.o \
+ crypto/ecdsa/ecs_sign.o \
+ crypto/ecdsa/ecs_vrf.o \
+ crypto/ecdsa/ecs_err.o \
+ crypto/buffer/buffer.o \
+ crypto/buffer/buf_str.o \
+ crypto/buffer/buf_err.o \
+ crypto/bio/bio_lib.o \
+ crypto/bio/bio_cb.o \
+ crypto/bio/bio_err.o \
+ crypto/bio/bss_mem.o \
+ crypto/bio/bss_null.o \
+ crypto/bio/bss_fd.o \
+ crypto/bio/bss_file.o \
+ crypto/bio/bf_null.o \
+ crypto/bio/bf_buff.o \
+ crypto/bio/b_dump.o \
+ crypto/bio/b_print.o \
+ crypto/bio/bf_nbio.o \
+ crypto/bio/bss_log.o \
+ crypto/bio/bss_bio.o \
+ crypto/bio/bss_dgram.o \
+ crypto/stack/stack.o \
+ crypto/lhash/lhash.o \
+ crypto/lhash/lh_stats.o \
+ crypto/rand/md_rand.o \
+ crypto/rand/randfile.o \
+ crypto/rand/rand_lib.o \
+ crypto/rand/rand_eng.o \
+ crypto/rand/rand_err.o \
+ crypto/rand/rand_egd.o \
+ crypto/rand/rand_win.o \
+ crypto/rand/rand_unix.o \
+ crypto/rand/rand_os2.o \
+ crypto/rand/rand_nw.o \
+ crypto/err/err.o \
+ crypto/err/err_def.o \
+ crypto/err/err_all.o \
+ crypto/err/err_prn.o \
+ crypto/err/err_str.o \
+ crypto/err/err_bio.o \
+ crypto/objects/o_names.o \
+ crypto/objects/obj_dat.o \
+ crypto/objects/obj_lib.o \
+ crypto/objects/obj_err.o \
+ crypto/evp/encode.o \
+ crypto/evp/digest.o \
+ crypto/evp/dig_eng.o \
+ crypto/evp/evp_enc.o \
+ crypto/evp/evp_key.o \
+ crypto/evp/evp_acnf.o \
+ crypto/evp/evp_cnf.o \
+ crypto/evp/e_des.o \
+ crypto/evp/e_bf.o \
+ crypto/evp/e_idea.o \
+ crypto/evp/e_des3.o \
+ crypto/evp/e_rc4.o \
+ crypto/evp/e_aes.o \
+ crypto/evp/names.o \
+ crypto/evp/e_xcbc_d.o \
+ crypto/evp/e_rc2.o \
+ crypto/evp/e_cast.o \
+ crypto/evp/e_rc5.o \
+ crypto/evp/enc_min.o \
+ crypto/evp/m_null.o \
+ crypto/evp/m_md2.o \
+ crypto/evp/m_md4.o \
+ crypto/evp/m_md5.o \
+ crypto/evp/m_sha.o \
+ crypto/evp/m_sha1.o \
+ crypto/evp/m_dss.o \
+ crypto/evp/m_dss1.o \
+ crypto/evp/m_ripemd.o \
+ crypto/evp/m_ecdsa.o \
+ crypto/evp/p_open.o \
+ crypto/evp/p_seal.o \
+ crypto/evp/p_sign.o \
+ crypto/evp/p_verify.o \
+ crypto/evp/p_lib.o \
+ crypto/evp/p_enc.o \
+ crypto/evp/p_dec.o \
+ crypto/evp/bio_md.o \
+ crypto/evp/bio_b64.o \
+ crypto/evp/bio_enc.o \
+ crypto/evp/evp_err.o \
+ crypto/evp/e_null.o \
+ crypto/evp/c_all.o \
+ crypto/evp/c_allc.o \
+ crypto/evp/c_alld.o \
+ crypto/evp/evp_lib.o \
+ crypto/evp/bio_ok.o \
+ crypto/evp/evp_pkey.o \
+ crypto/evp/evp_pbe.o \
+ crypto/evp/p5_crpt.o \
+ crypto/evp/p5_crpt2.o \
+ crypto/evp/e_old.o \
+ crypto/asn1/a_object.o \
+ crypto/asn1/a_bitstr.o \
+ crypto/asn1/a_utctm.o \
+ crypto/asn1/a_gentm.o \
+ crypto/asn1/a_time.o \
+ crypto/asn1/a_int.o \
+ crypto/asn1/a_octet.o \
+ crypto/asn1/a_print.o \
+ crypto/asn1/a_type.o \
+ crypto/asn1/a_set.o \
+ crypto/asn1/a_dup.o \
+ crypto/asn1/a_d2i_fp.o \
+ crypto/asn1/a_i2d_fp.o \
+ crypto/asn1/a_enum.o \
+ crypto/asn1/a_utf8.o \
+ crypto/asn1/a_sign.o \
+ crypto/asn1/a_digest.o \
+ crypto/asn1/a_verify.o \
+ crypto/asn1/a_mbstr.o \
+ crypto/asn1/a_strex.o \
+ crypto/asn1/x_algor.o \
+ crypto/asn1/x_val.o \
+ crypto/asn1/x_pubkey.o \
+ crypto/asn1/x_sig.o \
+ crypto/asn1/x_req.o \
+ crypto/asn1/x_attrib.o \
+ crypto/asn1/x_bignum.o \
+ crypto/asn1/x_long.o \
+ crypto/asn1/x_name.o \
+ crypto/asn1/x_x509.o \
+ crypto/asn1/x_x509a.o \
+ crypto/asn1/x_crl.o \
+ crypto/asn1/x_info.o \
+ crypto/asn1/x_spki.o \
+ crypto/asn1/nsseq.o \
+ crypto/asn1/d2i_pu.o \
+ crypto/asn1/d2i_pr.o \
+ crypto/asn1/i2d_pu.o \
+ crypto/asn1/i2d_pr.o \
+ crypto/asn1/t_req.o \
+ crypto/asn1/t_x509.o \
+ crypto/asn1/t_x509a.o \
+ crypto/asn1/t_crl.o \
+ crypto/asn1/t_pkey.o \
+ crypto/asn1/t_spki.o \
+ crypto/asn1/t_bitst.o \
+ crypto/asn1/tasn_new.o \
+ crypto/asn1/tasn_fre.o \
+ crypto/asn1/tasn_enc.o \
+ crypto/asn1/tasn_dec.o \
+ crypto/asn1/tasn_utl.o \
+ crypto/asn1/tasn_typ.o \
+ crypto/asn1/f_int.o \
+ crypto/asn1/f_string.o \
+ crypto/asn1/n_pkey.o \
+ crypto/asn1/f_enum.o \
+ crypto/asn1/a_hdr.o \
+ crypto/asn1/x_pkey.o \
+ crypto/asn1/a_bool.o \
+ crypto/asn1/x_exten.o \
+ crypto/asn1/asn_mime.o \
+ crypto/asn1/asn1_gen.o \
+ crypto/asn1/asn1_par.o \
+ crypto/asn1/asn1_lib.o \
+ crypto/asn1/asn1_err.o \
+ crypto/asn1/a_meth.o \
+ crypto/asn1/a_bytes.o \
+ crypto/asn1/a_strnid.o \
+ crypto/asn1/evp_asn1.o \
+ crypto/asn1/asn_pack.o \
+ crypto/asn1/p5_pbe.o \
+ crypto/asn1/p5_pbev2.o \
+ crypto/asn1/p8_pkey.o \
+ crypto/asn1/asn_moid.o \
+ crypto/pem/pem_sign.o \
+ crypto/pem/pem_seal.o \
+ crypto/pem/pem_info.o \
+ crypto/pem/pem_lib.o \
+ crypto/pem/pem_all.o \
+ crypto/pem/pem_err.o \
+ crypto/pem/pem_x509.o \
+ crypto/pem/pem_xaux.o \
+ crypto/pem/pem_oth.o \
+ crypto/pem/pem_pk8.o \
+ crypto/pem/pem_pkey.o \
+ crypto/x509/x509_def.o \
+ crypto/x509/x509_d2.o \
+ crypto/x509/x509_r2x.o \
+ crypto/x509/x509_cmp.o \
+ crypto/x509/x509_obj.o \
+ crypto/x509/x509_req.o \
+ crypto/x509/x509spki.o \
+ crypto/x509/x509_vfy.o \
+ crypto/x509/x509_set.o \
+ crypto/x509/x509cset.o \
+ crypto/x509/x509rset.o \
+ crypto/x509/x509_err.o \
+ crypto/x509/x509name.o \
+ crypto/x509/x509_v3.o \
+ crypto/x509/x509_ext.o \
+ crypto/x509/x509_att.o \
+ crypto/x509/x509type.o \
+ crypto/x509/x509_lu.o \
+ crypto/x509/x_all.o \
+ crypto/x509/x509_txt.o \
+ crypto/x509/x509_trs.o \
+ crypto/x509/by_file.o \
+ crypto/x509/by_dir.o \
+ crypto/x509/x509_vpm.o \
+ crypto/x509v3/v3_bcons.o \
+ crypto/x509v3/v3_bitst.o \
+ crypto/x509v3/v3_conf.o \
+ crypto/x509v3/v3_extku.o \
+ crypto/x509v3/v3_ia5.o \
+ crypto/x509v3/v3_lib.o \
+ crypto/x509v3/v3_prn.o \
+ crypto/x509v3/v3_utl.o \
+ crypto/x509v3/v3err.o \
+ crypto/x509v3/v3_genn.o \
+ crypto/x509v3/v3_alt.o \
+ crypto/x509v3/v3_skey.o \
+ crypto/x509v3/v3_akey.o \
+ crypto/x509v3/v3_pku.o \
+ crypto/x509v3/v3_int.o \
+ crypto/x509v3/v3_enum.o \
+ crypto/x509v3/v3_sxnet.o \
+ crypto/x509v3/v3_cpols.o \
+ crypto/x509v3/v3_crld.o \
+ crypto/x509v3/v3_purp.o \
+ crypto/x509v3/v3_info.o \
+ crypto/x509v3/v3_ocsp.o \
+ crypto/x509v3/v3_akeya.o \
+ crypto/x509v3/v3_pmaps.o \
+ crypto/x509v3/v3_pcons.o \
+ crypto/x509v3/v3_ncons.o \
+ crypto/x509v3/v3_pcia.o \
+ crypto/x509v3/v3_pci.o \
+ crypto/x509v3/pcy_cache.o \
+ crypto/x509v3/pcy_node.o \
+ crypto/x509v3/pcy_data.o \
+ crypto/x509v3/pcy_map.o \
+ crypto/x509v3/pcy_tree.o \
+ crypto/x509v3/pcy_lib.o \
+ crypto/x509v3/v3_asid.o \
+ crypto/x509v3/v3_addr.o \
+ crypto/conf/conf_err.o \
+ crypto/conf/conf_lib.o \
+ crypto/conf/conf_api.o \
+ crypto/conf/conf_def.o \
+ crypto/conf/conf_mod.o \
+ crypto/conf/conf_mall.o \
+ crypto/conf/conf_sap.o \
+ crypto/txt_db/txt_db.o \
+ crypto/pkcs7/pk7_asn1.o \
+ crypto/pkcs7/pk7_lib.o \
+ crypto/pkcs7/pkcs7err.o \
+ crypto/pkcs7/pk7_doit.o \
+ crypto/pkcs7/pk7_smime.o \
+ crypto/pkcs7/pk7_attr.o \
+ crypto/pkcs7/pk7_mime.o \
+ crypto/pkcs12/p12_add.o \
+ crypto/pkcs12/p12_asn.o \
+ crypto/pkcs12/p12_attr.o \
+ crypto/pkcs12/p12_crpt.o \
+ crypto/pkcs12/p12_crt.o \
+ crypto/pkcs12/p12_decr.o \
+ crypto/pkcs12/p12_init.o \
+ crypto/pkcs12/p12_key.o \
+ crypto/pkcs12/p12_kiss.o \
+ crypto/pkcs12/p12_mutl.o \
+ crypto/pkcs12/p12_utl.o \
+ crypto/pkcs12/p12_npas.o \
+ crypto/pkcs12/pk12err.o \
+ crypto/pkcs12/p12_p8d.o \
+ crypto/pkcs12/p12_p8e.o \
+ crypto/comp/comp_lib.o \
+ crypto/comp/comp_err.o \
+ crypto/comp/c_rle.o \
+ crypto/comp/c_zlib.o \
+ crypto/engine/eng_err.o \
+ crypto/engine/eng_lib.o \
+ crypto/engine/eng_list.o \
+ crypto/engine/eng_init.o \
+ crypto/engine/eng_ctrl.o \
+ crypto/engine/eng_table.o \
+ crypto/engine/eng_pkey.o \
+ crypto/engine/eng_fat.o \
+ crypto/engine/eng_all.o \
+ crypto/engine/tb_rsa.o \
+ crypto/engine/tb_dsa.o \
+ crypto/engine/tb_ecdsa.o \
+ crypto/engine/tb_dh.o \
+ crypto/engine/tb_ecdh.o \
+ crypto/engine/tb_rand.o \
+ crypto/engine/tb_store.o \
+ crypto/engine/tb_cipher.o \
+ crypto/engine/tb_digest.o \
+ crypto/engine/eng_openssl.o \
+ crypto/engine/eng_cnf.o \
+ crypto/engine/eng_dyn.o \
+ crypto/engine/eng_cryptodev.o \
+ crypto/engine/eng_padlock.o \
+ crypto/ocsp/ocsp_asn.o \
+ crypto/ocsp/ocsp_ext.o \
+ crypto/ocsp/ocsp_ht.o \
+ crypto/ocsp/ocsp_lib.o \
+ crypto/ocsp/ocsp_cl.o \
+ crypto/ocsp/ocsp_srv.o \
+ crypto/ocsp/ocsp_prn.o \
+ crypto/ocsp/ocsp_vfy.o \
+ crypto/ocsp/ocsp_err.o \
+ crypto/ui/ui_err.o \
+ crypto/ui/ui_lib.o \
+ crypto/ui/ui_util.o \
+ crypto/ui/ui_compat.o \
+ crypto/krb5/krb5_asn.o \
+ crypto/store/str_err.o \
+ crypto/store/str_lib.o \
+ crypto/store/str_meth.o \
+ crypto/store/str_mem.o \
+ crypto/pqueue/pqueue.o \
+
+
+
+all: $(TARGET)
+
+libopenssl.a: $(OBJS)
+ ar rcs libopenssl.a $(OBJS)
+
+clean:
+ rm -f $(TARGET) $(OBJS)
diff --git a/.pc/gcc5-includes-stdarg.patch/Makefile b/.pc/gcc5-includes-stdarg.patch/Makefile
new file mode 100644
index 0000000..9cae609
--- /dev/null
+++ b/.pc/gcc5-includes-stdarg.patch/Makefile
@@ -0,0 +1,183 @@
+CC = $(CROSS_COMPILE)gcc
+LD = $(CROSS_COMPILE)ld
+OBJCOPY = $(CROSS_COMPILE)objcopy
+
+ARCH = $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,)
+
+SUBDIRS = Cryptlib lib
+
+LIB_PATH = /usr/lib64
+
+EFI_INCLUDE := /usr/include/efi
+EFI_INCLUDES = -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -Iinclude
+EFI_PATH := /usr/lib64/gnuefi
+
+LIB_GCC = $(shell $(CC) -print-libgcc-file-name)
+EFI_LIBS = -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC)
+
+EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o
+EFI_LDS = elf_$(ARCH)_efi.lds
+
+DEFAULT_LOADER := \\\\grubx64.efi
+CFLAGS = -std=gnu89 -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
+ -fshort-wchar -Wall -Wsign-compare -Werror -fno-builtin \
+ -Werror=sign-compare \
+ "-DDEFAULT_LOADER=L\"$(DEFAULT_LOADER)\"" \
+ "-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \
+ $(EFI_INCLUDES)
+
+ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
+ CFLAGS += -DOVERRIDE_SECURITY_POLICY
+endif
+
+ifeq ($(ARCH),x86_64)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \
+ -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
+endif
+ifeq ($(ARCH),ia32)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args -m32
+endif
+
+ifeq ($(ARCH),aarch64)
+ CFLAGS += -ffreestanding -I$(shell $(CC) -print-file-name=include)
+endif
+
+ifeq ($(ARCH),arm)
+ CFLAGS += -ffreestanding -I$(shell $(CC) -print-file-name=include)
+endif
+
+ifneq ($(origin VENDOR_CERT_FILE), undefined)
+ CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\"
+endif
+ifneq ($(origin VENDOR_DBX_FILE), undefined)
+ CFLAGS += -DVENDOR_DBX_FILE=\"$(VENDOR_DBX_FILE)\"
+endif
+
+LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS)
+
+VERSION = 0.8
+
+TARGET = shim.efi MokManager.efi.signed fallback.efi.signed
+OBJS = shim.o netboot.o cert.o replacements.o version.o
+KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
+SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h version.c version.h
+MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o
+MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h
+FALLBACK_OBJS = fallback.o
+FALLBACK_SRCS = fallback.c
+
+all: $(TARGET)
+
+shim.crt:
+ ./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 $@
+ hexdump -v -e '1/1 "0x%02x, "' $< >> $@
+ echo "};" >> $@
+
+version.c : version.c.in
+ sed -e "s,@@VERSION@@,$(VERSION)," \
+ -e "s,@@UNAME@@,$(shell uname -a)," \
+ -e "s,@@COMMIT@@,$(shell if [ -d .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo commit id not available; fi)," \
+ < version.c.in > version.c
+
+certdb/secmod.db: shim.crt
+ -mkdir certdb
+ pk12util -d certdb/ -i shim.p12 -W "" -K ""
+ certutil -d certdb/ -A -i shim.crt -n shim -t u
+
+shim.o: $(SOURCES) shim_cert.h
+
+cert.o : cert.S
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+shim.so: $(OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+ $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
+
+fallback.o: $(FALLBACK_SRCS)
+
+fallback.so: $(FALLBACK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+ $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
+
+MokManager.o: $(MOK_SOURCES)
+
+MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a lib/lib.a
+ $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
+
+Cryptlib/libcryptlib.a:
+ $(MAKE) -C Cryptlib
+
+Cryptlib/OpenSSL/libopenssl.a:
+ $(MAKE) -C Cryptlib/OpenSSL
+
+lib/lib.a:
+ $(MAKE) -C lib
+
+ifeq ($(ARCH),aarch64)
+FORMAT := -O binary
+SUBSYSTEM := 0xa
+LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
+endif
+
+ifeq ($(ARCH),arm)
+FORMAT := -O binary
+SUBSYSTEM := 0xa
+LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
+endif
+
+FORMAT ?= --target efi-app-$(ARCH)
+
+%.efi: %.so
+ $(OBJCOPY) -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynsym -j .rel* \
+ -j .rela* -j .reloc -j .eh_frame \
+ -j .vendor_cert \
+ $(FORMAT) $^ $@
+ $(OBJCOPY) -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynsym -j .rel* \
+ -j .rela* -j .reloc -j .eh_frame \
+ -j .debug_info -j .debug_abbrev -j .debug_aranges \
+ -j .debug_line -j .debug_str -j .debug_ranges \
+ $(FORMAT) $^ $@.debug
+
+%.efi.signed: %.efi shim.crt
+ sbsign --key shim.key --cert shim.crt $<
+
+clean:
+ $(MAKE) -C Cryptlib clean
+ $(MAKE) -C Cryptlib/OpenSSL clean
+ $(MAKE) -C lib clean
+ rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb
+ rm -f *.debug *.so *.efi *.tar.* version.c
+
+GITTAG = $(VERSION)
+
+test-archive:
+ @rm -rf /tmp/shim-$(VERSION) /tmp/shim-$(VERSION)-tmp
+ @mkdir -p /tmp/shim-$(VERSION)-tmp
+ @git archive --format=tar $(shell git branch | awk '/^*/ { print $$2 }') | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x )
+ @git diff | ( cd /tmp/shim-$(VERSION)-tmp/ ; patch -s -p1 -b -z .gitdiff )
+ @mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/
+ @git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit
+ @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION)
+ @rm -rf /tmp/shim-$(VERSION)
+ @echo "The archive is in shim-$(VERSION).tar.bz2"
+
+tag:
+ git tag --sign $(GITTAG) refs/heads/master
+
+archive: tag
+ @rm -rf /tmp/shim-$(VERSION) /tmp/shim-$(VERSION)-tmp
+ @mkdir -p /tmp/shim-$(VERSION)-tmp
+ @git archive --format=tar $(GITTAG) | ( cd /tmp/shim-$(VERSION)-tmp/ ; tar x )
+ @mv /tmp/shim-$(VERSION)-tmp/ /tmp/shim-$(VERSION)/
+ @git log -1 --pretty=format:%H > /tmp/shim-$(VERSION)/commit
+ @dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/shim-$(VERSION).tar.bz2 shim-$(VERSION)
+ @rm -rf /tmp/shim-$(VERSION)
+ @echo "The archive is in shim-$(VERSION).tar.bz2"
+
+export ARCH CC LD OBJCOPY EFI_INCLUDE
diff --git a/.pc/gcc5-includes-stdarg.patch/MokManager.c b/.pc/gcc5-includes-stdarg.patch/MokManager.c
new file mode 100644
index 0000000..ee29051
--- /dev/null
+++ b/.pc/gcc5-includes-stdarg.patch/MokManager.c
@@ -0,0 +1,2017 @@
+#include
+#include
+#include
+#include
+#include "shim.h"
+#include "PeImage.h"
+#include "PasswordCrypt.h"
+
+#include "guid.h"
+#include "console.h"
+#include "variables.h"
+#include "simple_file.h"
+#include "efiauthenticated.h"
+
+#define PASSWORD_MAX 256
+#define PASSWORD_MIN 1
+#define SB_PASSWORD_LEN 16
+
+#define NAME_LINE_MAX 70
+
+#ifndef SHIM_VENDOR
+#define SHIM_VENDOR L"Shim"
+#endif
+
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+
+EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+
+#define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
+#define HASH_STRING L"Select a file to trust:\n\n"
+
+struct menu_item {
+ CHAR16 *text;
+ INTN (* callback)(void *data, void *data2, void *data3);
+ void *data;
+ void *data2;
+ void *data3;
+ UINTN colour;
+};
+
+typedef struct {
+ UINT32 MokSize;
+ UINT8 *Mok;
+ EFI_GUID Type;
+} __attribute__ ((packed)) MokListNode;
+
+typedef struct {
+ UINT32 MokSBState;
+ UINT32 PWLen;
+ CHAR16 Password[SB_PASSWORD_LEN];
+} __attribute__ ((packed)) MokSBvar;
+
+typedef struct {
+ UINT32 MokDBState;
+ UINT32 PWLen;
+ CHAR16 Password[SB_PASSWORD_LEN];
+} __attribute__ ((packed)) MokDBvar;
+
+static EFI_STATUS get_sha1sum (void *Data, int DataSize, UINT8 *hash)
+{
+ EFI_STATUS status;
+ unsigned int ctxsize;
+ void *ctx = NULL;
+
+ ctxsize = Sha1GetContextSize();
+ ctx = AllocatePool(ctxsize);
+
+ if (!ctx) {
+ console_notify(L"Unable to allocate memory for hash context");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!Sha1Init(ctx)) {
+ console_notify(L"Unable to initialise hash");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ if (!(Sha1Update(ctx, Data, DataSize))) {
+ console_notify(L"Unable to generate hash");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ if (!(Sha1Final(ctx, hash))) {
+ console_notify(L"Unable to finalise hash");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ status = EFI_SUCCESS;
+done:
+ return status;
+}
+
+static UINT32 count_keys(void *Data, UINTN DataSize)
+{
+ EFI_SIGNATURE_LIST *CertList = Data;
+ EFI_GUID CertType = X509_GUID;
+ EFI_GUID HashType = EFI_CERT_SHA256_GUID;
+ UINTN dbsize = DataSize;
+ UINT32 MokNum = 0;
+ void *end = Data + DataSize;
+
+ while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+
+ /* Use ptr arithmetics to ensure bounded access. Do not allow 0
+ * SignatureListSize that will cause endless loop.
+ */
+ if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
+ console_notify(L"Invalid MOK detected! Ignoring MOK List.");
+ return 0;
+ }
+
+ if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
+ (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
+ console_notify(L"Doesn't look like a key or hash");
+ dbsize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+ CertList->SignatureListSize);
+ continue;
+ }
+
+ if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
+ (CertList->SignatureSize != 48)) {
+ console_notify(L"Doesn't look like a valid hash");
+ dbsize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+ CertList->SignatureListSize);
+ continue;
+ }
+
+ MokNum++;
+ dbsize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+ CertList->SignatureListSize);
+ }
+
+ return MokNum;
+}
+
+static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
+ MokListNode *list;
+ EFI_SIGNATURE_LIST *CertList = Data;
+ EFI_SIGNATURE_DATA *Cert;
+ EFI_GUID CertType = X509_GUID;
+ EFI_GUID HashType = EFI_CERT_SHA256_GUID;
+ UINTN dbsize = DataSize;
+ UINTN count = 0;
+ void *end = Data + DataSize;
+
+ list = AllocatePool(sizeof(MokListNode) * num);
+
+ if (!list) {
+ console_notify(L"Unable to allocate MOK list");
+ return NULL;
+ }
+
+ while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+ /* CertList out of bounds? */
+ if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
+ FreePool(list);
+ return NULL;
+ }
+ if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
+ (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
+ dbsize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList +
+ CertList->SignatureListSize);
+ continue;
+ }
+
+ if ((CompareGuid (&CertList->SignatureType, &HashType) == 0) &&
+ (CertList->SignatureSize != 48)) {
+ dbsize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList +
+ CertList->SignatureListSize);
+ continue;
+ }
+
+ Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) +
+ sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+
+ /* Cert out of bounds? */
+ if ((void *)(Cert + 1) > end || CertList->SignatureSize <= sizeof(EFI_GUID)) {
+ FreePool(list);
+ return NULL;
+ }
+
+ list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID);
+ list[count].Mok = (void *)Cert->SignatureData;
+ list[count].Type = CertList->SignatureType;
+
+ /* MOK out of bounds? */
+ if (list[count].MokSize > (unsigned long)end -
+ (unsigned long)list[count].Mok) {
+ FreePool(list);
+ return NULL;
+ }
+
+ count++;
+ dbsize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+ CertList->SignatureListSize);
+ }
+
+ return list;
+}
+
+typedef struct {
+ int nid;
+ CHAR16 *name;
+} NidName;
+
+static NidName nidname[] = {
+ {NID_commonName, L"CN"},
+ {NID_organizationName, L"O"},
+ {NID_countryName, L"C"},
+ {NID_stateOrProvinceName, L"ST"},
+ {NID_localityName, L"L"},
+ {-1, NULL}
+};
+
+static CHAR16* get_x509_name (X509_NAME *X509Name)
+{
+ CHAR16 name[NAME_LINE_MAX+1];
+ CHAR16 part[NAME_LINE_MAX+1];
+ char str[NAME_LINE_MAX];
+ int i, len, rest, first;
+
+ name[0] = '\0';
+ rest = NAME_LINE_MAX;
+ first = 1;
+ for (i = 0; nidname[i].name != NULL; i++) {
+ int add;
+ len = X509_NAME_get_text_by_NID (X509Name, nidname[i].nid,
+ str, NAME_LINE_MAX);
+ if (len <= 0)
+ continue;
+
+ if (first)
+ add = len + (int)StrLen(nidname[i].name) + 1;
+ else
+ add = len + (int)StrLen(nidname[i].name) + 3;
+
+ if (add > rest)
+ continue;
+
+ if (first) {
+ SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L"%s=%a",
+ nidname[i].name, str);
+ } else {
+ SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L", %s=%a",
+ nidname[i].name, str);
+ }
+ StrCat(name, part);
+ rest -= add;
+ first = 0;
+ }
+
+ if (rest >= 0 && rest < NAME_LINE_MAX)
+ return PoolPrint(L"%s", name);
+
+ return NULL;
+}
+
+static CHAR16* get_x509_time (ASN1_TIME *time)
+{
+ BIO *bio = BIO_new (BIO_s_mem());
+ char str[30];
+ int len;
+
+ ASN1_TIME_print (bio, time);
+ len = BIO_read(bio, str, 29);
+ if (len < 0)
+ len = 0;
+ str[len] = '\0';
+ BIO_free (bio);
+
+ return PoolPrint(L"%a", str);
+}
+
+static void show_x509_info (X509 *X509Cert, UINT8 *hash)
+{
+ ASN1_INTEGER *serial;
+ BIGNUM *bnser;
+ unsigned char hexbuf[30];
+ X509_NAME *X509Name;
+ ASN1_TIME *time;
+ CHAR16 *issuer = NULL;
+ CHAR16 *subject = NULL;
+ CHAR16 *from = NULL;
+ CHAR16 *until = NULL;
+ POOL_PRINT hash_string1;
+ POOL_PRINT hash_string2;
+ POOL_PRINT serial_string;
+ int fields = 0;
+ CHAR16 **text;
+ int i = 0;
+
+ ZeroMem(&hash_string1, sizeof(hash_string1));
+ ZeroMem(&hash_string2, sizeof(hash_string2));
+ ZeroMem(&serial_string, sizeof(serial_string));
+
+ serial = X509_get_serialNumber(X509Cert);
+ if (serial) {
+ int i, n;
+ bnser = ASN1_INTEGER_to_BN(serial, NULL);
+ n = BN_bn2bin(bnser, hexbuf);
+ for (i = 0; i < n; i++) {
+ CatPrint(&serial_string, L"%02x:", hexbuf[i]);
+ }
+ }
+
+ if (serial_string.str)
+ fields++;
+
+ X509Name = X509_get_issuer_name(X509Cert);
+ if (X509Name) {
+ issuer = get_x509_name(X509Name);
+ if (issuer)
+ fields++;
+ }
+
+ X509Name = X509_get_subject_name(X509Cert);
+ if (X509Name) {
+ subject = get_x509_name(X509Name);
+ if (subject)
+ fields++;
+ }
+
+ time = X509_get_notBefore(X509Cert);
+ if (time) {
+ from = get_x509_time(time);
+ if (from)
+ fields++;
+ }
+
+ time = X509_get_notAfter(X509Cert);
+ if (time) {
+ until = get_x509_time(time);
+ if (until)
+ fields++;
+ }
+
+ for (i=0; i<10; i++)
+ CatPrint(&hash_string1, L"%02x ", hash[i]);
+ for (i=10; i<20; i++)
+ CatPrint(&hash_string2, L"%02x ", hash[i]);
+
+ if (hash_string1.str)
+ fields++;
+
+ if (hash_string2.str)
+ fields++;
+
+ if (!fields)
+ return;
+
+ i = 0;
+ text = AllocateZeroPool(sizeof(CHAR16 *) * (fields*3 + 1));
+ if (serial_string.str) {
+ text[i++] = StrDuplicate(L"[Serial Number]");
+ text[i++] = serial_string.str;
+ text[i++] = StrDuplicate(L"");
+ }
+ if (issuer) {
+ text[i++] = StrDuplicate(L"[Issuer]");
+ text[i++] = issuer;
+ text[i++] = StrDuplicate(L"");
+ }
+ if (subject) {
+ text[i++] = StrDuplicate(L"[Subject]");
+ text[i++] = subject;
+ text[i++] = StrDuplicate(L"");
+ }
+ if (from) {
+ text[i++] = StrDuplicate(L"[Valid Not Before]");
+ text[i++] = from;
+ text[i++] = StrDuplicate(L"");
+ }
+ if (until) {
+ text[i++] = StrDuplicate(L"[Valid Not After]");
+ text[i++] = until;
+ text[i++] = StrDuplicate(L"");
+ }
+ if (hash_string1.str) {
+ text[i++] = StrDuplicate(L"[Fingerprint]");
+ text[i++] = hash_string1.str;
+ }
+ if (hash_string2.str) {
+ text[i++] = hash_string2.str;
+ text[i++] = StrDuplicate(L"");
+ }
+ text[i] = NULL;
+
+ console_print_box(text, -1);
+
+ for (i=0; text[i] != NULL; i++)
+ FreePool(text[i]);
+
+ FreePool(text);
+}
+
+static void show_efi_hash (UINT8 *hash)
+{
+ CHAR16 *text[5];
+ POOL_PRINT hash_string1;
+ POOL_PRINT hash_string2;
+ int i;
+
+ ZeroMem(&hash_string1, sizeof(hash_string1));
+ ZeroMem(&hash_string2, sizeof(hash_string2));
+
+ text[0] = L"SHA256 hash";
+ text[1] = L"";
+
+ for (i=0; i<16; i++)
+ CatPrint(&hash_string1, L"%02x ", hash[i]);
+ for (i=16; i<32; i++)
+ CatPrint(&hash_string2, L"%02x ", hash[i]);
+
+ text[2] = hash_string1.str;
+ text[3] = hash_string2.str;
+ text[4] = NULL;
+
+ console_print_box(text, -1);
+
+ if (hash_string1.str)
+ FreePool(hash_string1.str);
+
+ if (hash_string2.str)
+ FreePool(hash_string2.str);
+}
+
+static void show_mok_info (void *Mok, UINTN MokSize)
+{
+ EFI_STATUS efi_status;
+ UINT8 hash[SHA1_DIGEST_SIZE];
+ X509 *X509Cert;
+
+ if (!Mok || MokSize == 0)
+ return;
+
+ if (MokSize != SHA256_DIGEST_SIZE) {
+ efi_status = get_sha1sum(Mok, MokSize, hash);
+
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to compute MOK fingerprint");
+ return;
+ }
+
+ if (X509ConstructCertificate(Mok, MokSize,
+ (UINT8 **) &X509Cert) && X509Cert != NULL) {
+ show_x509_info(X509Cert, hash);
+ X509_free(X509Cert);
+ } else {
+ console_notify(L"Not a valid X509 certificate");
+ return;
+ }
+ } else {
+ show_efi_hash(Mok);
+ }
+}
+
+static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
+{
+ INTN MokNum = 0;
+ MokListNode *keys = NULL;
+ INTN key_num = 0;
+ CHAR16 **menu_strings;
+ int i;
+
+ if (KeyListSize < (sizeof(EFI_SIGNATURE_LIST) +
+ sizeof(EFI_SIGNATURE_DATA))) {
+ console_notify(L"No MOK keys found");
+ return 0;
+ }
+
+ MokNum = count_keys(KeyList, KeyListSize);
+ if (MokNum == 0)
+ return 0;
+ keys = build_mok_list(MokNum, KeyList, KeyListSize);
+
+ if (!keys) {
+ console_notify(L"Failed to construct key list");
+ return 0;
+ }
+
+ menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (MokNum + 2));
+
+ if (!menu_strings)
+ return EFI_OUT_OF_RESOURCES;
+
+ for (i=0; i= line_max &&
+ key.UnicodeChar != CHAR_BACKSPACE) ||
+ key.UnicodeChar == CHAR_NULL ||
+ key.UnicodeChar == CHAR_TAB ||
+ key.UnicodeChar == CHAR_LINEFEED ||
+ key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
+ continue;
+ }
+
+ if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) {
+ continue;
+ } else if (key.UnicodeChar == CHAR_BACKSPACE) {
+ if (show) {
+ Print(L"\b");
+ }
+ line[--count] = '\0';
+ continue;
+ }
+
+ if (show) {
+ Print(L"%c", key.UnicodeChar);
+ }
+
+ line[count++] = key.UnicodeChar;
+ } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ Print(L"\n");
+
+ *length = count;
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password,
+ UINT32 pw_length, UINT8 *hash)
+{
+ EFI_STATUS status;
+ unsigned int ctxsize;
+ void *ctx = NULL;
+
+ ctxsize = Sha256GetContextSize();
+ ctx = AllocatePool(ctxsize);
+
+ if (!ctx) {
+ console_notify(L"Unable to allocate memory for hash context");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!Sha256Init(ctx)) {
+ console_notify(L"Unable to initialise hash");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ if (Data && DataSize) {
+ if (!(Sha256Update(ctx, Data, DataSize))) {
+ console_notify(L"Unable to generate hash");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+ }
+
+ if (!(Sha256Update(ctx, password, pw_length))) {
+ console_notify(L"Unable to generate hash");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ if (!(Sha256Final(ctx, hash))) {
+ console_notify(L"Unable to finalise hash");
+ status = EFI_OUT_OF_RESOURCES;
+ goto done;
+ }
+
+ status = EFI_SUCCESS;
+done:
+ return status;
+}
+
+static void console_save_and_set_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
+{
+ if (!SavedMode) {
+ Print(L"Invalid parameter: SavedMode\n");
+ return;
+ }
+
+ CopyMem(SavedMode, ST->ConOut->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE));
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+}
+
+static void console_restore_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
+{
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut,
+ SavedMode->CursorVisible);
+ uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut,
+ SavedMode->CursorColumn, SavedMode->CursorRow);
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
+ SavedMode->Attribute);
+}
+
+static UINT32 get_password (CHAR16 *prompt, CHAR16 *password, UINT32 max)
+{
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ CHAR16 *str;
+ CHAR16 *message[2];
+ UINTN length;
+ UINT32 pw_length;
+
+ if (!prompt)
+ prompt = L"Password:";
+
+ console_save_and_set_mode(&SavedMode);
+
+ str = PoolPrint(L"%s ", prompt);
+ if (!str) {
+ console_errorbox(L"Failed to allocate prompt");
+ return 0;
+ }
+
+ message[0] = str;
+ message[1] = NULL;
+ length = StrLen(message[0]);
+ console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1);
+ get_line(&pw_length, password, max, 0);
+
+ console_restore_mode(&SavedMode);
+
+ FreePool(str);
+
+ return pw_length;
+}
+
+static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
+ void *Data, UINTN DataSize,
+ UINT8 *auth, CHAR16 *prompt)
+{
+ EFI_STATUS status;
+ UINT8 hash[128];
+ UINT8 *auth_hash;
+ UINT32 auth_size;
+ CHAR16 password[PASSWORD_MAX];
+ UINT32 pw_length;
+ UINT8 fail_count = 0;
+ unsigned int i;
+
+ if (pw_crypt) {
+ auth_hash = pw_crypt->hash;
+ auth_size = get_hash_size (pw_crypt->method);
+ if (auth_size == 0)
+ return EFI_INVALID_PARAMETER;
+ } else if (auth) {
+ auth_hash = auth;
+ auth_size = SHA256_DIGEST_SIZE;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ while (fail_count < 3) {
+ pw_length = get_password(prompt, password, PASSWORD_MAX);
+
+ if (pw_length < PASSWORD_MIN || pw_length > PASSWORD_MAX) {
+ console_errorbox(L"Invalid password length");
+ fail_count++;
+ continue;
+ }
+
+ /*
+ * Compute password hash
+ */
+ if (pw_crypt) {
+ char pw_ascii[PASSWORD_MAX + 1];
+ for (i = 0; i < pw_length; i++)
+ pw_ascii[i] = (char)password[i];
+ pw_ascii[pw_length] = '\0';
+
+ status = password_crypt(pw_ascii, pw_length, pw_crypt, hash);
+ } else {
+ /*
+ * For backward compatibility
+ */
+ status = compute_pw_hash(Data, DataSize, (UINT8 *)password,
+ pw_length * sizeof(CHAR16), hash);
+ }
+ if (status != EFI_SUCCESS) {
+ console_errorbox(L"Unable to generate password hash");
+ fail_count++;
+ continue;
+ }
+
+ if (CompareMem(auth_hash, hash, auth_size) != 0) {
+ console_errorbox(L"Password doesn't match");
+ fail_count++;
+ continue;
+ }
+
+ break;
+ }
+
+ if (fail_count >= 3)
+ return EFI_ACCESS_DENIED;
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ UINT8 auth[PASSWORD_CRYPT_SIZE];
+ UINTN auth_size = PASSWORD_CRYPT_SIZE;
+ UINT32 attributes;
+
+ if (authenticate) {
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
+ &shim_lock_guid,
+ &attributes, &auth_size, auth);
+
+ if (efi_status != EFI_SUCCESS ||
+ (auth_size != SHA256_DIGEST_SIZE &&
+ auth_size != PASSWORD_CRYPT_SIZE)) {
+ console_error(L"Failed to get MokAuth", efi_status);
+ return efi_status;
+ }
+
+ if (auth_size == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)auth,
+ NULL, 0, NULL, NULL);
+ } else {
+ efi_status = match_password(NULL, MokNew, MokNewSize,
+ auth, NULL);
+ }
+ if (efi_status != EFI_SUCCESS)
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (!MokNewSize) {
+ /* Delete MOK */
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0, NULL);
+ } else {
+ /* Write new MOK */
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_APPEND_WRITE,
+ MokNewSize, MokNew);
+ }
+
+ if (efi_status != EFI_SUCCESS) {
+ console_error(L"Failed to set variable", efi_status);
+ return efi_status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) {
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+
+ if (list_keys(MokNew, MokNewSize, L"[Enroll MOK]") != EFI_SUCCESS)
+ return 0;
+
+ if (console_yes_no((CHAR16 *[]){L"Enroll the key(s)?", NULL}) == 0)
+ return 0;
+
+ efi_status = store_keys(MokNew, MokNewSize, auth);
+
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to enroll keys\n");
+ return -1;
+ }
+
+ if (auth) {
+ LibDeleteVariable(L"MokNew", &shim_lock_guid);
+ LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+
+ console_notify(L"The system must now be rebooted");
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+ EFI_SUCCESS, 0, NULL);
+ console_notify(L"Failed to reboot");
+ return -1;
+ }
+
+ return 0;
+}
+
+static INTN mok_reset_prompt ()
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ if (console_yes_no((CHAR16 *[]){L"Erase all stored keys?", NULL }) == 0)
+ return 0;
+
+ efi_status = store_keys(NULL, 0, TRUE);
+
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to erase keys\n");
+ return -1;
+ }
+
+ LibDeleteVariable(L"MokNew", &shim_lock_guid);
+ LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+
+ console_notify(L"The system must now be rebooted");
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+ EFI_SUCCESS, 0, NULL);
+ console_notify(L"Failed to reboot\n");
+ return -1;
+}
+
+static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *CertData;
+ void *Data = NULL, *ptr;
+ INTN DataSize = 0;
+ int i;
+
+ for (i = 0; i < key_num; i++) {
+ if (list[i].Mok == NULL)
+ continue;
+
+ DataSize += sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
+ DataSize += list[i].MokSize;
+ }
+
+ Data = AllocatePool(DataSize);
+ if (Data == NULL && DataSize != 0)
+ return EFI_OUT_OF_RESOURCES;
+
+ ptr = Data;
+
+ for (i = 0; i < key_num; i++) {
+ if (list[i].Mok == NULL)
+ continue;
+
+ CertList = (EFI_SIGNATURE_LIST *)ptr;
+ CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) +
+ sizeof(EFI_SIGNATURE_LIST));
+
+ CertList->SignatureType = list[i].Type;
+ CertList->SignatureListSize = list[i].MokSize +
+ sizeof(EFI_SIGNATURE_LIST) +
+ sizeof(EFI_SIGNATURE_DATA) - 1;
+ CertList->SignatureHeaderSize = 0;
+ CertList->SignatureSize = list[i].MokSize + sizeof(EFI_GUID);
+
+ CertData->SignatureOwner = shim_lock_guid;
+ CopyMem(CertData->SignatureData, list[i].Mok, list[i].MokSize);
+
+ ptr = (uint8_t *)ptr + sizeof(EFI_SIGNATURE_LIST) +
+ sizeof(EFI_GUID) + list[i].MokSize;
+ }
+
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ DataSize, Data);
+ if (Data)
+ FreePool(Data);
+
+ if (efi_status != EFI_SUCCESS) {
+ console_error(L"Failed to set variable", efi_status);
+ return efi_status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ UINT8 auth[PASSWORD_CRYPT_SIZE];
+ UINTN auth_size = PASSWORD_CRYPT_SIZE;
+ UINT32 attributes;
+ UINT8 *MokListData = NULL;
+ UINTN MokListDataSize = 0;
+ MokListNode *mok, *del_key;
+ INTN mok_num, del_num;
+ int i, j;
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
+ &shim_lock_guid,
+ &attributes, &auth_size, auth);
+
+ if (efi_status != EFI_SUCCESS ||
+ (auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_CRYPT_SIZE)) {
+ console_error(L"Failed to get MokDelAuth", efi_status);
+ return efi_status;
+ }
+
+ if (auth_size == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)auth, NULL, 0,
+ NULL, NULL);
+ } else {
+ efi_status = match_password(NULL, MokDel, MokDelSize, auth, NULL);
+ }
+ if (efi_status != EFI_SUCCESS)
+ return EFI_ACCESS_DENIED;
+
+ efi_status = get_variable_attr (L"MokList", &MokListData, &MokListDataSize,
+ shim_lock_guid, &attributes);
+ if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+ console_alertbox((CHAR16 *[]){L"MokList is compromised!",
+ L"Erase all keys in MokList!",
+ NULL});
+ if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to erase MokList");
+ }
+ return EFI_ACCESS_DENIED;
+ }
+
+ /* Nothing to do */
+ if (!MokListData || MokListDataSize == 0)
+ return EFI_SUCCESS;
+
+ /* Construct lists */
+ mok_num = count_keys(MokListData, MokListDataSize);
+ mok = build_mok_list(mok_num, MokListData, MokListDataSize);
+ del_num = count_keys(MokDel, MokDelSize);
+ del_key = build_mok_list(del_num, MokDel, MokDelSize);
+
+ /* Search and destroy */
+ for (i = 0; i < del_num; i++) {
+ UINT32 key_size = del_key[i].MokSize;
+ void *key = del_key[i].Mok;
+ for (j = 0; j < mok_num; j++) {
+ if (mok[j].MokSize == key_size &&
+ CompareMem(key, mok[j].Mok, key_size) == 0) {
+ /* Remove the key */
+ mok[j].Mok = NULL;
+ mok[j].MokSize = 0;
+ }
+ }
+ }
+
+ efi_status = write_back_mok_list(mok, mok_num);
+
+ if (MokListData)
+ FreePool(MokListData);
+ if (mok)
+ FreePool(mok);
+ if (del_key)
+ FreePool(del_key);
+
+ return efi_status;
+}
+
+static INTN mok_deletion_prompt (void *MokDel, UINTN MokDelSize)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+
+ if (list_keys(MokDel, MokDelSize, L"[Delete MOK]") != EFI_SUCCESS) {
+ return 0;
+ }
+
+ if (console_yes_no((CHAR16 *[]){L"Delete the key(s)?", NULL}) == 0)
+ return 0;
+
+ efi_status = delete_keys(MokDel, MokDelSize);
+
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to delete keys");
+ return -1;
+ }
+
+ LibDeleteVariable(L"MokDel", &shim_lock_guid);
+ LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+
+ console_notify(L"The system must now be rebooted");
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+ EFI_SUCCESS, 0, NULL);
+ console_notify(L"Failed to reboot");
+ return -1;
+}
+
+static CHAR16 get_password_charater (CHAR16 *prompt)
+{
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ EFI_STATUS status;
+ CHAR16 *message[2];
+ CHAR16 character;
+ UINTN length;
+ UINT32 pw_length;
+
+ if (!prompt)
+ prompt = L"Password charater: ";
+
+ console_save_and_set_mode(&SavedMode);
+
+ message[0] = prompt;
+ message[1] = NULL;
+ length = StrLen(message[0]);
+ console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1);
+ status = get_line(&pw_length, &character, 1, 0);
+ if (EFI_ERROR(status))
+ character = 0;
+
+ console_restore_mode(&SavedMode);
+
+ return character;
+}
+
+static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) {
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ MokSBvar *var = MokSB;
+ CHAR16 *message[4];
+ CHAR16 pass1, pass2, pass3;
+ CHAR16 *str;
+ UINT8 fail_count = 0;
+ UINT8 sbval = 1;
+ UINT8 pos1, pos2, pos3;
+ int ret;
+
+ if (MokSBSize != sizeof(MokSBvar)) {
+ console_notify(L"Invalid MokSB variable contents");
+ return -1;
+ }
+
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ message[0] = L"Change Secure Boot state";
+ message[1] = NULL;
+
+ console_save_and_set_mode(&SavedMode);
+ console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
+ console_restore_mode(&SavedMode);
+
+ while (fail_count < 3) {
+ RandomBytes (&pos1, sizeof(pos1));
+ pos1 = (pos1 % var->PWLen);
+
+ do {
+ RandomBytes (&pos2, sizeof(pos2));
+ pos2 = (pos2 % var->PWLen);
+ } while (pos2 == pos1);
+
+ do {
+ RandomBytes (&pos3, sizeof(pos3));
+ pos3 = (pos3 % var->PWLen) ;
+ } while (pos3 == pos2 || pos3 == pos1);
+
+ str = PoolPrint(L"Enter password character %d: ", pos1 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return -1;
+ }
+ pass1 = get_password_charater(str);
+ FreePool(str);
+
+ str = PoolPrint(L"Enter password character %d: ", pos2 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return -1;
+ }
+ pass2 = get_password_charater(str);
+ FreePool(str);
+
+ str = PoolPrint(L"Enter password character %d: ", pos3 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return -1;
+ }
+ pass3 = get_password_charater(str);
+ FreePool(str);
+
+ if (pass1 != var->Password[pos1] ||
+ pass2 != var->Password[pos2] ||
+ pass3 != var->Password[pos3]) {
+ Print(L"Invalid character\n");
+ fail_count++;
+ } else {
+ break;
+ }
+ }
+
+ if (fail_count >= 3) {
+ console_notify(L"Password limit reached");
+ return -1;
+ }
+
+ if (var->MokSBState == 0)
+ ret = console_yes_no((CHAR16 *[]){L"Disable Secure Boot", NULL});
+ else
+ ret = console_yes_no((CHAR16 *[]){L"Enable Secure Boot", NULL});
+
+ if (ret == 0) {
+ LibDeleteVariable(L"MokSB", &shim_lock_guid);
+ return -1;
+ }
+
+ if (var->MokSBState == 0) {
+ efi_status = uefi_call_wrapper(RT->SetVariable,
+ 5, L"MokSBState",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 1, &sbval);
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to set Secure Boot state");
+ return -1;
+ }
+ } else {
+ efi_status = uefi_call_wrapper(RT->SetVariable,
+ 5, L"MokSBState",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0, NULL);
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to delete Secure Boot state");
+ return -1;
+ }
+ }
+
+ console_notify(L"The system must now be rebooted");
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+ EFI_SUCCESS, 0, NULL);
+ console_notify(L"Failed to reboot");
+ return -1;
+}
+
+static INTN mok_db_prompt (void *MokDB, UINTN MokDBSize) {
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ MokDBvar *var = MokDB;
+ CHAR16 *message[4];
+ CHAR16 pass1, pass2, pass3;
+ CHAR16 *str;
+ UINT8 fail_count = 0;
+ UINT8 dbval = 1;
+ UINT8 pos1, pos2, pos3;
+ int ret;
+
+ if (MokDBSize != sizeof(MokDBvar)) {
+ console_notify(L"Invalid MokDB variable contents");
+ return -1;
+ }
+
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ message[0] = L"Change DB state";
+ message[1] = NULL;
+
+ console_save_and_set_mode(&SavedMode);
+ console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
+ console_restore_mode(&SavedMode);
+
+ while (fail_count < 3) {
+ RandomBytes (&pos1, sizeof(pos1));
+ pos1 = (pos1 % var->PWLen);
+
+ do {
+ RandomBytes (&pos2, sizeof(pos2));
+ pos2 = (pos2 % var->PWLen);
+ } while (pos2 == pos1);
+
+ do {
+ RandomBytes (&pos3, sizeof(pos3));
+ pos3 = (pos3 % var->PWLen) ;
+ } while (pos3 == pos2 || pos3 == pos1);
+
+ str = PoolPrint(L"Enter password character %d: ", pos1 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return -1;
+ }
+ pass1 = get_password_charater(str);
+ FreePool(str);
+
+ str = PoolPrint(L"Enter password character %d: ", pos2 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return -1;
+ }
+ pass2 = get_password_charater(str);
+ FreePool(str);
+
+ str = PoolPrint(L"Enter password character %d: ", pos3 + 1);
+ if (!str) {
+ console_errorbox(L"Failed to allocate buffer");
+ return -1;
+ }
+ pass3 = get_password_charater(str);
+ FreePool(str);
+
+ if (pass1 != var->Password[pos1] ||
+ pass2 != var->Password[pos2] ||
+ pass3 != var->Password[pos3]) {
+ Print(L"Invalid character\n");
+ fail_count++;
+ } else {
+ break;
+ }
+ }
+
+ if (fail_count >= 3) {
+ console_notify(L"Password limit reached");
+ return -1;
+ }
+
+ if (var->MokDBState == 0)
+ ret = console_yes_no((CHAR16 *[]){L"Ignore DB certs/hashes", NULL});
+ else
+ ret = console_yes_no((CHAR16 *[]){L"Use DB certs/hashes", NULL});
+
+ if (ret == 0) {
+ LibDeleteVariable(L"MokDB", &shim_lock_guid);
+ return -1;
+ }
+
+ if (var->MokDBState == 0) {
+ efi_status = uefi_call_wrapper(RT->SetVariable,
+ 5, L"MokDBState",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 1, &dbval);
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to set DB state");
+ return -1;
+ }
+ } else {
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5,
+ L"MokDBState",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0, NULL);
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to delete DB state");
+ return -1;
+ }
+ }
+
+ console_notify(L"The system must now be rebooted");
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+ EFI_SUCCESS, 0, NULL);
+ console_notify(L"Failed to reboot");
+ return -1;
+}
+
+static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ UINT8 hash[PASSWORD_CRYPT_SIZE];
+ UINT8 clear = 0;
+
+ if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_CRYPT_SIZE) {
+ console_notify(L"Invalid MokPW variable contents");
+ return -1;
+ }
+
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ SetMem(hash, PASSWORD_CRYPT_SIZE, 0);
+
+ if (MokPWSize == PASSWORD_CRYPT_SIZE) {
+ if (CompareMem(MokPW, hash, PASSWORD_CRYPT_SIZE) == 0)
+ clear = 1;
+ } else {
+ if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0)
+ clear = 1;
+ }
+
+ if (clear) {
+ if (console_yes_no((CHAR16 *[]){L"Clear MOK password?", NULL}) == 0)
+ return 0;
+
+ uefi_call_wrapper(RT->SetVariable, 5, L"MokPWStore",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0, NULL);
+ LibDeleteVariable(L"MokPW", &shim_lock_guid);
+ console_notify(L"The system must now be rebooted");
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0,
+ NULL);
+ console_notify(L"Failed to reboot");
+ return -1;
+ }
+
+ if (MokPWSize == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)MokPW, NULL, 0,
+ NULL, L"Confirm MOK passphrase: ");
+ } else {
+ efi_status = match_password(NULL, NULL, 0, MokPW,
+ L"Confirm MOK passphrase: ");
+ }
+
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Password limit reached");
+ return -1;
+ }
+
+ if (console_yes_no((CHAR16 *[]){L"Set MOK password?", NULL}) == 0)
+ return 0;
+
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5,
+ L"MokPWStore",
+ &shim_lock_guid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ MokPWSize, MokPW);
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Failed to set MOK password");
+ return -1;
+ }
+
+ LibDeleteVariable(L"MokPW", &shim_lock_guid);
+
+ console_notify(L"The system must now be rebooted");
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0,
+ NULL);
+ console_notify(L"Failed to reboot");
+ return -1;
+}
+
+static BOOLEAN verify_certificate(UINT8 *cert, UINTN size)
+{
+ X509 *X509Cert;
+ UINTN length;
+ if (!cert || size < 0)
+ return FALSE;
+
+ /*
+ * A DER encoding x509 certificate starts with SEQUENCE(0x30),
+ * the number of length bytes, and the number of value bytes.
+ * The size of a x509 certificate is usually between 127 bytes
+ * and 64KB. For convenience, assume the number of value bytes
+ * is 2, i.e. the second byte is 0x82.
+ */
+ if (cert[0] != 0x30 || cert[1] != 0x82) {
+ console_notify(L"Not a DER encoding X509 certificate");
+ return FALSE;
+ }
+
+ length = (cert[2]<<8 | cert[3]);
+ if (length != (size - 4)) {
+ console_notify(L"Invalid X509 certificate: Inconsistent size");
+ return FALSE;
+ }
+
+ if (!(X509ConstructCertificate(cert, size, (UINT8 **) &X509Cert)) ||
+ X509Cert == NULL) {
+ console_notify(L"Invalid X509 certificate");
+ return FALSE;
+ }
+
+ X509_free(X509Cert);
+ return TRUE;
+}
+
+static EFI_STATUS enroll_file (void *data, UINTN datasize, BOOLEAN hash)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *CertData;
+ UINTN mokbuffersize;
+ void *mokbuffer = NULL;
+
+ if (hash) {
+ UINT8 sha256[SHA256_DIGEST_SIZE];
+ UINT8 sha1[SHA1_DIGEST_SIZE];
+ SHIM_LOCK *shim_lock;
+ EFI_GUID shim_guid = SHIM_LOCK_GUID;
+ PE_COFF_LOADER_IMAGE_CONTEXT context;
+
+ status = LibLocateProtocol(&shim_guid, (VOID **)&shim_lock);
+
+ if (status != EFI_SUCCESS)
+ goto out;
+
+ mokbuffersize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID) +
+ SHA256_DIGEST_SIZE;
+
+ mokbuffer = AllocatePool(mokbuffersize);
+
+ if (!mokbuffer)
+ goto out;
+
+ status = shim_lock->Context(data, datasize, &context);
+
+ if (status != EFI_SUCCESS)
+ goto out;
+
+ status = shim_lock->Hash(data, datasize, &context, sha256,
+ sha1);
+
+ if (status != EFI_SUCCESS)
+ goto out;
+
+ CertList = mokbuffer;
+ CertList->SignatureType = EFI_CERT_SHA256_GUID;
+ CertList->SignatureSize = 16 + SHA256_DIGEST_SIZE;
+ CertData = (EFI_SIGNATURE_DATA *)(((UINT8 *)mokbuffer) +
+ sizeof(EFI_SIGNATURE_LIST));
+ CopyMem(CertData->SignatureData, sha256, SHA256_DIGEST_SIZE);
+ } else {
+ mokbuffersize = datasize + sizeof(EFI_SIGNATURE_LIST) +
+ sizeof(EFI_GUID);
+ mokbuffer = AllocatePool(mokbuffersize);
+
+ if (!mokbuffer)
+ goto out;
+
+ CertList = mokbuffer;
+ CertList->SignatureType = X509_GUID;
+ CertList->SignatureSize = 16 + datasize;
+
+ memcpy(mokbuffer + sizeof(EFI_SIGNATURE_LIST) + 16, data,
+ datasize);
+
+ CertData = (EFI_SIGNATURE_DATA *)(((UINT8 *)mokbuffer) +
+ sizeof(EFI_SIGNATURE_LIST));
+ }
+
+ CertList->SignatureListSize = mokbuffersize;
+ CertList->SignatureHeaderSize = 0;
+ CertData->SignatureOwner = shim_lock_guid;
+
+ if (!hash) {
+ if (!verify_certificate(CertData->SignatureData, datasize))
+ goto out;
+ }
+
+ mok_enrollment_prompt(mokbuffer, mokbuffersize, FALSE);
+out:
+ if (mokbuffer)
+ FreePool(mokbuffer);
+
+ return status;
+}
+
+static void mok_hash_enroll(void)
+{
+ EFI_STATUS efi_status;
+ CHAR16 *file_name = NULL;
+ EFI_HANDLE im = NULL;
+ EFI_FILE *file = NULL;
+ UINTN filesize;
+ void *data;
+
+ simple_file_selector(&im, (CHAR16 *[]){
+ L"Select Binary",
+ L"",
+ L"The Selected Binary will have its hash Enrolled",
+ L"This means it will Subsequently Boot with no prompting",
+ L"Remember to make sure it is a genuine binary before Enroling its hash",
+ NULL
+ }, L"\\", L"", &file_name);
+
+ if (!file_name)
+ return;
+
+ efi_status = simple_file_open(im, file_name, &file, EFI_FILE_MODE_READ);
+
+ if (efi_status != EFI_SUCCESS) {
+ console_error(L"Unable to open file", efi_status);
+ return;
+ }
+
+ simple_file_read_all(file, &filesize, &data);
+ simple_file_close(file);
+
+ if (!filesize) {
+ console_error(L"Unable to read file", efi_status);
+ return;
+ }
+
+ efi_status = enroll_file(data, filesize, TRUE);
+
+ if (efi_status != EFI_SUCCESS)
+ console_error(L"Hash failed (did you select a valid EFI binary?)", efi_status);
+
+ FreePool(data);
+}
+
+static CHAR16 *der_suffix[] = {
+ L".cer",
+ L".der",
+ L".crt",
+ NULL
+};
+
+static BOOLEAN check_der_suffix (CHAR16 *file_name)
+{
+ CHAR16 suffix[5];
+ int i;
+
+ if (!file_name || StrLen(file_name) <= 4)
+ return FALSE;
+
+ suffix[0] = '\0';
+ StrCat(suffix, file_name + StrLen(file_name) - 4);
+
+ StrLwr (suffix);
+ for (i = 0; der_suffix[i] != NULL; i++) {
+ if (StrCmp(suffix, der_suffix[i]) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void mok_key_enroll(void)
+{
+ EFI_STATUS efi_status;
+ CHAR16 *file_name = NULL;
+ EFI_HANDLE im = NULL;
+ EFI_FILE *file = NULL;
+ UINTN filesize;
+ void *data;
+
+ simple_file_selector(&im, (CHAR16 *[]){
+ L"Select Key",
+ L"",
+ L"The selected key will be enrolled into the MOK database",
+ L"This means any binaries signed with it will be run without prompting",
+ L"Remember to make sure it is a genuine key before Enroling it",
+ NULL
+ }, L"\\", L"", &file_name);
+
+ if (!file_name)
+ return;
+
+ if (!check_der_suffix(file_name)) {
+ console_alertbox((CHAR16 *[]){
+ L"Unsupported Format",
+ L"",
+ L"Only DER encoded certificate (*.cer/der/crt) is supported",
+ NULL});
+ return;
+ }
+
+ efi_status = simple_file_open(im, file_name, &file, EFI_FILE_MODE_READ);
+
+ if (efi_status != EFI_SUCCESS) {
+ console_error(L"Unable to open file", efi_status);
+ return;
+ }
+
+ simple_file_read_all(file, &filesize, &data);
+ simple_file_close(file);
+
+ if (!filesize) {
+ console_error(L"Unable to read file", efi_status);
+ return;
+ }
+
+ enroll_file(data, filesize, FALSE);
+ FreePool(data);
+}
+
+static BOOLEAN verify_pw(BOOLEAN *protected)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status;
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ UINT8 pwhash[PASSWORD_CRYPT_SIZE];
+ UINTN size = PASSWORD_CRYPT_SIZE;
+ UINT32 attributes;
+ CHAR16 *message[2];
+
+ *protected = FALSE;
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
+ &shim_lock_guid, &attributes, &size,
+ pwhash);
+
+ /*
+ * If anything can attack the password it could just set it to a
+ * known value, so there's no safety advantage in failing to validate
+ * purely because of a failure to read the variable
+ */
+ if (efi_status != EFI_SUCCESS ||
+ (size != SHA256_DIGEST_SIZE && size != PASSWORD_CRYPT_SIZE))
+ return TRUE;
+
+ if (attributes & EFI_VARIABLE_RUNTIME_ACCESS)
+ return TRUE;
+
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ /* Draw the background */
+ console_save_and_set_mode(&SavedMode);
+ message[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
+ message[1] = NULL;
+ console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
+ FreePool(message[0]);
+ console_restore_mode(&SavedMode);
+
+ if (size == PASSWORD_CRYPT_SIZE) {
+ efi_status = match_password((PASSWORD_CRYPT *)pwhash, NULL, 0,
+ NULL, L"Enter MOK password:");
+ } else {
+ efi_status = match_password(NULL, NULL, 0, pwhash,
+ L"Enter MOK password:");
+ }
+ if (efi_status != EFI_SUCCESS) {
+ console_notify(L"Password limit reached");
+ return FALSE;
+ }
+
+ *protected = TRUE;
+
+ return TRUE;
+}
+
+static int draw_countdown()
+{
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ EFI_INPUT_KEY key;
+ EFI_STATUS status;
+ UINTN cols, rows;
+ CHAR16 *title[2];
+ CHAR16 *message = L"Press any key to perform MOK management";
+ int timeout = 10, wait = 10000000;
+
+ console_save_and_set_mode (&SavedMode);
+
+ title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
+ title[1] = NULL;
+
+ console_print_box_at(title, -1, 0, 0, -1, -1, 1, 1);
+
+ uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
+ ST->ConOut->Mode->Mode, &cols, &rows);
+
+ PrintAt((cols - StrLen(message))/2, rows/2, message);
+ while (1) {
+ if (timeout > 1)
+ PrintAt(2, rows - 3, L"Booting in %d seconds ", timeout);
+ else if (timeout)
+ PrintAt(2, rows - 3, L"Booting in %d second ", timeout);
+
+ status = WaitForSingleEvent(ST->ConIn->WaitForKey, wait);
+
+ if (status != EFI_TIMEOUT) {
+ /* Clear the key in the queue */
+ uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
+ ST->ConIn, &key);
+ break;
+ }
+
+ timeout--;
+ if (!timeout)
+ break;
+ }
+
+ FreePool(title[0]);
+
+ console_restore_mode(&SavedMode);
+
+ return timeout;
+}
+
+typedef enum {
+ MOK_CONTINUE_BOOT,
+ MOK_RESET_MOK,
+ MOK_ENROLL_MOK,
+ MOK_DELETE_MOK,
+ MOK_CHANGE_SB,
+ MOK_SET_PW,
+ MOK_CHANGE_DB,
+ MOK_KEY_ENROLL,
+ MOK_HASH_ENROLL
+} mok_menu_item;
+
+static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
+ void *MokNew, UINTN MokNewSize,
+ void *MokDel, UINTN MokDelSize,
+ void *MokSB, UINTN MokSBSize,
+ void *MokPW, UINTN MokPWSize,
+ void *MokDB, UINTN MokDBSize)
+{
+ CHAR16 **menu_strings;
+ mok_menu_item *menu_item;
+ int choice = 0;
+ UINT32 MokAuth = 0;
+ UINT32 MokDelAuth = 0;
+ UINTN menucount = 3, i = 0;
+ EFI_STATUS efi_status;
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ UINT8 auth[PASSWORD_CRYPT_SIZE];
+ UINTN auth_size = PASSWORD_CRYPT_SIZE;
+ UINT32 attributes;
+ BOOLEAN protected;
+ EFI_STATUS ret = EFI_SUCCESS;
+
+ if (verify_pw(&protected) == FALSE)
+ return EFI_ACCESS_DENIED;
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
+ &shim_lock_guid,
+ &attributes, &auth_size, auth);
+
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+ MokAuth = 1;
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth",
+ &shim_lock_guid,
+ &attributes, &auth_size, auth);
+
+ if ((efi_status == EFI_SUCCESS) &&
+ (auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE))
+ MokDelAuth = 1;
+
+ if (MokNew || MokAuth)
+ menucount++;
+
+ if (MokDel || MokDelAuth)
+ menucount++;
+
+ if (MokSB)
+ menucount++;
+
+ if (MokPW)
+ menucount++;
+
+ if (MokDB)
+ menucount++;
+
+ menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (menucount + 1));
+
+ if (!menu_strings)
+ return EFI_OUT_OF_RESOURCES;
+
+ menu_item = AllocateZeroPool(sizeof(mok_menu_item) * menucount);
+
+ if (!menu_item) {
+ FreePool(menu_strings);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ menu_strings[i] = L"Continue boot";
+ menu_item[i] = MOK_CONTINUE_BOOT;
+
+ i++;
+
+ if (MokNew || MokAuth) {
+ if (!MokNew) {
+ menu_strings[i] = L"Reset MOK";
+ menu_item[i] = MOK_RESET_MOK;
+ } else {
+ menu_strings[i] = L"Enroll MOK";
+ menu_item[i] = MOK_ENROLL_MOK;
+ }
+ i++;
+ }
+
+ if (MokDel || MokDelAuth) {
+ menu_strings[i] = L"Delete MOK";
+ menu_item[i] = MOK_DELETE_MOK;
+ i++;
+ }
+
+ if (MokSB) {
+ menu_strings[i] = L"Change Secure Boot state";
+ menu_item[i] = MOK_CHANGE_SB;
+ i++;
+ }
+
+ if (MokPW) {
+ menu_strings[i] = L"Set MOK password";
+ menu_item[i] = MOK_SET_PW;
+ i++;
+ }
+
+ if (MokDB) {
+ menu_strings[i] = L"Change DB state";
+ menu_item[i] = MOK_CHANGE_DB;
+ i++;
+ }
+
+ menu_strings[i] = L"Enroll key from disk";
+ menu_item[i] = MOK_KEY_ENROLL;
+ i++;
+
+ menu_strings[i] = L"Enroll hash from disk";
+ menu_item[i] = MOK_HASH_ENROLL;
+ i++;
+
+ menu_strings[i] = NULL;
+
+ if (protected == FALSE && draw_countdown() == 0)
+ goto out;
+
+ while (choice >= 0) {
+ choice = console_select((CHAR16 *[]){ L"Perform MOK management", NULL },
+ menu_strings, 0);
+
+ if (choice < 0)
+ goto out;
+
+ switch (menu_item[choice]) {
+ case MOK_CONTINUE_BOOT:
+ goto out;
+ case MOK_RESET_MOK:
+ mok_reset_prompt();
+ break;
+ case MOK_ENROLL_MOK:
+ mok_enrollment_prompt(MokNew, MokNewSize, TRUE);
+ break;
+ case MOK_DELETE_MOK:
+ mok_deletion_prompt(MokDel, MokDelSize);
+ break;
+ case MOK_CHANGE_SB:
+ mok_sb_prompt(MokSB, MokSBSize);
+ break;
+ case MOK_SET_PW:
+ mok_pw_prompt(MokPW, MokPWSize);
+ break;
+ case MOK_CHANGE_DB:
+ mok_db_prompt(MokDB, MokDBSize);
+ break;
+ case MOK_KEY_ENROLL:
+ mok_key_enroll();
+ break;
+ case MOK_HASH_ENROLL:
+ mok_hash_enroll();
+ break;
+ }
+ }
+
+out:
+ console_reset();
+
+ FreePool(menu_strings);
+
+ if (menu_item)
+ FreePool(menu_item);
+
+ return ret;
+}
+
+static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0,
+ MokDBSize = 0;
+ void *MokNew = NULL;
+ void *MokDel = NULL;
+ void *MokSB = NULL;
+ void *MokPW = NULL;
+ void *MokDB = NULL;
+ EFI_STATUS status;
+
+ status = get_variable(L"MokNew", (UINT8 **)&MokNew, &MokNewSize,
+ shim_lock_guid);
+ if (status == EFI_SUCCESS) {
+ if (LibDeleteVariable(L"MokNew", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to delete MokNew");
+ }
+ } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokNew", status);
+ }
+
+ status = get_variable(L"MokDel", (UINT8 **)&MokDel, &MokDelSize,
+ shim_lock_guid);
+ if (status == EFI_SUCCESS) {
+ if (LibDeleteVariable(L"MokDel", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to delete MokDel");
+ }
+ } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokDel", status);
+ }
+
+ status = get_variable(L"MokSB", (UINT8 **)&MokSB, &MokSBSize,
+ shim_lock_guid);
+ if (status == EFI_SUCCESS) {
+ if (LibDeleteVariable(L"MokSB", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to delete MokSB");
+ }
+ } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokSB", status);
+ }
+
+ status = get_variable(L"MokPW", (UINT8 **)&MokPW, &MokPWSize,
+ shim_lock_guid);
+ if (status == EFI_SUCCESS) {
+ if (LibDeleteVariable(L"MokPW", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to delete MokPW");
+ }
+ } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokPW", status);
+ }
+
+ status = get_variable(L"MokDB", (UINT8 **)&MokDB, &MokDBSize,
+ shim_lock_guid);
+ if (status == EFI_SUCCESS) {
+ if (LibDeleteVariable(L"MokDB", &shim_lock_guid) != EFI_SUCCESS) {
+ console_notify(L"Failed to delete MokDB");
+ }
+ } else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) {
+ console_error(L"Could not retrieve MokDB", status);
+ }
+
+ enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize,
+ MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize);
+
+ if (MokNew)
+ FreePool (MokNew);
+
+ if (MokDel)
+ FreePool (MokDel);
+
+ if (MokSB)
+ FreePool (MokSB);
+
+ if (MokPW)
+ FreePool (MokPW);
+
+ if (MokDB)
+ FreePool (MokDB);
+
+ LibDeleteVariable(L"MokAuth", &shim_lock_guid);
+ LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS setup_rand (void)
+{
+ EFI_TIME time;
+ EFI_STATUS efi_status;
+ UINT64 seed;
+ BOOLEAN status;
+
+ efi_status = uefi_call_wrapper(RT->GetTime, 2, &time, NULL);
+
+ if (efi_status != EFI_SUCCESS)
+ return efi_status;
+
+ seed = ((UINT64)time.Year << 48) | ((UINT64)time.Month << 40) |
+ ((UINT64)time.Day << 32) | ((UINT64)time.Hour << 24) |
+ ((UINT64)time.Minute << 16) | ((UINT64)time.Second << 8) |
+ ((UINT64)time.Daylight);
+
+ status = RandomSeed((UINT8 *)&seed, sizeof(seed));
+
+ if (!status)
+ return EFI_ABORTED;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
+{
+ EFI_STATUS efi_status;
+
+ InitializeLib(image_handle, systab);
+
+ setup_console(1);
+
+ setup_rand();
+
+ efi_status = check_mok_request(image_handle);
+
+ setup_console(0);
+ return efi_status;
+}
diff --git a/Cryptlib/Include/OpenSslSupport.h b/Cryptlib/Include/OpenSslSupport.h
index 9e56ced..b77838d 100644
--- a/Cryptlib/Include/OpenSslSupport.h
+++ b/Cryptlib/Include/OpenSslSupport.h
@@ -34,7 +34,7 @@ typedef VOID *FILE;
//
// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
//
-#if !defined(__CC_ARM) // if va_list is not already defined
+#if !defined(__CC_ARM) || defined(_STDARG_H) // if va_list is not already defined
/*
* These are now unconditionally #defined by GNU_EFI's efistdarg.h,
* so we should #undef them here before providing a new definition.
@@ -94,7 +94,9 @@ typedef __builtin_va_list VA_LIST;
portably, hence it is provided by a Standard C header file.
For pre-Standard C compilers, here is a version that usually works
(but watch out!): */
+#ifndef offsetof
#define offsetof(type, member) ( (int) & ((type*)0) -> member )
+#endif
//
// Basic types from EFI Application Toolkit required to buiild Open SSL
diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile
index e930656..a7f1dbb 100644
--- a/Cryptlib/Makefile
+++ b/Cryptlib/Makefile
@@ -2,7 +2,8 @@
EFI_INCLUDES = -IInclude -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
CFLAGS = -std=gnu89 -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar \
- -Wall $(EFI_INCLUDES)
+ -Wall $(EFI_INCLUDES) \
+ -ffreestanding -I$(shell $(CC) -print-file-name=include)
ifeq ($(ARCH),x86_64)
CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \
diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile
index f5b7e4f..1a2d07b 100644
--- a/Cryptlib/OpenSSL/Makefile
+++ b/Cryptlib/OpenSSL/Makefile
@@ -2,6 +2,7 @@
EFI_INCLUDES = -I../Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
CFLAGS = -std=gnu89 -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc \
+ -ffreestanding -I$(shell $(CC) -print-file-name=include) \
-Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
ifeq ($(ARCH),x86_64)
@@ -13,10 +14,10 @@ ifeq ($(ARCH),ia32)
-m32 -DTHIRTY_TWO_BIT
endif
ifeq ($(ARCH),aarch64)
- CFLAGS += -O2 -DSIXTY_FOUR_BIT_LONG -ffreestanding -I$(shell $(CC) -print-file-name=include)
+ CFLAGS += -O2 -DSIXTY_FOUR_BIT_LONG
endif
ifeq ($(ARCH),arm)
- CFLAGS += -O2 -DTHIRTY_TWO_BIT -ffreestanding -I$(shell $(CC) -print-file-name=include)
+ CFLAGS += -O2 -DTHIRTY_TWO_BIT
endif
LDFLAGS = -nostdlib -znocombreloc
diff --git a/Makefile b/Makefile
index 9cae609..57616b4 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,8 @@ EFI_LDS = elf_$(ARCH)_efi.lds
DEFAULT_LOADER := \\\\grubx64.efi
CFLAGS = -std=gnu89 -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
-fshort-wchar -Wall -Wsign-compare -Werror -fno-builtin \
- -Werror=sign-compare \
+ -Werror=sign-compare -ffreestanding \
+ -I$(shell $(CC) -print-file-name=include) \
"-DDEFAULT_LOADER=L\"$(DEFAULT_LOADER)\"" \
"-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \
$(EFI_INCLUDES)
@@ -31,19 +32,13 @@ ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
endif
ifeq ($(ARCH),x86_64)
- CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
+ -maccumulate-outgoing-args \
-DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
endif
ifeq ($(ARCH),ia32)
- CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args -m32
-endif
-
-ifeq ($(ARCH),aarch64)
- CFLAGS += -ffreestanding -I$(shell $(CC) -print-file-name=include)
-endif
-
-ifeq ($(ARCH),arm)
- CFLAGS += -ffreestanding -I$(shell $(CC) -print-file-name=include)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
+ -maccumulate-outgoing-args -m32
endif
ifneq ($(origin VENDOR_CERT_FILE), undefined)
diff --git a/MokManager.c b/MokManager.c
index ee29051..0235dd8 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -1,5 +1,6 @@
#include
#include
+#include
#include
#include
#include "shim.h"
diff --git a/debian/changelog b/debian/changelog
index 134a88e..0447de8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,10 @@ shim (0.8-0ubuntu3) UNRELEASED; urgency=medium
* Fix build with GCC 5, forcing -std=gnu89 to not rely on stdint.h
required by efibind.h, and not found with -nostdinc. (LP: #1429978)
+ [ Mathieu Trudel-Lapierre ]
+ * More GCC 5 fixes: stdarg.h and other include tweaks, cherry-pick from
+ d51739a4.
+
-- Mathieu Trudel-Lapierre Tue, 12 May 2015 21:43:35 -0400
shim (0.8-0ubuntu2) wily; urgency=medium
diff --git a/debian/patches/gcc5-includes-stdarg.patch b/debian/patches/gcc5-includes-stdarg.patch
new file mode 100644
index 0000000..57cf4a8
--- /dev/null
+++ b/debian/patches/gcc5-includes-stdarg.patch
@@ -0,0 +1,129 @@
+From d51739a416400ad348d8a1c7e3886abce11fff1b Mon Sep 17 00:00:00 2001
+From: Peter Jones
+Date: Tue, 7 Apr 2015 11:59:25 -0400
+Subject: [PATCH] gcc 5.0 changes some include bits, so copy what arm does on
+ x86.
+
+Basically they messed around with stdarg some and now we need to do it
+the other way.
+
+Signed-off-by: Peter Jones
+---
+ Cryptlib/Include/OpenSslSupport.h | 4 +++-
+ Cryptlib/Makefile | 3 ++-
+ Cryptlib/OpenSSL/Makefile | 5 +++--
+ Makefile | 17 ++++++-----------
+ MokManager.c | 1 +
+ 5 files changed, 15 insertions(+), 15 deletions(-)
+
+Index: b/Cryptlib/Include/OpenSslSupport.h
+===================================================================
+--- a/Cryptlib/Include/OpenSslSupport.h
++++ b/Cryptlib/Include/OpenSslSupport.h
+@@ -34,7 +34,7 @@ typedef VOID *FILE;
+ //
+ // Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
+ //
+-#if !defined(__CC_ARM) // if va_list is not already defined
++#if !defined(__CC_ARM) || defined(_STDARG_H) // if va_list is not already defined
+ /*
+ * These are now unconditionally #defined by GNU_EFI's efistdarg.h,
+ * so we should #undef them here before providing a new definition.
+@@ -94,7 +94,9 @@ typedef __builtin_va_list VA_LIST;
+ portably, hence it is provided by a Standard C header file.
+ For pre-Standard C compilers, here is a version that usually works
+ (but watch out!): */
++#ifndef offsetof
+ #define offsetof(type, member) ( (int) & ((type*)0) -> member )
++#endif
+
+ //
+ // Basic types from EFI Application Toolkit required to buiild Open SSL
+Index: b/Cryptlib/Makefile
+===================================================================
+--- a/Cryptlib/Makefile
++++ b/Cryptlib/Makefile
+@@ -2,7 +2,8 @@
+ EFI_INCLUDES = -IInclude -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
+
+ CFLAGS = -std=gnu89 -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar \
+- -Wall $(EFI_INCLUDES)
++ -Wall $(EFI_INCLUDES) \
++ -ffreestanding -I$(shell $(CC) -print-file-name=include)
+
+ ifeq ($(ARCH),x86_64)
+ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \
+Index: b/Cryptlib/OpenSSL/Makefile
+===================================================================
+--- a/Cryptlib/OpenSSL/Makefile
++++ b/Cryptlib/OpenSSL/Makefile
+@@ -2,6 +2,7 @@
+ EFI_INCLUDES = -I../Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
+
+ CFLAGS = -std=gnu89 -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc \
++ -ffreestanding -I$(shell $(CC) -print-file-name=include) \
+ -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC
+
+ ifeq ($(ARCH),x86_64)
+@@ -13,10 +14,10 @@ ifeq ($(ARCH),ia32)
+ -m32 -DTHIRTY_TWO_BIT
+ endif
+ ifeq ($(ARCH),aarch64)
+- CFLAGS += -O2 -DSIXTY_FOUR_BIT_LONG -ffreestanding -I$(shell $(CC) -print-file-name=include)
++ CFLAGS += -O2 -DSIXTY_FOUR_BIT_LONG
+ endif
+ ifeq ($(ARCH),arm)
+- CFLAGS += -O2 -DTHIRTY_TWO_BIT -ffreestanding -I$(shell $(CC) -print-file-name=include)
++ CFLAGS += -O2 -DTHIRTY_TWO_BIT
+ endif
+ LDFLAGS = -nostdlib -znocombreloc
+
+Index: b/Makefile
+===================================================================
+--- a/Makefile
++++ b/Makefile
+@@ -21,7 +21,8 @@ EFI_LDS = elf_$(ARCH)_efi.lds
+ DEFAULT_LOADER := \\\\grubx64.efi
+ CFLAGS = -std=gnu89 -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
+ -fshort-wchar -Wall -Wsign-compare -Werror -fno-builtin \
+- -Werror=sign-compare \
++ -Werror=sign-compare -ffreestanding \
++ -I$(shell $(CC) -print-file-name=include) \
+ "-DDEFAULT_LOADER=L\"$(DEFAULT_LOADER)\"" \
+ "-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \
+ $(EFI_INCLUDES)
+@@ -31,19 +32,13 @@ ifneq ($(origin OVERRIDE_SECURITY_POLICY
+ endif
+
+ ifeq ($(ARCH),x86_64)
+- CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args \
++ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
++ -maccumulate-outgoing-args \
+ -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI
+ endif
+ ifeq ($(ARCH),ia32)
+- CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args -m32
+-endif
+-
+-ifeq ($(ARCH),aarch64)
+- CFLAGS += -ffreestanding -I$(shell $(CC) -print-file-name=include)
+-endif
+-
+-ifeq ($(ARCH),arm)
+- CFLAGS += -ffreestanding -I$(shell $(CC) -print-file-name=include)
++ CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
++ -maccumulate-outgoing-args -m32
+ endif
+
+ ifneq ($(origin VENDOR_CERT_FILE), undefined)
+Index: b/MokManager.c
+===================================================================
+--- a/MokManager.c
++++ b/MokManager.c
+@@ -1,5 +1,6 @@
+ #include
+ #include
++#include
+ #include
+ #include
+ #include "shim.h"
diff --git a/debian/patches/series b/debian/patches/series
index bf02a35..93f1acf 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,4 @@ prototypes
second-stage-path
sbsigntool-not-pesign
gcc-5.diff
+gcc5-includes-stdarg.patch