From c2f285a93f50edc40d6f2b8114e4f9af812398d0 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Tue, 12 May 2015 21:51:24 -0400 Subject: [PATCH] More GCC 5 fixes: stdarg.h and other include tweaks, cherry-pick from d51739a4. --- .pc/applied-patches | 1 + .pc/gcc5-includes-stdarg.patch/.timestamp | 0 .../Cryptlib/Include/OpenSslSupport.h | 269 +++ .../Cryptlib/Makefile | 45 + .../Cryptlib/OpenSSL/Makefile | 531 +++++ .pc/gcc5-includes-stdarg.patch/Makefile | 183 ++ .pc/gcc5-includes-stdarg.patch/MokManager.c | 2017 +++++++++++++++++ Cryptlib/Include/OpenSslSupport.h | 4 +- Cryptlib/Makefile | 3 +- Cryptlib/OpenSSL/Makefile | 5 +- Makefile | 17 +- MokManager.c | 1 + debian/changelog | 4 + debian/patches/gcc5-includes-stdarg.patch | 129 ++ debian/patches/series | 1 + 15 files changed, 3195 insertions(+), 15 deletions(-) create mode 100644 .pc/gcc5-includes-stdarg.patch/.timestamp create mode 100644 .pc/gcc5-includes-stdarg.patch/Cryptlib/Include/OpenSslSupport.h create mode 100644 .pc/gcc5-includes-stdarg.patch/Cryptlib/Makefile create mode 100644 .pc/gcc5-includes-stdarg.patch/Cryptlib/OpenSSL/Makefile create mode 100644 .pc/gcc5-includes-stdarg.patch/Makefile create mode 100644 .pc/gcc5-includes-stdarg.patch/MokManager.c create mode 100644 debian/patches/gcc5-includes-stdarg.patch 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