--- /dev/null
+Below file was part of the efitools package by James Bottomley, from which
+most of the source files in this directory were taken. The mok.c and mok.h
+files, however, are based on Matthew J. Garrett's shim program; see the
+copyright notices in those files for details....
+
+------------------------------------------------------------------------
+
+efitools - useful tools for manipulating UEFI secure boot platforms
+
+(c) 2012 James Bottomley
+
+All of these programs are made available under version 2 of the GNU General
+Public Licence.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+#
+# mok/Make.tiano
+# Build control file for Secure Boot components of rEFInd, using TianoCore EDK2
+#
+
+include ../Make.tiano
+
+SOURCE_NAMES = guid mok security_policy simple_file
+OBJS = $(SOURCE_NAMES:=.obj)
+
+all: $(AR_TARGET)
+
+$(AR_TARGET): $(OBJS)
+ $(AR) -cr $(AR_TARGET).lib $(OBJS)
+
+clean:
+ make clean
--- /dev/null
+#
+# mok/Makefile
+# Build control file for the libeg library
+#
+
+SRCDIR = .
+
+VPATH = $(SRCDIR)
+
+LOCAL_CPPFLAGS = -I$(SRCDIR) -I$(SRCDIR)/../include
+
+OBJS = guid.o mok.o security_policy.o simple_file.o
+TARGET = libmok.a
+
+all: $(TARGET)
+
+include $(SRCDIR)/../Make.common
+
+# EOF
--- /dev/null
+EFI_INPUT_KEY
+console_get_keystroke(void);
+void
+console_print_box_at(CHAR16 *str_arr[], int highlight, int start_col, int start_row, int size_cols, int size_rows, int offset, int lines);
+void
+console_print_box(CHAR16 *str_arr[], int highlight);
+int
+console_yes_no(CHAR16 *str_arr[]);
+int
+console_select(CHAR16 *title[], CHAR16* selectors[], int start);
+void
+console_errorbox(CHAR16 *err);
+void
+console_error(CHAR16 *err, EFI_STATUS);
+void
+console_alertbox(CHAR16 **title);
--- /dev/null
+#ifndef _INC_EFIAUTHENTICATED_H
+#define _INC_EFIAUTHENTICATED_H
+//#include "wincert.h"
+#include "../include/PeImage.h"
+//***********************************************************************
+// Signature Database
+//***********************************************************************
+///
+/// The format of a signature database.
+///
+#pragma pack(1)
+
+typedef struct {
+ ///
+ /// An identifier which identifies the agent which added the signature to the list.
+ ///
+ EFI_GUID SignatureOwner;
+ ///
+ /// The format of the signature is defined by the SignatureType.
+ ///
+ UINT8 SignatureData[1];
+} EFI_SIGNATURE_DATA;
+
+typedef struct {
+ ///
+ /// Type of the signature. GUID signature types are defined in below.
+ ///
+ EFI_GUID SignatureType;
+ ///
+ /// Total size of the signature list, including this header.
+ ///
+ UINT32 SignatureListSize;
+ ///
+ /// Size of the signature header which precedes the array of signatures.
+ ///
+ UINT32 SignatureHeaderSize;
+ ///
+ /// Size of each signature.
+ ///
+ UINT32 SignatureSize;
+ ///
+ /// Header before the array of signatures. The format of this header is specified
+ /// by the SignatureType.
+ /// UINT8 SignatureHeader[SignatureHeaderSize];
+ ///
+ /// An array of signatures. Each signature is SignatureSize bytes in length.
+ /// EFI_SIGNATURE_DATA Signatures[][SignatureSize];
+ ///
+} EFI_SIGNATURE_LIST;
+
+#pragma pack()
+
+//
+// _WIN_CERTIFICATE.wCertificateType
+//
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
+#define WIN_CERT_TYPE_EFI_PKCS115 0x0EF0
+#define WIN_CERT_TYPE_EFI_GUID 0x0EF1
+
+#define EFI_CERT_X509_GUID \
+ (EFI_GUID){ \
+ 0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72} \
+ }
+
+#define EFI_CERT_RSA2048_GUID \
+ (EFI_GUID){ \
+ 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6} \
+ }
+
+
+#define EFI_CERT_TYPE_PKCS7_GUID \
+ (EFI_GUID){ \
+ 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
+ }
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertType
+///
+#define EFI_CERT_TYPE_RSA2048_SHA256_GUID \
+ {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf } }
+
+#ifdef __MAKEWITH_GNUEFI
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertData
+///
+typedef struct {
+ EFI_GUID HashType;
+ UINT8 PublicKey[256];
+ UINT8 Signature[256];
+} EFI_CERT_BLOCK_RSA_2048_SHA256;
+
+
+///
+/// Certificate which encapsulates a GUID-specific digital signature
+///
+typedef struct {
+ ///
+ /// This is the standard WIN_CERTIFICATE header, where
+ /// wCertificateType is set to WIN_CERT_TYPE_UEFI_GUID.
+ ///
+ WIN_CERTIFICATE Hdr;
+ ///
+ /// This is the unique id which determines the
+ /// format of the CertData. .
+ ///
+ EFI_GUID CertType;
+ ///
+ /// The following is the certificate data. The format of
+ /// the data is determined by the CertType.
+ /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
+ /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
+ ///
+ UINT8 CertData[1];
+} WIN_CERTIFICATE_UEFI_GUID;
+
+
+///
+/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
+///
+/// The WIN_CERTIFICATE_UEFI_PKCS1_15 structure is derived from
+/// WIN_CERTIFICATE and encapsulate the information needed to
+/// implement the RSASSA-PKCS1-v1_5 digital signature algorithm as
+/// specified in RFC2437.
+///
+typedef struct {
+ ///
+ /// This is the standard WIN_CERTIFICATE header, where
+ /// wCertificateType is set to WIN_CERT_TYPE_UEFI_PKCS1_15.
+ ///
+ WIN_CERTIFICATE Hdr;
+ ///
+ /// This is the hashing algorithm which was performed on the
+ /// UEFI executable when creating the digital signature.
+ ///
+ EFI_GUID HashAlgorithm;
+ ///
+ /// The following is the actual digital signature. The
+ /// size of the signature is the same size as the key
+ /// (1024-bit key is 128 bytes) and can be determined by
+ /// subtracting the length of the other parts of this header
+ /// from the total length of the certificate as found in
+ /// Hdr.dwLength.
+ ///
+ /// UINT8 Signature[];
+ ///
+} WIN_CERTIFICATE_EFI_PKCS1_15;
+
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+
+#endif
+
+///
+/// Attributes of Authenticated Variable
+///
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+
+#ifdef __MAKEWITH_GNUEFI
+
+///
+/// AuthInfo is a WIN_CERTIFICATE using the wCertificateType
+/// WIN_CERTIFICATE_UEFI_GUID and the CertType
+/// EFI_CERT_TYPE_RSA2048_SHA256_GUID. If the attribute specifies
+/// authenticated access, then the Data buffer should begin with an
+/// authentication descriptor prior to the data payload and DataSize
+/// should reflect the the data.and descriptor size. The caller
+/// shall digest the Monotonic Count value and the associated data
+/// for the variable update using the SHA-256 1-way hash algorithm.
+/// The ensuing the 32-byte digest will be signed using the private
+/// key associated w/ the public/private 2048-bit RSA key-pair. The
+/// WIN_CERTIFICATE shall be used to describe the signature of the
+/// Variable data *Data. In addition, the signature will also
+/// include the MonotonicCount value to guard against replay attacks.
+///
+typedef struct {
+ ///
+ /// Included in the signature of
+ /// AuthInfo.Used to ensure freshness/no
+ /// replay. Incremented during each
+ /// "Write" access.
+ ///
+ UINT64 MonotonicCount;
+ ///
+ /// Provides the authorization for the variable
+ /// access. It is a signature across the
+ /// variable data and the Monotonic Count
+ /// value. Caller uses Private key that is
+ /// associated with a public key that has been
+ /// provisioned via the key exchange.
+ ///
+ WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION;
+
+///
+/// When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is
+/// set, then the Data buffer shall begin with an instance of a complete (and serialized)
+/// EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new
+/// variable value and DataSize shall reflect the combined size of the descriptor and the new
+/// variable value. The authentication descriptor is not part of the variable data and is not
+/// returned by subsequent calls to GetVariable().
+///
+typedef struct {
+ ///
+ /// For the TimeStamp value, components Pad1, Nanosecond, TimeZone, Daylight and
+ /// Pad2 shall be set to 0. This means that the time shall always be expressed in GMT.
+ ///
+ EFI_TIME TimeStamp;
+ ///
+ /// Only a CertType of EFI_CERT_TYPE_PKCS7_GUID is accepted.
+ ///
+ WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+ } EFI_VARIABLE_AUTHENTICATION_2;
+
+#endif
+
+///
+/// Size of AuthInfo prior to the data payload.
+///
+#define AUTHINFO_SIZE ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION, AuthInfo)) + \
+ (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) + \
+ sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256))
+
+#define AUTHINFO2_SIZE(VarAuth2) ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \
+ (UINTN) ((EFI_VARIABLE_AUTHENTICATION_2 *) (VarAuth2))->AuthInfo.Hdr.dwLength)
+
+#define OFFSET_OF_AUTHINFO2_CERT_DATA ((OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo)) + \
+ (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)))
+
+#endif
--- /dev/null
+EFI_STATUS
+generate_path(CHAR16* name, EFI_LOADED_IMAGE *li,
+ EFI_DEVICE_PATH **path, CHAR16 **PathName);
+EFI_STATUS
+execute(EFI_HANDLE image, CHAR16 *name);
--- /dev/null
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ */
+
+#include "global.h"
+#include "guid.h"
+#include <stdio.h>
+
+// #ifndef BUILD_EFI
+// /* EFI has %g for this, so it's only needed in platform c */
+// const char *guid_to_str(EFI_GUID *guid)
+// {
+// static char str[256];
+//
+// sprintf(str, "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
+// guid->Data1, guid->Data2, guid->Data3,
+// guid->Data4[0], guid->Data4[1], guid->Data4[2],
+// guid->Data4[3], guid->Data4[4], guid->Data4[5],
+// guid->Data4[6], guid->Data4[7]);
+//
+// return str;
+// }
+//
+// void str_to_guid(const char *str, EFI_GUID *guid)
+// {
+// sscanf(str, "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
+// &guid->Data1, &guid->Data2, &guid->Data3,
+// guid->Data4, guid->Data4 + 1, guid->Data4 + 2,
+// guid->Data4 + 3, guid->Data4 + 4, guid->Data4 + 5,
+// guid->Data4 + 6, guid->Data4 + 7);
+// }
+// #endif
+
+/* all the necessary guids */
+EFI_GUID GV_GUID = EFI_GLOBAL_VARIABLE;
+EFI_GUID SIG_DB = { 0xd719b2cb, 0x3d3a, 0x4596, {0xa3, 0xbc, 0xda, 0xd0, 0xe, 0x67, 0x65, 0x6f }};
+
+EFI_GUID X509_GUID = { 0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72} };
+EFI_GUID RSA2048_GUID = { 0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6} };
+EFI_GUID PKCS7_GUID = { 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} };
+EFI_GUID IMAGE_PROTOCOL = LOADED_IMAGE_PROTOCOL;
+EFI_GUID SIMPLE_FS_PROTOCOL = SIMPLE_FILE_SYSTEM_PROTOCOL;
+EFI_GUID EFI_CERT_SHA256_GUID = { 0xc1c41626, 0x504c, 0x4092, { 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 } };
+EFI_GUID MOK_OWNER = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+EFI_GUID SECURITY_PROTOCOL_GUID = { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } };
+EFI_GUID SECURITY2_PROTOCOL_GUID = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
--- /dev/null
+//#include <efi.h>
+
+// #ifndef BUILD_EFI
+// const char *guid_to_str(EFI_GUID *guid);
+// void str_to_guid(const char *str, EFI_GUID *guid);
+// #endif
+
+extern EFI_GUID GV_GUID;
+extern EFI_GUID SIG_DB;
+extern EFI_GUID X509_GUID;
+extern EFI_GUID RSA2048_GUID;
+extern EFI_GUID PKCS7_GUID;
+extern EFI_GUID IMAGE_PROTOCOL;
+extern EFI_GUID SIMPLE_FS_PROTOCOL;
+extern EFI_GUID EFI_CERT_SHA256_GUID;
+extern EFI_GUID MOK_OWNER;
+extern EFI_GUID SECURITY_PROTOCOL_GUID;
+extern EFI_GUID SECURITY2_PROTOCOL_GUID;
--- /dev/null
+/* mok/mok.c
+ *
+ * Based mostly on shim.c by Matthew J. Garrett/Red Hat (see below
+ * copyright notice).
+ *
+ * Code to perform Secure Boot verification of boot loader programs
+ * using the Shim program and its Machine Owner Keys (MOKs), to
+ * supplement standard Secure Boot checks performed by the firmware.
+ *
+ */
+
+/*
+ * shim - trivial UEFI first-stage bootloader
+ *
+ * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Tianocore
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
+ * Corporation.
+ */
+
+#include "global.h"
+#include "mok.h"
+#include "../include/refit_call_wrapper.h"
+
+static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes, UINTN *size, VOID **buffer)
+{
+ EFI_STATUS efi_status;
+ char allocate = !(*size);
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, buffer);
+
+ if (efi_status != EFI_BUFFER_TOO_SMALL || !allocate) {
+ return efi_status;
+ }
+
+ *buffer = AllocatePool(*size);
+
+ if (!*buffer) {
+ Print(L"Unable to allocate variable buffer\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, *buffer);
+
+ return efi_status;
+} // get_variable()
+
+/*
+ * Check whether we're in Secure Boot and user mode
+ */
+BOOLEAN secure_mode (VOID)
+{
+ EFI_STATUS status;
+ EFI_GUID global_var = EFI_GLOBAL_VARIABLE;
+ UINTN charsize = sizeof(char);
+ UINT8 sb, setupmode;
+ UINT32 attributes;
+
+ status = get_variable(L"SecureBoot", global_var, &attributes, &charsize, (VOID *)&sb);
+
+ /* FIXME - more paranoia here? */
+ if (status != EFI_SUCCESS || sb != 1) {
+ return FALSE;
+ }
+
+ status = get_variable(L"SetupMode", global_var, &attributes, &charsize, (VOID *)&setupmode);
+
+ if (status == EFI_SUCCESS && setupmode == 1) {
+ return FALSE;
+ }
+
+ return TRUE;
+} // secure_mode()
+
+// Returns TRUE if the shim program is available to verify binaries,
+// FALSE if not
+BOOLEAN ShimLoaded(void) {
+ SHIM_LOCK *shim_lock;
+ EFI_GUID ShimLockGuid = SHIM_LOCK_GUID;
+
+ return (refit_call3_wrapper(BS->LocateProtocol, &ShimLockGuid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS);
+} // ShimLoaded()
+
+// The following is based on the grub_linuxefi_secure_validate() function in Fedora's
+// version of GRUB 2.
+// Returns TRUE if the specified data is validated by Shim's MOK, FALSE otherwise
+BOOLEAN ShimValidate (VOID *data, UINT32 size)
+{
+ SHIM_LOCK *shim_lock;
+ EFI_GUID ShimLockGuid = SHIM_LOCK_GUID;
+
+ if (refit_call3_wrapper(BS->LocateProtocol, &ShimLockGuid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS) {
+ if (!shim_lock)
+ return FALSE;
+
+ if (shim_lock->shim_verify(data, size) == EFI_SUCCESS)
+ return TRUE;
+ }
+
+ return FALSE;
+} // BOOLEAN ShimValidate()
typedef struct _SHIM_LOCK
{
EFI_STATUS (*shim_verify) (VOID *buffer, UINT32 size);
- EFI_STATUS (*generate_hash) (char *data, int datasize,
- GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context, UINT8 *sha256hash,
- UINT8 *sha1hash);
- EFI_STATUS (*read_header) (void *data, unsigned int datasize,
- GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context);
+ EFI_STATUS (*generate_hash) (char *data, int datasize, GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ UINT8 *sha256hash, UINT8 *sha1hash);
+ EFI_STATUS (*read_header) (void *data, unsigned int datasize, GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context);
} SHIM_LOCK;
#endif
BOOLEAN ShimLoaded(void);
+BOOLEAN ShimValidate (VOID *data, UINT32 size);
BOOLEAN secure_mode (VOID);
-EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath, VOID *data, UINTN datasize,
- CHAR16 *Options, REFIT_VOLUME *DeviceVolume, IN EFI_DEVICE_PATH *DevicePath);
--- /dev/null
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ *
+ * Install and remove a platform security2 override policy
+ */
+
+// #include <efi.h>
+// #include <efilib.h>
+#include <global.h>
+
+#include "guid.h"
+//#include "sha256.h"
+//#include "variables.h"
+#include "simple_file.h"
+//#include "errors.h"
+#include "../include/refit_call_wrapper.h"
+#include "mok.h"
+
+#include <security_policy.h>
+
+/*
+ * See the UEFI Platform Initialization manual (Vol2: DXE) for this
+ */
+struct _EFI_SECURITY2_PROTOCOL;
+struct _EFI_SECURITY_PROTOCOL;
+struct _EFI_DEVICE_PATH_PROTOCOL;
+typedef struct _EFI_SECURITY2_PROTOCOL EFI_SECURITY2_PROTOCOL;
+typedef struct _EFI_SECURITY_PROTOCOL EFI_SECURITY_PROTOCOL;
+#ifdef __MAKEWITH_GNUEFI
+typedef struct _EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL;
+#endif
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE) (
+ const EFI_SECURITY_PROTOCOL *This,
+ UINT32 AuthenticationStatus,
+ const EFI_DEVICE_PATH_PROTOCOL *File
+ );
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION) (
+ const EFI_SECURITY2_PROTOCOL *This,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ VOID *FileBuffer,
+ UINTN FileSize,
+ BOOLEAN BootPolicy
+ );
+
+struct _EFI_SECURITY2_PROTOCOL {
+ EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
+};
+
+struct _EFI_SECURITY_PROTOCOL {
+ EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState;
+};
+
+
+static UINT8 *security_policy_esl = NULL;
+static UINTN security_policy_esl_len;
+
+static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
+static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
+
+#ifdef __MAKEWITH_GNUEFI
+static EFI_STATUS thunk_security_policy_authentication(
+ const EFI_SECURITY_PROTOCOL *This,
+ UINT32 AuthenticationStatus,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+__attribute__((unused));
+
+static EFI_STATUS thunk_security2_policy_authentication(
+ const EFI_SECURITY2_PROTOCOL *This,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ VOID *FileBuffer,
+ UINTN FileSize,
+ BOOLEAN BootPolicy
+ )
+__attribute__((unused));
+#endif
+
+#ifdef __MAKEWITH_GNUEFI
+static __attribute__((used)) EFI_STATUS
+#else
+static __attribute__((ms_abi)) EFI_STATUS
+#endif
+security2_policy_authentication (
+ const EFI_SECURITY2_PROTOCOL *This,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ VOID *FileBuffer,
+ UINTN FileSize,
+ BOOLEAN BootPolicy
+ )
+{
+ EFI_STATUS status;
+
+ /* Chain original security policy */
+ status = uefi_call_wrapper(es2fa, 5, This, DevicePath, FileBuffer, FileSize, BootPolicy);
+
+ /* if OK, don't bother with MOK check */
+ if (status == EFI_SUCCESS)
+ return status;
+
+ if (ShimValidate(FileBuffer, FileSize)) {
+ status = EFI_SUCCESS;
+ } else {
+ status = EFI_ACCESS_DENIED;
+ }
+
+// status = security_policy_check_mok(FileBuffer, FileSize);
+
+ return status;
+}
+
+#ifdef __MAKEWITH_GNUEFI
+static __attribute__((used)) EFI_STATUS
+#else
+static __attribute__((ms_abi)) EFI_STATUS
+#endif
+security_policy_authentication (
+ const EFI_SECURITY_PROTOCOL *This,
+ UINT32 AuthenticationStatus,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst
+ )
+{
+ EFI_STATUS status;
+ EFI_DEVICE_PATH *DevPath
+ = DuplicateDevicePath((EFI_DEVICE_PATH *)DevicePathConst),
+ *OrigDevPath = DevPath;
+ EFI_HANDLE h;
+ EFI_FILE *f;
+ VOID *FileBuffer;
+ UINTN FileSize;
+ CHAR16* DevPathStr;
+
+ /* Chain original security policy */
+ status = refit_call3_wrapper(esfas, This, AuthenticationStatus, DevicePathConst);
+
+ /* if OK avoid checking MOK: It's a bit expensive to
+ * read the whole file in again (esfas already did this) */
+ if (status == EFI_SUCCESS)
+ goto out;
+
+ status = refit_call3_wrapper(BS->LocateDevicePath, &SIMPLE_FS_PROTOCOL, &DevPath, &h);
+ if (status != EFI_SUCCESS)
+ goto out;
+
+ DevPathStr = DevicePathToStr(DevPath);
+
+ status = simple_file_open_by_handle(h, DevPathStr, &f, EFI_FILE_MODE_READ);
+ FreePool(DevPathStr);
+ if (status != EFI_SUCCESS)
+ goto out;
+
+ status = simple_file_read_all(f, &FileSize, &FileBuffer);
+ simple_file_close(f);
+ if (status != EFI_SUCCESS)
+ goto out;
+
+ if (ShimValidate(FileBuffer, FileSize)) {
+ status = EFI_SUCCESS;
+ } else {
+ status = EFI_ACCESS_DENIED;
+ }
+ FreePool(FileBuffer);
+
+ out:
+ FreePool(OrigDevPath);
+ return status;
+}
+
+#ifdef __MAKEWITH_GNUEFI
+/* Nasty: ELF and EFI have different calling conventions. Here is the map for
+ * calling ELF -> EFI
+ *
+ * 1) rdi -> rcx (32 saved)
+ * 2) rsi -> rdx (32 saved)
+ * 3) rdx -> r8 ( 32 saved)
+ * 4) rcx -> r9 (32 saved)
+ * 5) r8 -> 32(%rsp) (48 saved)
+ * 6) r9 -> 40(%rsp) (48 saved)
+ * 7) pad+0(%rsp) -> 48(%rsp) (64 saved)
+ * 8) pad+8(%rsp) -> 56(%rsp) (64 saved)
+ * 9) pad+16(%rsp) -> 64(%rsp) (80 saved)
+ * 10) pad+24(%rsp) -> 72(%rsp) (80 saved)
+ * 11) pad+32(%rsp) -> 80(%rsp) (96 saved)
+
+ *
+ * So for a five argument callback, the map is ignore the first two arguments
+ * and then map (EFI -> ELF) assuming pad = 0.
+ *
+ * ARG4 -> ARG1
+ * ARG3 -> ARG2
+ * ARG5 -> ARG3
+ * ARG6 -> ARG4
+ * ARG11 -> ARG5
+ *
+ * Calling conventions also differ over volatile and preserved registers in
+ * MS: RBX, RBP, RDI, RSI, R12, R13, R14, and R15 are considered nonvolatile .
+ * In ELF: Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling
+ * function and the called function is required to preserve their values.
+ *
+ * This means when accepting a function callback from MS -> ELF, we have to do
+ * separate preservation on %rdi, %rsi before swizzling the arguments and
+ * handing off to the ELF function.
+ */
+
+asm (
+".type security2_policy_authentication,@function\n"
+"thunk_security2_policy_authentication:\n\t"
+ "mov 0x28(%rsp), %r10 # ARG5\n\t"
+ "push %rdi\n\t"
+ "push %rsi\n\t"
+ "mov %r10, %rdi\n\t"
+ "subq $8, %rsp # space for storing stack pad\n\t"
+ "mov $0x08, %rax\n\t"
+ "mov $0x10, %r10\n\t"
+ "and %rsp, %rax\n\t"
+ "cmovnz %rax, %r11\n\t"
+ "cmovz %r10, %r11\n\t"
+ "subq %r11, %rsp\n\t"
+ "addq $8, %r11\n\t"
+ "mov %r11, (%rsp)\n\t"
+"# five argument swizzle\n\t"
+ "mov %rdi, %r10\n\t"
+ "mov %rcx, %rdi\n\t"
+ "mov %rdx, %rsi\n\t"
+ "mov %r8, %rdx\n\t"
+ "mov %r9, %rcx\n\t"
+ "mov %r10, %r8\n\t"
+ "callq security2_policy_authentication@PLT\n\t"
+ "mov (%rsp), %r11\n\t"
+ "addq %r11, %rsp\n\t"
+ "pop %rsi\n\t"
+ "pop %rdi\n\t"
+ "ret\n"
+);
+
+asm (
+".type security_policy_authentication,@function\n"
+"thunk_security_policy_authentication:\n\t"
+ "push %rdi\n\t"
+ "push %rsi\n\t"
+ "subq $8, %rsp # space for storing stack pad\n\t"
+ "mov $0x08, %rax\n\t"
+ "mov $0x10, %r10\n\t"
+ "and %rsp, %rax\n\t"
+ "cmovnz %rax, %r11\n\t"
+ "cmovz %r10, %r11\n\t"
+ "subq %r11, %rsp\n\t"
+ "addq $8, %r11\n\t"
+ "mov %r11, (%rsp)\n\t"
+"# three argument swizzle\n\t"
+ "mov %rcx, %rdi\n\t"
+ "mov %rdx, %rsi\n\t"
+ "mov %r8, %rdx\n\t"
+ "callq security_policy_authentication@PLT\n\t"
+ "mov (%rsp), %r11\n\t"
+ "addq %r11, %rsp\n\t"
+ "pop %rsi\n\t"
+ "pop %rdi\n\t"
+ "ret\n"
+);
+#endif
+
+EFI_STATUS
+security_policy_install(void)
+{
+ EFI_SECURITY_PROTOCOL *security_protocol;
+ EFI_SECURITY2_PROTOCOL *security2_protocol = NULL;
+ EFI_STATUS status;
+
+ if (esfas) {
+ /* Already Installed */
+ return EFI_ALREADY_STARTED;
+ }
+
+ /* Don't bother with status here. The call is allowed
+ * to fail, since SECURITY2 was introduced in PI 1.2.1
+ * If it fails, use security2_protocol == NULL as indicator */
+ uefi_call_wrapper(BS->LocateProtocol, 3, &SECURITY2_PROTOCOL_GUID, NULL, (VOID**) &security2_protocol);
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, &SECURITY_PROTOCOL_GUID, NULL, (VOID**) &security_protocol);
+ if (status != EFI_SUCCESS)
+ /* This one is mandatory, so there's a serious problem */
+ return status;
+
+ if (security2_protocol) {
+ es2fa = security2_protocol->FileAuthentication;
+#ifdef __MAKEWITH_GNUEFI
+ security2_protocol->FileAuthentication = thunk_security2_policy_authentication;
+#else
+ security2_protocol->FileAuthentication = security2_policy_authentication;
+#endif
+ }
+
+ esfas = security_protocol->FileAuthenticationState;
+#ifdef __MAKEWITH_GNUEFI
+ security_protocol->FileAuthenticationState = thunk_security_policy_authentication;
+#else
+ security_protocol->FileAuthenticationState = security_policy_authentication;
+#endif
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+security_policy_uninstall(void)
+{
+ EFI_STATUS status;
+
+ if (esfas) {
+ EFI_SECURITY_PROTOCOL *security_protocol;
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3,
+ &SECURITY_PROTOCOL_GUID, NULL,
+ (VOID**) &security_protocol);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ security_protocol->FileAuthenticationState = esfas;
+ esfas = NULL;
+ } else {
+ /* nothing installed */
+ return EFI_NOT_STARTED;
+ }
+
+ if (es2fa) {
+ EFI_SECURITY2_PROTOCOL *security2_protocol;
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3,
+ &SECURITY2_PROTOCOL_GUID, NULL,
+ (VOID**) &security2_protocol);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ security2_protocol->FileAuthentication = es2fa;
+ es2fa = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+void
+security_protocol_set_hashes(unsigned char *esl, int len)
+{
+ security_policy_esl = esl;
+ security_policy_esl_len = len;
+}
--- /dev/null
+EFI_STATUS
+security_policy_install(void);
+EFI_STATUS
+security_policy_uninstall(void);
+void
+security_protocol_set_hashes(unsigned char *esl, int len);
--- /dev/null
+/*
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ *
+ * see COPYING file
+ */
+
+#include <global.h>
+#include "../include/refit_call_wrapper.h"
+
+#include "console.h"
+#include "simple_file.h"
+//#include "efiauthenticated.h"
+#include "execute.h" /* for generate_path() */
+
+static EFI_GUID IMAGE_PROTOCOL = LOADED_IMAGE_PROTOCOL;
+static EFI_GUID SIMPLE_FS_PROTOCOL = SIMPLE_FILE_SYSTEM_PROTOCOL;
+static EFI_GUID FILE_INFO = EFI_FILE_INFO_ID;
+
+EFI_STATUS
+simple_file_open_by_handle(EFI_HANDLE device, CHAR16 *name, EFI_FILE **file, UINT64 mode)
+{
+ EFI_STATUS efi_status;
+ EFI_FILE_IO_INTERFACE *drive;
+ EFI_FILE *root;
+
+ efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
+ &SIMPLE_FS_PROTOCOL, (VOID**) &drive);
+
+ if (efi_status != EFI_SUCCESS) {
+ Print(L"Unable to find simple file protocol\n");
+ goto error;
+ }
+
+ efi_status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
+
+ if (efi_status != EFI_SUCCESS) {
+ Print(L"Failed to open drive volume\n");
+ goto error;
+ }
+
+ efi_status = uefi_call_wrapper(root->Open, 5, root, file, name,
+ mode, 0);
+
+ error:
+ return efi_status;
+}
+
+EFI_STATUS
+simple_file_open(EFI_HANDLE image, CHAR16 *name, EFI_FILE **file, UINT64 mode)
+{
+ EFI_STATUS efi_status;
+ EFI_HANDLE device;
+ EFI_LOADED_IMAGE *li;
+ EFI_DEVICE_PATH *loadpath = NULL;
+ CHAR16 *PathName = NULL;
+
+ efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
+ &IMAGE_PROTOCOL, (VOID**) &li);
+
+ if (efi_status != EFI_SUCCESS)
+ return simple_file_open_by_handle(image, name, file, mode);
+
+ efi_status = generate_path(name, li, &loadpath, &PathName);
+
+ if (efi_status != EFI_SUCCESS) {
+ Print(L"Unable to generate load path for %s\n", name);
+ return efi_status;
+ }
+
+ device = li->DeviceHandle;
+
+ efi_status = simple_file_open_by_handle(device, PathName, file, mode);
+
+ FreePool(PathName);
+ FreePool(loadpath);
+
+ return efi_status;
+}
+
+EFI_STATUS
+simple_file_read_all(EFI_FILE *file, UINTN *size, void **buffer)
+{
+ EFI_STATUS efi_status;
+ EFI_FILE_INFO *fi;
+ char buf[1024];
+
+ *size = sizeof(buf);
+ fi = (void *)buf;
+
+
+ efi_status = uefi_call_wrapper(file->GetInfo, 4, file, &FILE_INFO,
+ size, fi);
+ if (efi_status != EFI_SUCCESS) {
+ Print(L"Failed to get file info\n");
+ return efi_status;
+ }
+
+ *size = fi->FileSize;
+
+ *buffer = AllocatePool(*size);
+ if (!*buffer) {
+ Print(L"Failed to allocate buffer of size %d\n", *size);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ efi_status = uefi_call_wrapper(file->Read, 3, file, size, *buffer);
+
+ return efi_status;
+}
+
+void
+simple_file_close(EFI_FILE *file)
+{
+ uefi_call_wrapper(file->Close, 1, file);
+}
--- /dev/null
+EFI_STATUS
+simple_file_open (EFI_HANDLE image, CHAR16 *name, EFI_FILE **file, UINT64 mode);
+EFI_STATUS
+simple_file_open_by_handle(EFI_HANDLE device, CHAR16 *name, EFI_FILE **file, UINT64 mode);
+EFI_STATUS
+simple_file_read_all(EFI_FILE *file, UINTN *size, void **buffer);
+void
+simple_file_close(EFI_FILE *file);
+
+++ /dev/null
-/* refind/mok.c
- *
- * Based mostly on shim.c by Matthew J. Garrett/Red Hat (see below
- * copyright notice).
- *
- * Code to perform Secure Boot verification of boot loader programs
- * using the Shim program and its Machine Owner Keys (MOKs), to
- * supplement standard Secure Boot checks performed by the firmware.
- *
- */
-
-/*
- * shim - trivial UEFI first-stage bootloader
- *
- * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Significant portions of this code are derived from Tianocore
- * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
- * Corporation.
- */
-
-#include "global.h"
-#include "mok.h"
-#include "lib.h"
-#include "config.h"
-#include "screen.h"
-#include "../include/refit_call_wrapper.h"
-#include "../include/PeImage.h"
-
-#define SECOND_STAGE L"\\refind.efi"
-#define MOK_MANAGER L"\\MokManager.efi"
-
-static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
-
-// /*
-// * The vendor certificate used for validating the second stage loader
-// */
-// extern UINT8 vendor_cert[];
-// extern UINT32 vendor_cert_size;
-// extern UINT32 vendor_dbx_size;
-
-#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
-
-//static UINT8 insecure_mode;
-
-typedef enum {
- DATA_FOUND,
- DATA_NOT_FOUND,
- VAR_NOT_FOUND
-} CHECK_STATUS;
-
-typedef struct {
- UINT32 MokSize;
- UINT8 *Mok;
-} MokListNode;
-
-
-static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes, UINTN *size, VOID **buffer)
-{
- EFI_STATUS efi_status;
- char allocate = !(*size);
-
- efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, buffer);
-
- if (efi_status != EFI_BUFFER_TOO_SMALL || !allocate) {
- return efi_status;
- }
-
- *buffer = AllocatePool(*size);
-
- if (!*buffer) {
- Print(L"Unable to allocate variable buffer\n");
- return EFI_OUT_OF_RESOURCES;
- }
-
- efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, attributes, size, *buffer);
-
- return efi_status;
-} // get_variable()
-
-/*
- * Check whether we're in Secure Boot and user mode
- */
-BOOLEAN secure_mode (VOID)
-{
- EFI_STATUS status;
- EFI_GUID global_var = EFI_GLOBAL_VARIABLE;
- UINTN charsize = sizeof(char);
- UINT8 sb, setupmode;
- UINT32 attributes;
-
- status = get_variable(L"SecureBoot", global_var, &attributes, &charsize, (VOID *)&sb);
-
- /* FIXME - more paranoia here? */
- if (status != EFI_SUCCESS || sb != 1) {
- return FALSE;
- }
-
- status = get_variable(L"SetupMode", global_var, &attributes, &charsize, (VOID *)&setupmode);
-
- if (status == EFI_SUCCESS && setupmode == 1) {
- return FALSE;
- }
-
- return TRUE;
-} // secure_mode()
-
-// Returns TRUE if the shim program is available to verify binaries,
-// FALSE if not
-BOOLEAN ShimLoaded(void) {
- SHIM_LOCK *shim_lock;
- EFI_GUID ShimLockGuid = SHIM_LOCK_GUID;
-
- return (BS->LocateProtocol(&ShimLockGuid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS);
-} // ShimLoaded()
-
-/*
- * Currently, shim/MOK only works on x86-64 (X64) systems, and some of this code
- * generates warnings on x86 (IA32) builds, so don't bother compiling it at all
- * on such systems.
- *
- */
-
-#if defined(EFIX64)
-
-/*
- * Perform basic bounds checking of the intra-image pointers
- */
-static void *ImageAddress (void *image, int size, unsigned int address)
-{
- if (address > size)
- return NULL;
-
- return image + address;
-}
-
-/*
- * Perform the actual relocation
- */
-static EFI_STATUS relocate_coff (GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context, void *data)
-{
- EFI_IMAGE_BASE_RELOCATION *RelocBase, *RelocBaseEnd;
- UINT64 Adjust;
- UINT16 *Reloc, *RelocEnd;
- char *Fixup, *FixupBase, *FixupData = NULL;
- UINT16 *Fixup16;
- UINT32 *Fixup32;
- UINT64 *Fixup64;
- int size = context->ImageSize;
- void *ImageEnd = (char *)data + size;
-
- context->PEHdr->Pe32Plus.OptionalHeader.ImageBase = (UINT64)data;
-
- // Linux kernels with EFI stub support don't have relocation information, so
- // we can skip all this stuff....
- if (((context->RelocDir->VirtualAddress == 0) && (context->RelocDir->Size == 0)) ||
- ((context->PEHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {
- return EFI_SUCCESS;
- }
-
- if (context->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
- Print(L"Image has no relocation entry\n");
- return EFI_UNSUPPORTED;
- }
-
- RelocBase = ImageAddress(data, size, context->RelocDir->VirtualAddress);
- RelocBaseEnd = ImageAddress(data, size, context->RelocDir->VirtualAddress + context->RelocDir->Size - 1);
-
- if (!RelocBase || !RelocBaseEnd) {
- Print(L"Reloc table overflows binary\n");
- return EFI_UNSUPPORTED;
- }
-
- Adjust = (UINT64)data - context->ImageAddress;
-
- while (RelocBase < RelocBaseEnd) {
- Reloc = (UINT16 *) ((char *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
- RelocEnd = (UINT16 *) ((char *) RelocBase + RelocBase->SizeOfBlock);
-
- if ((void *)RelocEnd < data || (void *)RelocEnd > ImageEnd) {
- Print(L"Reloc entry overflows binary\n");
- return EFI_UNSUPPORTED;
- }
-
- FixupBase = ImageAddress(data, size, RelocBase->VirtualAddress);
- if (!FixupBase) {
- Print(L"Invalid fixupbase\n");
- return EFI_UNSUPPORTED;
- }
-
- while (Reloc < RelocEnd) {
- Fixup = FixupBase + (*Reloc & 0xFFF);
- switch ((*Reloc) >> 12) {
- case EFI_IMAGE_REL_BASED_ABSOLUTE:
- break;
-
- case EFI_IMAGE_REL_BASED_HIGH:
- Fixup16 = (UINT16 *) Fixup;
- *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));
- if (FixupData != NULL) {
- *(UINT16 *) FixupData = *Fixup16;
- FixupData = FixupData + sizeof (UINT16);
- }
- break;
-
- case EFI_IMAGE_REL_BASED_LOW:
- Fixup16 = (UINT16 *) Fixup;
- *Fixup16 = (UINT16) (*Fixup16 + (UINT16) Adjust);
- if (FixupData != NULL) {
- *(UINT16 *) FixupData = *Fixup16;
- FixupData = FixupData + sizeof (UINT16);
- }
- break;
-
- case EFI_IMAGE_REL_BASED_HIGHLOW:
- Fixup32 = (UINT32 *) Fixup;
- *Fixup32 = *Fixup32 + (UINT32) Adjust;
- if (FixupData != NULL) {
- FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));
- *(UINT32 *)FixupData = *Fixup32;
- FixupData = FixupData + sizeof (UINT32);
- }
- break;
-
- case EFI_IMAGE_REL_BASED_DIR64:
- Fixup64 = (UINT64 *) Fixup;
- *Fixup64 = *Fixup64 + (UINT64) Adjust;
- if (FixupData != NULL) {
- FixupData = ALIGN_POINTER (FixupData, sizeof(UINT64));
- *(UINT64 *)(FixupData) = *Fixup64;
- FixupData = FixupData + sizeof(UINT64);
- }
- break;
-
- default:
- Print(L"Unknown relocation\n");
- return EFI_UNSUPPORTED;
- }
- Reloc += 1;
- }
- RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
- }
-
- return EFI_SUCCESS;
-} /* relocate_coff() */
-
-/*
- * Read the binary header and grab appropriate information from it
- */
-static EFI_STATUS read_header(void *data, unsigned int datasize,
- GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT *context)
-{
- EFI_IMAGE_DOS_HEADER *DosHdr = data;
- EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data;
-
- if (datasize < sizeof(EFI_IMAGE_DOS_HEADER)) {
- Print(L"Invalid image\n");
- return EFI_UNSUPPORTED;
- }
-
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE)
- PEHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((char *)data + DosHdr->e_lfanew);
-
- if ((((UINT8 *)PEHdr - (UINT8 *)data) + sizeof(EFI_IMAGE_OPTIONAL_HEADER_UNION)) > datasize) {
- Print(L"Invalid image\n");
- return EFI_UNSUPPORTED;
- }
-
- if (PEHdr->Te.Signature != EFI_IMAGE_NT_SIGNATURE) {
- Print(L"Unsupported image type\n");
- return EFI_UNSUPPORTED;
- }
-
- if (PEHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) {
- Print(L"Unsupported image - Relocations have been stripped\n");
- return EFI_UNSUPPORTED;
- }
-
- if (PEHdr->Pe32.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
- Print(L"Only 64-bit images supported\n");
- return EFI_UNSUPPORTED;
- }
-
- context->PEHdr = PEHdr;
- context->ImageAddress = PEHdr->Pe32Plus.OptionalHeader.ImageBase;
- context->ImageSize = (UINT64)PEHdr->Pe32Plus.OptionalHeader.SizeOfImage;
- context->SizeOfHeaders = PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
- context->EntryPoint = PEHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint;
- context->RelocDir = &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
- context->NumberOfRvaAndSizes = PEHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;
- context->NumberOfSections = PEHdr->Pe32.FileHeader.NumberOfSections;
- context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)((char *)PEHdr + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader + sizeof(UINT32) + sizeof(EFI_IMAGE_FILE_HEADER));
- context->SecDir = (EFI_IMAGE_DATA_DIRECTORY *) &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
-
- if (context->ImageSize < context->SizeOfHeaders) {
- Print(L"Invalid image\n");
- return EFI_UNSUPPORTED;
- }
-
- if (((UINT8 *)context->SecDir - (UINT8 *)data) > (datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) {
- Print(L"Invalid image\n");
- return EFI_UNSUPPORTED;
- }
-
- if (context->SecDir->VirtualAddress >= datasize) {
- Print(L"Malformed security header\n");
- return EFI_INVALID_PARAMETER;
- }
- return EFI_SUCCESS;
-}
-
-// The following is based on the grub_linuxefi_secure_validate() function in Fedora's
-// version of GRUB 2.
-// Returns TRUE if the specified data is validated by Shim's MOK, FALSE otherwise
-static BOOLEAN ShimValidate (VOID *data, UINT32 size)
-{
- SHIM_LOCK *shim_lock;
- EFI_GUID ShimLockGuid = SHIM_LOCK_GUID;
-
- if (BS->LocateProtocol(&ShimLockGuid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS) {
- if (!shim_lock)
- return FALSE;
-
- if (shim_lock->shim_verify(data, size) == EFI_SUCCESS)
- return TRUE;
- } // if
-
- return FALSE;
-} // BOOLEAN ShimValidate()
-
-/*
- * Once the image has been loaded it needs to be validated and relocated
- */
-static EFI_STATUS handle_image (void *data, unsigned int datasize, EFI_LOADED_IMAGE *li,
- CHAR16 *Options, REFIT_VOLUME *DeviceVolume, IN CHAR16 *FileName)
-{
- EFI_STATUS efi_status;
- char *buffer;
- int i, size;
- EFI_IMAGE_SECTION_HEADER *Section;
- char *base, *end;
- GNUEFI_PE_COFF_LOADER_IMAGE_CONTEXT context;
- EFI_DEVICE_PATH *DevicePath;
-
- /*
- * The binary header contains relevant context and section pointers
- */
- efi_status = read_header(data, datasize, &context);
- if (efi_status != EFI_SUCCESS) {
- Print(L"Failed to read header\n");
- return efi_status;
- }
-
- /*
- * Validate the image; if this fails, return EFI_ACCESS_DENIED
- */
- if (!ShimValidate(data, datasize)) {
- return EFI_ACCESS_DENIED;
- }
-
- buffer = AllocatePool(context.ImageSize);
-
- if (!buffer) {
- Print(L"Failed to allocate image buffer\n");
- return EFI_OUT_OF_RESOURCES;
- }
-
- CopyMem(buffer, data, context.SizeOfHeaders);
-
- /*
- * Copy the executable's sections to their desired offsets
- */
- Section = context.FirstSection;
- for (i = 0; i < context.NumberOfSections; i++) {
- size = Section->Misc.VirtualSize;
-
- if (size > Section->SizeOfRawData)
- size = Section->SizeOfRawData;
-
- base = ImageAddress (buffer, context.ImageSize, Section->VirtualAddress);
- end = ImageAddress (buffer, context.ImageSize, Section->VirtualAddress + size - 1);
-
- if (!base || !end) {
- Print(L"Invalid section size\n");
- return EFI_UNSUPPORTED;
- }
-
- if (Section->SizeOfRawData > 0)
- CopyMem(base, data + Section->PointerToRawData, size);
-
- if (size < Section->Misc.VirtualSize)
- ZeroMem (base + size, Section->Misc.VirtualSize - size);
-
- Section += 1;
- }
-
- /*
- * Run the relocation fixups
- */
- efi_status = relocate_coff(&context, buffer);
-
- if (efi_status != EFI_SUCCESS) {
- Print(L"Relocation failed\n");
- FreePool(buffer);
- return efi_status;
- }
-
- entry_point = ImageAddress(buffer, context.ImageSize, context.EntryPoint);
- /*
- * grub needs to know its location and size in memory, its location on
- * disk, and its load options, so fix up the loaded image protocol values
- */
- DevicePath = FileDevicePath(NULL, FileName);
-// DevicePath = FileDevicePath(DeviceVolume->DeviceHandle, FileName);
- li->DeviceHandle = DeviceVolume->DeviceHandle;
- li->FilePath = DevicePath;
- li->LoadOptionsSize = ((UINT32)StrLen(Options) + 1) * sizeof(CHAR16);
- li->LoadOptions = (VOID *)Options;
- li->ImageBase = buffer;
- li->ImageSize = context.ImageSize;
-
- if (!entry_point) {
- Print(L"Invalid entry point\n");
- FreePool(buffer);
- return EFI_UNSUPPORTED;
- }
-
- return EFI_SUCCESS;
-}
-
-#endif /* defined(EFIX64) */
-
-/*
- * Load and run an EFI executable.
- * Note that most of this function compiles only on x86-64 (X64) systems, since
- * shim/MOK works only on those systems. I'm leaving just enough to get the
- * function to return EFI_ACCESS_DENIED on x86 (IA32) systems, which should
- * let the calling function work in case it somehow ends up calling this
- * function inappropriately.
- */
-EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath, VOID *data, UINTN datasize,
- CHAR16 *Options, REFIT_VOLUME *DeviceVolume, IN EFI_DEVICE_PATH *DevicePath)
-{
- EFI_STATUS efi_status = EFI_ACCESS_DENIED;
-#if defined(EFIX64)
- EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL;
- EFI_LOADED_IMAGE *li, li_bak;
- CHAR16 *PathName = NULL;
-
- if (data == NULL)
- return EFI_LOAD_ERROR;
-
- /*
- * We need to refer to the loaded image protocol on the running
- * binary in order to find our path
- */
- efi_status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, &loaded_image_protocol, (void **)&li);
-
- if (efi_status != EFI_SUCCESS) {
- Print(L"Unable to init protocol\n");
- return efi_status;
- }
-
- /*
- * We need to modify the loaded image protocol entry before running
- * the new binary, so back it up
- */
- CopyMem(&li_bak, li, sizeof(li_bak));
-
- /*
- * Verify and, if appropriate, relocate and execute the executable
- */
- efi_status = handle_image(data, datasize, li, Options, DeviceVolume, ImagePath);
-
- if (efi_status != EFI_SUCCESS) {
- Print(L"Failed to load image\n");
- CopyMem(li, &li_bak, sizeof(li_bak));
- goto done;
- }
-
- /*
- * The binary is trusted and relocated. Run it
- */
- efi_status = refit_call2_wrapper(entry_point, image_handle, ST);
-
-// efi_status = refit_call1_wrapper(BS->UnloadImage, li);
-
- /*
- * Restore our original loaded image values
- */
- CopyMem(li, &li_bak, sizeof(li_bak));
-done:
- if (PathName)
- FreePool(PathName);
-
- if (data)
- FreePool(data);
-
-#endif
- return efi_status;
-} // EFI_STATUS start_image()