Revamp the MokManager UI OBS-URL: https://build.opensuse.org/request/show/174778 OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=26
10788 lines
352 KiB
Diff
10788 lines
352 KiB
Diff
From 0709a7fd4ab06b445ed7343c2e9f544e0040ab21 Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Tue, 16 Apr 2013 16:51:31 +0800
|
||
Subject: [PATCH 01/12] Merge efitools lib
|
||
|
||
---
|
||
Makefile | 15 +-
|
||
efitools/COPYING | 350 +++++++++++++++
|
||
efitools/Make.rules | 24 +
|
||
efitools/Makefile | 15 +
|
||
efitools/include/PeImage.h | 787 +++++++++++++++++++++++++++++++++
|
||
efitools/include/configtable.h | 68 +++
|
||
efitools/include/console.h | 21 +
|
||
efitools/include/efiauthenticated.h | 222 ++++++++++
|
||
efitools/include/errors.h | 9 +
|
||
efitools/include/execute.h | 5 +
|
||
efitools/include/guid.h | 19 +
|
||
efitools/include/kernel_efivars.h | 26 ++
|
||
efitools/include/pecoff.h | 23 +
|
||
efitools/include/security_policy.h | 6 +
|
||
efitools/include/sha256.h | 33 ++
|
||
efitools/include/shell.h | 2 +
|
||
efitools/include/simple_file.h | 21 +
|
||
efitools/include/variables.h | 45 ++
|
||
efitools/include/variables_iterators.h | 16 +
|
||
efitools/include/version.h | 8 +
|
||
efitools/include/wincert.h | 33 ++
|
||
efitools/include/x509.h | 23 +
|
||
efitools/lib/Makefile | 12 +
|
||
efitools/lib/asn1/.gitignore | 1 +
|
||
efitools/lib/asn1/Makefile | 11 +
|
||
efitools/lib/asn1/asn1.c | 197 +++++++++
|
||
efitools/lib/asn1/asn1.h | 115 +++++
|
||
efitools/lib/asn1/asn1_parser.c | 286 ++++++++++++
|
||
efitools/lib/asn1/asn1_parser.h | 117 +++++
|
||
efitools/lib/asn1/chunk.c | 83 ++++
|
||
efitools/lib/asn1/chunk.h | 164 +++++++
|
||
efitools/lib/asn1/enumerator.c | 37 ++
|
||
efitools/lib/asn1/enumerator.h | 55 +++
|
||
efitools/lib/asn1/identification.c | 226 ++++++++++
|
||
efitools/lib/asn1/identification.h | 285 ++++++++++++
|
||
efitools/lib/asn1/oid.c | 390 ++++++++++++++++
|
||
efitools/lib/asn1/oid.h | 224 ++++++++++
|
||
efitools/lib/asn1/oid.pl | 134 ++++++
|
||
efitools/lib/asn1/oid.txt | 377 ++++++++++++++++
|
||
efitools/lib/asn1/test.c | 29 ++
|
||
efitools/lib/asn1/typedefs.h | 117 +++++
|
||
efitools/lib/asn1/x509.c | 58 +++
|
||
efitools/lib/configtable.c | 144 ++++++
|
||
efitools/lib/console.c | 413 +++++++++++++++++
|
||
efitools/lib/execute.c | 127 ++++++
|
||
efitools/lib/guid.c | 57 +++
|
||
efitools/lib/pecoff.c | 391 ++++++++++++++++
|
||
efitools/lib/security_policy.c | 399 +++++++++++++++++
|
||
efitools/lib/sha256.c | 394 +++++++++++++++++
|
||
efitools/lib/shell.c | 57 +++
|
||
efitools/lib/simple_file.c | 501 +++++++++++++++++++++
|
||
efitools/lib/variables.c | 340 ++++++++++++++
|
||
52 files changed, 7509 insertions(+), 3 deletions(-)
|
||
create mode 100644 efitools/COPYING
|
||
create mode 100644 efitools/Make.rules
|
||
create mode 100644 efitools/Makefile
|
||
create mode 100644 efitools/include/PeImage.h
|
||
create mode 100644 efitools/include/configtable.h
|
||
create mode 100644 efitools/include/console.h
|
||
create mode 100644 efitools/include/efiauthenticated.h
|
||
create mode 100644 efitools/include/errors.h
|
||
create mode 100644 efitools/include/execute.h
|
||
create mode 100644 efitools/include/guid.h
|
||
create mode 100644 efitools/include/kernel_efivars.h
|
||
create mode 100644 efitools/include/pecoff.h
|
||
create mode 100644 efitools/include/security_policy.h
|
||
create mode 100644 efitools/include/sha256.h
|
||
create mode 100644 efitools/include/shell.h
|
||
create mode 100644 efitools/include/simple_file.h
|
||
create mode 100644 efitools/include/variables.h
|
||
create mode 100644 efitools/include/variables_iterators.h
|
||
create mode 100644 efitools/include/version.h
|
||
create mode 100644 efitools/include/wincert.h
|
||
create mode 100644 efitools/include/x509.h
|
||
create mode 100644 efitools/lib/Makefile
|
||
create mode 100644 efitools/lib/asn1/.gitignore
|
||
create mode 100644 efitools/lib/asn1/Makefile
|
||
create mode 100644 efitools/lib/asn1/asn1.c
|
||
create mode 100644 efitools/lib/asn1/asn1.h
|
||
create mode 100644 efitools/lib/asn1/asn1_parser.c
|
||
create mode 100644 efitools/lib/asn1/asn1_parser.h
|
||
create mode 100644 efitools/lib/asn1/chunk.c
|
||
create mode 100644 efitools/lib/asn1/chunk.h
|
||
create mode 100644 efitools/lib/asn1/enumerator.c
|
||
create mode 100644 efitools/lib/asn1/enumerator.h
|
||
create mode 100644 efitools/lib/asn1/identification.c
|
||
create mode 100644 efitools/lib/asn1/identification.h
|
||
create mode 100644 efitools/lib/asn1/oid.c
|
||
create mode 100644 efitools/lib/asn1/oid.h
|
||
create mode 100644 efitools/lib/asn1/oid.pl
|
||
create mode 100644 efitools/lib/asn1/oid.txt
|
||
create mode 100644 efitools/lib/asn1/test.c
|
||
create mode 100644 efitools/lib/asn1/typedefs.h
|
||
create mode 100644 efitools/lib/asn1/x509.c
|
||
create mode 100644 efitools/lib/configtable.c
|
||
create mode 100644 efitools/lib/console.c
|
||
create mode 100644 efitools/lib/execute.c
|
||
create mode 100644 efitools/lib/guid.c
|
||
create mode 100644 efitools/lib/pecoff.c
|
||
create mode 100644 efitools/lib/security_policy.c
|
||
create mode 100644 efitools/lib/sha256.c
|
||
create mode 100644 efitools/lib/shell.c
|
||
create mode 100644 efitools/lib/simple_file.c
|
||
create mode 100644 efitools/lib/variables.c
|
||
|
||
diff --git a/Makefile b/Makefile
|
||
index 9217ba1..8ca8c51 100644
|
||
--- a/Makefile
|
||
+++ b/Makefile
|
||
@@ -1,11 +1,13 @@
|
||
+export TOPDIR := $(shell pwd)/
|
||
+
|
||
ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)
|
||
|
||
-SUBDIRS = Cryptlib
|
||
+SUBDIRS = Cryptlib efitools
|
||
|
||
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
|
||
+EFI_INCLUDES = -nostdinc -ICryptlib -ICryptlib/Include -Iefitools/include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol
|
||
EFI_PATH = /usr/lib64
|
||
|
||
LIB_GCC = $(shell $(CC) -print-libgcc-file-name)
|
||
@@ -67,7 +69,7 @@ shim.so: $(OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a
|
||
|
||
MokManager.o: $(MOK_SOURCES)
|
||
|
||
-MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a
|
||
+MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a efitools/lib/lib-efi.a
|
||
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS)
|
||
|
||
Cryptlib/libcryptlib.a:
|
||
@@ -76,6 +78,12 @@ Cryptlib/libcryptlib.a:
|
||
Cryptlib/OpenSSL/libopenssl.a:
|
||
$(MAKE) -C Cryptlib/OpenSSL
|
||
|
||
+efitools/lib/lib-efi.a:
|
||
+ $(MAKE) -C efitools/lib
|
||
+
|
||
+efitools/lib/asn1/libasn1-efi.a:
|
||
+ $(MAKE) -C efitools/lib/asn1
|
||
+
|
||
%.efi: %.so
|
||
objcopy -j .text -j .sdata -j .data \
|
||
-j .dynamic -j .dynsym -j .rel \
|
||
@@ -94,6 +102,7 @@ Cryptlib/OpenSSL/libopenssl.a:
|
||
clean:
|
||
$(MAKE) -C Cryptlib clean
|
||
$(MAKE) -C Cryptlib/OpenSSL clean
|
||
+ $(MAKE) -C efitools clean
|
||
rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(KEYS) certdb
|
||
rm -f *.debug *.so
|
||
|
||
diff --git a/efitools/COPYING b/efitools/COPYING
|
||
new file mode 100644
|
||
index 0000000..7737e63
|
||
--- /dev/null
|
||
+++ b/efitools/COPYING
|
||
@@ -0,0 +1,350 @@
|
||
+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. The library routines in lib/ are made available under the GNU
|
||
+Lesser General Public Licence version 2.1. Additionally for linking the
|
||
+programme files with openSSL, there is an additional permission that
|
||
+compiling, linking, and/or using OpenSSL is allowed.
|
||
+
|
||
+ 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.
|
||
+
|
||
+ 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.)
|
||
+
|
||
+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.
|
||
+
|
||
+ 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.
|
||
+
|
||
+ 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
|
||
+
|
||
+ 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.
|
||
diff --git a/efitools/Make.rules b/efitools/Make.rules
|
||
new file mode 100644
|
||
index 0000000..6ba937e
|
||
--- /dev/null
|
||
+++ b/efitools/Make.rules
|
||
@@ -0,0 +1,24 @@
|
||
+ARCH = $(shell uname -m)
|
||
+INCDIR = -I$(TOPDIR)efitools/include/ -I/usr/include/efi -I/usr/include/efi/$(ARCH) -I/usr/include/efi/protocol
|
||
+CPPFLAGS = -DCONFIG_$(ARCH)
|
||
+CFLAGS = -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -mno-red-zone -fno-stack-protector -g
|
||
+LDFLAGS = -nostdlib
|
||
+LDFLAGS += -T $(LDSCRIPT) -shared -Bsymbolic $(CRTOBJS) -L $(CRTPATH)
|
||
+FORMAT = efi-app-$(ARCH)
|
||
+OBJCOPY = objcopy
|
||
+
|
||
+ifeq ($(ARCH),x86_64)
|
||
+ CFLAGS += -DEFI_FUNCTION_WRAPPER
|
||
+endif
|
||
+
|
||
+%.o: %.c
|
||
+ $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||
+
|
||
+%.efi.o: %.c
|
||
+ $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@
|
||
+
|
||
+%.efi.s: %.c
|
||
+ $(CC) -S $(INCDIR) $(CFLAGS) $(CPPFLAGS) -fno-toplevel-reorder -DBUILD_EFI -c $< -o $@
|
||
+
|
||
+%.a:
|
||
+ ar rcv $@ $^
|
||
diff --git a/efitools/Makefile b/efitools/Makefile
|
||
new file mode 100644
|
||
index 0000000..45d6f3a
|
||
--- /dev/null
|
||
+++ b/efitools/Makefile
|
||
@@ -0,0 +1,15 @@
|
||
+include Make.rules
|
||
+
|
||
+EFITOOL_LIBS=lib/lib-efi.a lib/asn1/libasn1-efi.a
|
||
+
|
||
+all: $(EFITOOL_LIBS)
|
||
+
|
||
+lib/lib-efi.a:
|
||
+ $(MAKE) -C lib $(notdir $@)
|
||
+
|
||
+lib/asn1/libasn1-efi.a:
|
||
+ $(MAKE) -C lib/asn1 $(notdir $@)
|
||
+
|
||
+clean:
|
||
+ $(MAKE) -C lib clean
|
||
+ $(MAKE) -C lib/asn1 clean
|
||
diff --git a/efitools/include/PeImage.h b/efitools/include/PeImage.h
|
||
new file mode 100644
|
||
index 0000000..ec13404
|
||
--- /dev/null
|
||
+++ b/efitools/include/PeImage.h
|
||
@@ -0,0 +1,787 @@
|
||
+/** @file
|
||
+ EFI image format for PE32, PE32+ and TE. Please note some data structures are
|
||
+ different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and
|
||
+ EFI_IMAGE_NT_HEADERS64 is for PE32+.
|
||
+
|
||
+ This file is coded to the Visual Studio, Microsoft Portable Executable and
|
||
+ Common Object File Format Specification, Revision 8.0 - May 16, 2006.
|
||
+ This file also includes some definitions in PI Specification, Revision 1.0.
|
||
+
|
||
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||
+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 __PE_IMAGE_H__
|
||
+#define __PE_IMAGE_H__
|
||
+
|
||
+#include <wincert.h>
|
||
+
|
||
+#define SIGNATURE_16(A, B) ((A) | (B << 8))
|
||
+#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
|
||
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
|
||
+ (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
|
||
+
|
||
+#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)))
|
||
+#define ALIGN_POINTER(Pointer, Alignment) ((VOID *) (ALIGN_VALUE ((UINTN)(Pointer), (Alignment))))
|
||
+
|
||
+//
|
||
+// PE32+ Subsystem type for EFI images
|
||
+//
|
||
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10
|
||
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
|
||
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
|
||
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 ///< defined PI Specification, 1.0
|
||
+
|
||
+
|
||
+//
|
||
+// PE32+ Machine type for EFI images
|
||
+//
|
||
+#define IMAGE_FILE_MACHINE_I386 0x014c
|
||
+#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||
+#define IMAGE_FILE_MACHINE_EBC 0x0EBC
|
||
+#define IMAGE_FILE_MACHINE_X64 0x8664
|
||
+#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2
|
||
+
|
||
+//
|
||
+// EXE file formats
|
||
+//
|
||
+#define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z')
|
||
+#define EFI_IMAGE_OS2_SIGNATURE SIGNATURE_16('N', 'E')
|
||
+#define EFI_IMAGE_OS2_SIGNATURE_LE SIGNATURE_16('L', 'E')
|
||
+#define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0')
|
||
+
|
||
+///
|
||
+/// PE images can start with an optional DOS header, so if an image is run
|
||
+/// under DOS it can print an error message.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT16 e_magic; ///< Magic number.
|
||
+ UINT16 e_cblp; ///< Bytes on last page of file.
|
||
+ UINT16 e_cp; ///< Pages in file.
|
||
+ UINT16 e_crlc; ///< Relocations.
|
||
+ UINT16 e_cparhdr; ///< Size of header in paragraphs.
|
||
+ UINT16 e_minalloc; ///< Minimum extra paragraphs needed.
|
||
+ UINT16 e_maxalloc; ///< Maximum extra paragraphs needed.
|
||
+ UINT16 e_ss; ///< Initial (relative) SS value.
|
||
+ UINT16 e_sp; ///< Initial SP value.
|
||
+ UINT16 e_csum; ///< Checksum.
|
||
+ UINT16 e_ip; ///< Initial IP value.
|
||
+ UINT16 e_cs; ///< Initial (relative) CS value.
|
||
+ UINT16 e_lfarlc; ///< File address of relocation table.
|
||
+ UINT16 e_ovno; ///< Overlay number.
|
||
+ UINT16 e_res[4]; ///< Reserved words.
|
||
+ UINT16 e_oemid; ///< OEM identifier (for e_oeminfo).
|
||
+ UINT16 e_oeminfo; ///< OEM information; e_oemid specific.
|
||
+ UINT16 e_res2[10]; ///< Reserved words.
|
||
+ UINT32 e_lfanew; ///< File address of new exe header.
|
||
+} EFI_IMAGE_DOS_HEADER;
|
||
+
|
||
+///
|
||
+/// COFF File Header (Object and Image).
|
||
+///
|
||
+typedef struct {
|
||
+ UINT16 Machine;
|
||
+ UINT16 NumberOfSections;
|
||
+ UINT32 TimeDateStamp;
|
||
+ UINT32 PointerToSymbolTable;
|
||
+ UINT32 NumberOfSymbols;
|
||
+ UINT16 SizeOfOptionalHeader;
|
||
+ UINT16 Characteristics;
|
||
+} EFI_IMAGE_FILE_HEADER;
|
||
+
|
||
+///
|
||
+/// Size of EFI_IMAGE_FILE_HEADER.
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_FILE_HEADER 20
|
||
+
|
||
+//
|
||
+// Characteristics
|
||
+//
|
||
+#define EFI_IMAGE_FILE_RELOCS_STRIPPED (1 << 0) ///< 0x0001 Relocation info stripped from file.
|
||
+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE (1 << 1) ///< 0x0002 File is executable (i.e. no unresolved externel references).
|
||
+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED (1 << 2) ///< 0x0004 Line nunbers stripped from file.
|
||
+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED (1 << 3) ///< 0x0008 Local symbols stripped from file.
|
||
+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO (1 << 7) ///< 0x0080 Bytes of machine word are reversed.
|
||
+#define EFI_IMAGE_FILE_32BIT_MACHINE (1 << 8) ///< 0x0100 32 bit word machine.
|
||
+#define EFI_IMAGE_FILE_DEBUG_STRIPPED (1 << 9) ///< 0x0200 Debugging info stripped from file in .DBG file.
|
||
+#define EFI_IMAGE_FILE_SYSTEM (1 << 12) ///< 0x1000 System File.
|
||
+#define EFI_IMAGE_FILE_DLL (1 << 13) ///< 0x2000 File is a DLL.
|
||
+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI (1 << 15) ///< 0x8000 Bytes of machine word are reversed.
|
||
+
|
||
+///
|
||
+/// Header Data Directories.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 VirtualAddress;
|
||
+ UINT32 Size;
|
||
+} EFI_IMAGE_DATA_DIRECTORY;
|
||
+
|
||
+//
|
||
+// Directory Entries
|
||
+//
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9
|
||
+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
|
||
+
|
||
+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
|
||
+
|
||
+///
|
||
+/// @attention
|
||
+/// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and
|
||
+/// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary
|
||
+/// after NT additional fields.
|
||
+///
|
||
+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
||
+
|
||
+///
|
||
+/// Optional Header Standard Fields for PE32.
|
||
+///
|
||
+typedef struct {
|
||
+ ///
|
||
+ /// Standard fields.
|
||
+ ///
|
||
+ UINT16 Magic;
|
||
+ UINT8 MajorLinkerVersion;
|
||
+ UINT8 MinorLinkerVersion;
|
||
+ UINT32 SizeOfCode;
|
||
+ UINT32 SizeOfInitializedData;
|
||
+ UINT32 SizeOfUninitializedData;
|
||
+ UINT32 AddressOfEntryPoint;
|
||
+ UINT32 BaseOfCode;
|
||
+ UINT32 BaseOfData; ///< PE32 contains this additional field, which is absent in PE32+.
|
||
+ ///
|
||
+ /// Optional Header Windows-Specific Fields.
|
||
+ ///
|
||
+ UINT32 ImageBase;
|
||
+ UINT32 SectionAlignment;
|
||
+ UINT32 FileAlignment;
|
||
+ UINT16 MajorOperatingSystemVersion;
|
||
+ UINT16 MinorOperatingSystemVersion;
|
||
+ UINT16 MajorImageVersion;
|
||
+ UINT16 MinorImageVersion;
|
||
+ UINT16 MajorSubsystemVersion;
|
||
+ UINT16 MinorSubsystemVersion;
|
||
+ UINT32 Win32VersionValue;
|
||
+ UINT32 SizeOfImage;
|
||
+ UINT32 SizeOfHeaders;
|
||
+ UINT32 CheckSum;
|
||
+ UINT16 Subsystem;
|
||
+ UINT16 DllCharacteristics;
|
||
+ UINT32 SizeOfStackReserve;
|
||
+ UINT32 SizeOfStackCommit;
|
||
+ UINT32 SizeOfHeapReserve;
|
||
+ UINT32 SizeOfHeapCommit;
|
||
+ UINT32 LoaderFlags;
|
||
+ UINT32 NumberOfRvaAndSizes;
|
||
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
|
||
+} EFI_IMAGE_OPTIONAL_HEADER32;
|
||
+
|
||
+///
|
||
+/// @attention
|
||
+/// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and
|
||
+/// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary
|
||
+/// after NT additional fields.
|
||
+///
|
||
+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
||
+
|
||
+///
|
||
+/// Optional Header Standard Fields for PE32+.
|
||
+///
|
||
+typedef struct {
|
||
+ ///
|
||
+ /// Standard fields.
|
||
+ ///
|
||
+ UINT16 Magic;
|
||
+ UINT8 MajorLinkerVersion;
|
||
+ UINT8 MinorLinkerVersion;
|
||
+ UINT32 SizeOfCode;
|
||
+ UINT32 SizeOfInitializedData;
|
||
+ UINT32 SizeOfUninitializedData;
|
||
+ UINT32 AddressOfEntryPoint;
|
||
+ UINT32 BaseOfCode;
|
||
+ ///
|
||
+ /// Optional Header Windows-Specific Fields.
|
||
+ ///
|
||
+ UINT64 ImageBase;
|
||
+ UINT32 SectionAlignment;
|
||
+ UINT32 FileAlignment;
|
||
+ UINT16 MajorOperatingSystemVersion;
|
||
+ UINT16 MinorOperatingSystemVersion;
|
||
+ UINT16 MajorImageVersion;
|
||
+ UINT16 MinorImageVersion;
|
||
+ UINT16 MajorSubsystemVersion;
|
||
+ UINT16 MinorSubsystemVersion;
|
||
+ UINT32 Win32VersionValue;
|
||
+ UINT32 SizeOfImage;
|
||
+ UINT32 SizeOfHeaders;
|
||
+ UINT32 CheckSum;
|
||
+ UINT16 Subsystem;
|
||
+ UINT16 DllCharacteristics;
|
||
+ UINT64 SizeOfStackReserve;
|
||
+ UINT64 SizeOfStackCommit;
|
||
+ UINT64 SizeOfHeapReserve;
|
||
+ UINT64 SizeOfHeapCommit;
|
||
+ UINT32 LoaderFlags;
|
||
+ UINT32 NumberOfRvaAndSizes;
|
||
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
|
||
+} EFI_IMAGE_OPTIONAL_HEADER64;
|
||
+
|
||
+
|
||
+///
|
||
+/// @attention
|
||
+/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 Signature;
|
||
+ EFI_IMAGE_FILE_HEADER FileHeader;
|
||
+ EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;
|
||
+} EFI_IMAGE_NT_HEADERS32;
|
||
+
|
||
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)
|
||
+
|
||
+///
|
||
+/// @attention
|
||
+/// EFI_IMAGE_HEADERS64 is for use ONLY by tools.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 Signature;
|
||
+ EFI_IMAGE_FILE_HEADER FileHeader;
|
||
+ EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;
|
||
+} EFI_IMAGE_NT_HEADERS64;
|
||
+
|
||
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)
|
||
+
|
||
+//
|
||
+// Other Windows Subsystem Values
|
||
+//
|
||
+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0
|
||
+#define EFI_IMAGE_SUBSYSTEM_NATIVE 1
|
||
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
|
||
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3
|
||
+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5
|
||
+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7
|
||
+
|
||
+///
|
||
+/// Length of ShortName.
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
|
||
+
|
||
+///
|
||
+/// Section Table. This table immediately follows the optional header.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
|
||
+ union {
|
||
+ UINT32 PhysicalAddress;
|
||
+ UINT32 VirtualSize;
|
||
+ } Misc;
|
||
+ UINT32 VirtualAddress;
|
||
+ UINT32 SizeOfRawData;
|
||
+ UINT32 PointerToRawData;
|
||
+ UINT32 PointerToRelocations;
|
||
+ UINT32 PointerToLinenumbers;
|
||
+ UINT16 NumberOfRelocations;
|
||
+ UINT16 NumberOfLinenumbers;
|
||
+ UINT32 Characteristics;
|
||
+} EFI_IMAGE_SECTION_HEADER;
|
||
+
|
||
+///
|
||
+/// Size of EFI_IMAGE_SECTION_HEADER.
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40
|
||
+
|
||
+//
|
||
+// Section Flags Values
|
||
+//
|
||
+#define EFI_IMAGE_SCN_TYPE_NO_PAD BIT3 ///< 0x00000008 ///< Reserved.
|
||
+#define EFI_IMAGE_SCN_CNT_CODE BIT5 ///< 0x00000020
|
||
+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA BIT6 ///< 0x00000040
|
||
+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA BIT7 ///< 0x00000080
|
||
+
|
||
+#define EFI_IMAGE_SCN_LNK_OTHER BIT8 ///< 0x00000100 ///< Reserved.
|
||
+#define EFI_IMAGE_SCN_LNK_INFO BIT9 ///< 0x00000200 ///< Section contains comments or some other type of information.
|
||
+#define EFI_IMAGE_SCN_LNK_REMOVE BIT11 ///< 0x00000800 ///< Section contents will not become part of image.
|
||
+#define EFI_IMAGE_SCN_LNK_COMDAT BIT12 ///< 0x00001000
|
||
+
|
||
+#define EFI_IMAGE_SCN_ALIGN_1BYTES BIT20 ///< 0x00100000
|
||
+#define EFI_IMAGE_SCN_ALIGN_2BYTES BIT21 ///< 0x00200000
|
||
+#define EFI_IMAGE_SCN_ALIGN_4BYTES (BIT20|BIT21) ///< 0x00300000
|
||
+#define EFI_IMAGE_SCN_ALIGN_8BYTES BIT22 ///< 0x00400000
|
||
+#define EFI_IMAGE_SCN_ALIGN_16BYTES (BIT20|BIT22) ///< 0x00500000
|
||
+#define EFI_IMAGE_SCN_ALIGN_32BYTES (BIT21|BIT22) ///< 0x00600000
|
||
+#define EFI_IMAGE_SCN_ALIGN_64BYTES (BIT20|BIT21|BIT22) ///< 0x00700000
|
||
+
|
||
+#define EFI_IMAGE_SCN_MEM_DISCARDABLE BIT25 ///< 0x02000000
|
||
+#define EFI_IMAGE_SCN_MEM_NOT_CACHED BIT26 ///< 0x04000000
|
||
+#define EFI_IMAGE_SCN_MEM_NOT_PAGED BIT27 ///< 0x08000000
|
||
+#define EFI_IMAGE_SCN_MEM_SHARED BIT28 ///< 0x10000000
|
||
+#define EFI_IMAGE_SCN_MEM_EXECUTE BIT29 ///< 0x20000000
|
||
+#define EFI_IMAGE_SCN_MEM_READ BIT30 ///< 0x40000000
|
||
+#define EFI_IMAGE_SCN_MEM_WRITE BIT31 ///< 0x80000000
|
||
+
|
||
+///
|
||
+/// Size of a Symbol Table Record.
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_SYMBOL 18
|
||
+
|
||
+//
|
||
+// Symbols have a section number of the section in which they are
|
||
+// defined. Otherwise, section numbers have the following meanings:
|
||
+//
|
||
+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 ///< Symbol is undefined or is common.
|
||
+#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 ///< Symbol is an absolute value.
|
||
+#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 ///< Symbol is a special debug item.
|
||
+
|
||
+//
|
||
+// Symbol Type (fundamental) values.
|
||
+//
|
||
+#define EFI_IMAGE_SYM_TYPE_NULL 0 ///< no type.
|
||
+#define EFI_IMAGE_SYM_TYPE_VOID 1 ///< no valid type.
|
||
+#define EFI_IMAGE_SYM_TYPE_CHAR 2 ///< type character.
|
||
+#define EFI_IMAGE_SYM_TYPE_SHORT 3 ///< type short integer.
|
||
+#define EFI_IMAGE_SYM_TYPE_INT 4
|
||
+#define EFI_IMAGE_SYM_TYPE_LONG 5
|
||
+#define EFI_IMAGE_SYM_TYPE_FLOAT 6
|
||
+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
|
||
+#define EFI_IMAGE_SYM_TYPE_STRUCT 8
|
||
+#define EFI_IMAGE_SYM_TYPE_UNION 9
|
||
+#define EFI_IMAGE_SYM_TYPE_ENUM 10 ///< enumeration.
|
||
+#define EFI_IMAGE_SYM_TYPE_MOE 11 ///< member of enumeration.
|
||
+#define EFI_IMAGE_SYM_TYPE_BYTE 12
|
||
+#define EFI_IMAGE_SYM_TYPE_WORD 13
|
||
+#define EFI_IMAGE_SYM_TYPE_UINT 14
|
||
+#define EFI_IMAGE_SYM_TYPE_DWORD 15
|
||
+
|
||
+//
|
||
+// Symbol Type (derived) values.
|
||
+//
|
||
+#define EFI_IMAGE_SYM_DTYPE_NULL 0 ///< no derived type.
|
||
+#define EFI_IMAGE_SYM_DTYPE_POINTER 1
|
||
+#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2
|
||
+#define EFI_IMAGE_SYM_DTYPE_ARRAY 3
|
||
+
|
||
+//
|
||
+// Storage classes.
|
||
+//
|
||
+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION ((UINT8) -1)
|
||
+#define EFI_IMAGE_SYM_CLASS_NULL 0
|
||
+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1
|
||
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2
|
||
+#define EFI_IMAGE_SYM_CLASS_STATIC 3
|
||
+#define EFI_IMAGE_SYM_CLASS_REGISTER 4
|
||
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5
|
||
+#define EFI_IMAGE_SYM_CLASS_LABEL 6
|
||
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
|
||
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
|
||
+#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9
|
||
+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10
|
||
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
|
||
+#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12
|
||
+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13
|
||
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
|
||
+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15
|
||
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
|
||
+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17
|
||
+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18
|
||
+#define EFI_IMAGE_SYM_CLASS_BLOCK 100
|
||
+#define EFI_IMAGE_SYM_CLASS_FUNCTION 101
|
||
+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102
|
||
+#define EFI_IMAGE_SYM_CLASS_FILE 103
|
||
+#define EFI_IMAGE_SYM_CLASS_SECTION 104
|
||
+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
|
||
+
|
||
+//
|
||
+// type packing constants
|
||
+//
|
||
+#define EFI_IMAGE_N_BTMASK 017
|
||
+#define EFI_IMAGE_N_TMASK 060
|
||
+#define EFI_IMAGE_N_TMASK1 0300
|
||
+#define EFI_IMAGE_N_TMASK2 0360
|
||
+#define EFI_IMAGE_N_BTSHFT 4
|
||
+#define EFI_IMAGE_N_TSHIFT 2
|
||
+
|
||
+//
|
||
+// Communal selection types.
|
||
+//
|
||
+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1
|
||
+#define EFI_IMAGE_COMDAT_SELECT_ANY 2
|
||
+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3
|
||
+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4
|
||
+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
|
||
+
|
||
+//
|
||
+// the following values only be referred in PeCoff, not defined in PECOFF.
|
||
+//
|
||
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
|
||
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
|
||
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
|
||
+
|
||
+///
|
||
+/// Relocation format.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 VirtualAddress;
|
||
+ UINT32 SymbolTableIndex;
|
||
+ UINT16 Type;
|
||
+} EFI_IMAGE_RELOCATION;
|
||
+
|
||
+///
|
||
+/// Size of EFI_IMAGE_RELOCATION
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_RELOCATION 10
|
||
+
|
||
+//
|
||
+// I386 relocation types.
|
||
+//
|
||
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000 ///< Reference is absolute, no relocation is necessary.
|
||
+#define EFI_IMAGE_REL_I386_DIR16 0x0001 ///< Direct 16-bit reference to the symbols virtual address.
|
||
+#define EFI_IMAGE_REL_I386_REL16 0x0002 ///< PC-relative 16-bit reference to the symbols virtual address.
|
||
+#define EFI_IMAGE_REL_I386_DIR32 0x0006 ///< Direct 32-bit reference to the symbols virtual address.
|
||
+#define EFI_IMAGE_REL_I386_DIR32NB 0x0007 ///< Direct 32-bit reference to the symbols virtual address, base not included.
|
||
+#define EFI_IMAGE_REL_I386_SEG12 0x0009 ///< Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address.
|
||
+#define EFI_IMAGE_REL_I386_SECTION 0x000A
|
||
+#define EFI_IMAGE_REL_I386_SECREL 0x000B
|
||
+#define EFI_IMAGE_REL_I386_REL32 0x0014 ///< PC-relative 32-bit reference to the symbols virtual address.
|
||
+
|
||
+//
|
||
+// x64 processor relocation types.
|
||
+//
|
||
+#define IMAGE_REL_AMD64_ABSOLUTE 0x0000
|
||
+#define IMAGE_REL_AMD64_ADDR64 0x0001
|
||
+#define IMAGE_REL_AMD64_ADDR32 0x0002
|
||
+#define IMAGE_REL_AMD64_ADDR32NB 0x0003
|
||
+#define IMAGE_REL_AMD64_REL32 0x0004
|
||
+#define IMAGE_REL_AMD64_REL32_1 0x0005
|
||
+#define IMAGE_REL_AMD64_REL32_2 0x0006
|
||
+#define IMAGE_REL_AMD64_REL32_3 0x0007
|
||
+#define IMAGE_REL_AMD64_REL32_4 0x0008
|
||
+#define IMAGE_REL_AMD64_REL32_5 0x0009
|
||
+#define IMAGE_REL_AMD64_SECTION 0x000A
|
||
+#define IMAGE_REL_AMD64_SECREL 0x000B
|
||
+#define IMAGE_REL_AMD64_SECREL7 0x000C
|
||
+#define IMAGE_REL_AMD64_TOKEN 0x000D
|
||
+#define IMAGE_REL_AMD64_SREL32 0x000E
|
||
+#define IMAGE_REL_AMD64_PAIR 0x000F
|
||
+#define IMAGE_REL_AMD64_SSPAN32 0x0010
|
||
+
|
||
+///
|
||
+/// Based relocation format.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 VirtualAddress;
|
||
+ UINT32 SizeOfBlock;
|
||
+} EFI_IMAGE_BASE_RELOCATION;
|
||
+
|
||
+///
|
||
+/// Size of EFI_IMAGE_BASE_RELOCATION.
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8
|
||
+
|
||
+//
|
||
+// Based relocation types.
|
||
+//
|
||
+#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
|
||
+#define EFI_IMAGE_REL_BASED_HIGH 1
|
||
+#define EFI_IMAGE_REL_BASED_LOW 2
|
||
+#define EFI_IMAGE_REL_BASED_HIGHLOW 3
|
||
+#define EFI_IMAGE_REL_BASED_HIGHADJ 4
|
||
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
|
||
+#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
|
||
+#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
|
||
+#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
|
||
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9
|
||
+#define EFI_IMAGE_REL_BASED_DIR64 10
|
||
+
|
||
+///
|
||
+/// Line number format.
|
||
+///
|
||
+typedef struct {
|
||
+ union {
|
||
+ UINT32 SymbolTableIndex; ///< Symbol table index of function name if Linenumber is 0.
|
||
+ UINT32 VirtualAddress; ///< Virtual address of line number.
|
||
+ } Type;
|
||
+ UINT16 Linenumber; ///< Line number.
|
||
+} EFI_IMAGE_LINENUMBER;
|
||
+
|
||
+///
|
||
+/// Size of EFI_IMAGE_LINENUMBER.
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_LINENUMBER 6
|
||
+
|
||
+//
|
||
+// Archive format.
|
||
+//
|
||
+#define EFI_IMAGE_ARCHIVE_START_SIZE 8
|
||
+#define EFI_IMAGE_ARCHIVE_START "!<arch>\n"
|
||
+#define EFI_IMAGE_ARCHIVE_END "`\n"
|
||
+#define EFI_IMAGE_ARCHIVE_PAD "\n"
|
||
+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ "
|
||
+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
|
||
+
|
||
+///
|
||
+/// Archive Member Headers
|
||
+///
|
||
+typedef struct {
|
||
+ UINT8 Name[16]; ///< File member name - `/' terminated.
|
||
+ UINT8 Date[12]; ///< File member date - decimal.
|
||
+ UINT8 UserID[6]; ///< File member user id - decimal.
|
||
+ UINT8 GroupID[6]; ///< File member group id - decimal.
|
||
+ UINT8 Mode[8]; ///< File member mode - octal.
|
||
+ UINT8 Size[10]; ///< File member size - decimal.
|
||
+ UINT8 EndHeader[2]; ///< String to end header. (0x60 0x0A).
|
||
+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
|
||
+
|
||
+///
|
||
+/// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER.
|
||
+///
|
||
+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
|
||
+
|
||
+
|
||
+//
|
||
+// DLL Support
|
||
+//
|
||
+
|
||
+///
|
||
+/// Export Directory Table.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 Characteristics;
|
||
+ UINT32 TimeDateStamp;
|
||
+ UINT16 MajorVersion;
|
||
+ UINT16 MinorVersion;
|
||
+ UINT32 Name;
|
||
+ UINT32 Base;
|
||
+ UINT32 NumberOfFunctions;
|
||
+ UINT32 NumberOfNames;
|
||
+ UINT32 AddressOfFunctions;
|
||
+ UINT32 AddressOfNames;
|
||
+ UINT32 AddressOfNameOrdinals;
|
||
+} EFI_IMAGE_EXPORT_DIRECTORY;
|
||
+
|
||
+///
|
||
+/// Hint/Name Table.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT16 Hint;
|
||
+ UINT8 Name[1];
|
||
+} EFI_IMAGE_IMPORT_BY_NAME;
|
||
+
|
||
+///
|
||
+/// Import Address Table RVA (Thunk Table).
|
||
+///
|
||
+typedef struct {
|
||
+ union {
|
||
+ UINT32 Function;
|
||
+ UINT32 Ordinal;
|
||
+ EFI_IMAGE_IMPORT_BY_NAME *AddressOfData;
|
||
+ } u1;
|
||
+} EFI_IMAGE_THUNK_DATA;
|
||
+
|
||
+#define EFI_IMAGE_ORDINAL_FLAG BIT31 ///< Flag for PE32.
|
||
+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
|
||
+#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
|
||
+
|
||
+///
|
||
+/// Import Directory Table
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 Characteristics;
|
||
+ UINT32 TimeDateStamp;
|
||
+ UINT32 ForwarderChain;
|
||
+ UINT32 Name;
|
||
+ EFI_IMAGE_THUNK_DATA *FirstThunk;
|
||
+} EFI_IMAGE_IMPORT_DESCRIPTOR;
|
||
+
|
||
+
|
||
+///
|
||
+/// Debug Directory Format.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 Characteristics;
|
||
+ UINT32 TimeDateStamp;
|
||
+ UINT16 MajorVersion;
|
||
+ UINT16 MinorVersion;
|
||
+ UINT32 Type;
|
||
+ UINT32 SizeOfData;
|
||
+ UINT32 RVA; ///< The address of the debug data when loaded, relative to the image base.
|
||
+ UINT32 FileOffset; ///< The file pointer to the debug data.
|
||
+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
|
||
+
|
||
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 ///< The Visual C++ debug information.
|
||
+
|
||
+///
|
||
+/// Debug Data Structure defined in Microsoft C++.
|
||
+///
|
||
+#define CODEVIEW_SIGNATURE_NB10 SIGNATURE_32('N', 'B', '1', '0')
|
||
+typedef struct {
|
||
+ UINT32 Signature; ///< "NB10"
|
||
+ UINT32 Unknown;
|
||
+ UINT32 Unknown2;
|
||
+ UINT32 Unknown3;
|
||
+ //
|
||
+ // Filename of .PDB goes here
|
||
+ //
|
||
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
|
||
+
|
||
+///
|
||
+/// Debug Data Structure defined in Microsoft C++.
|
||
+///
|
||
+#define CODEVIEW_SIGNATURE_RSDS SIGNATURE_32('R', 'S', 'D', 'S')
|
||
+typedef struct {
|
||
+ UINT32 Signature; ///< "RSDS".
|
||
+ UINT32 Unknown;
|
||
+ UINT32 Unknown2;
|
||
+ UINT32 Unknown3;
|
||
+ UINT32 Unknown4;
|
||
+ UINT32 Unknown5;
|
||
+ //
|
||
+ // Filename of .PDB goes here
|
||
+ //
|
||
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
|
||
+
|
||
+
|
||
+///
|
||
+/// Debug Data Structure defined by Apple Mach-O to Coff utility.
|
||
+///
|
||
+#define CODEVIEW_SIGNATURE_MTOC SIGNATURE_32('M', 'T', 'O', 'C')
|
||
+typedef struct {
|
||
+ UINT32 Signature; ///< "MTOC".
|
||
+ EFI_GUID MachOUuid;
|
||
+ //
|
||
+ // Filename of .DLL (Mach-O with debug info) goes here
|
||
+ //
|
||
+} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;
|
||
+
|
||
+///
|
||
+/// Resource format.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 Characteristics;
|
||
+ UINT32 TimeDateStamp;
|
||
+ UINT16 MajorVersion;
|
||
+ UINT16 MinorVersion;
|
||
+ UINT16 NumberOfNamedEntries;
|
||
+ UINT16 NumberOfIdEntries;
|
||
+ //
|
||
+ // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here.
|
||
+ //
|
||
+} EFI_IMAGE_RESOURCE_DIRECTORY;
|
||
+
|
||
+///
|
||
+/// Resource directory entry format.
|
||
+///
|
||
+typedef struct {
|
||
+ union {
|
||
+ struct {
|
||
+ UINT32 NameOffset:31;
|
||
+ UINT32 NameIsString:1;
|
||
+ } s;
|
||
+ UINT32 Id;
|
||
+ } u1;
|
||
+ union {
|
||
+ UINT32 OffsetToData;
|
||
+ struct {
|
||
+ UINT32 OffsetToDirectory:31;
|
||
+ UINT32 DataIsDirectory:1;
|
||
+ } s;
|
||
+ } u2;
|
||
+} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||
+
|
||
+///
|
||
+/// Resource directory entry for string.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT16 Length;
|
||
+ CHAR16 String[1];
|
||
+} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;
|
||
+
|
||
+///
|
||
+/// Resource directory entry for data array.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT32 OffsetToData;
|
||
+ UINT32 Size;
|
||
+ UINT32 CodePage;
|
||
+ UINT32 Reserved;
|
||
+} EFI_IMAGE_RESOURCE_DATA_ENTRY;
|
||
+
|
||
+///
|
||
+/// Header format for TE images, defined in the PI Specification, 1.0.
|
||
+///
|
||
+typedef struct {
|
||
+ UINT16 Signature; ///< The signature for TE format = "VZ".
|
||
+ UINT16 Machine; ///< From the original file header.
|
||
+ UINT8 NumberOfSections; ///< From the original file header.
|
||
+ UINT8 Subsystem; ///< From original optional header.
|
||
+ UINT16 StrippedSize; ///< Number of bytes we removed from the header.
|
||
+ UINT32 AddressOfEntryPoint; ///< Offset to entry point -- from original optional header.
|
||
+ UINT32 BaseOfCode; ///< From original image -- required for ITP debug.
|
||
+ UINT64 ImageBase; ///< From original file header.
|
||
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; ///< Only base relocation and debug directory.
|
||
+} EFI_TE_IMAGE_HEADER;
|
||
+
|
||
+
|
||
+#define EFI_TE_IMAGE_HEADER_SIGNATURE SIGNATURE_16('V', 'Z')
|
||
+
|
||
+//
|
||
+// Data directory indexes in our TE image header
|
||
+//
|
||
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0
|
||
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1
|
||
+
|
||
+
|
||
+///
|
||
+/// Union of PE32, PE32+, and TE headers.
|
||
+///
|
||
+typedef union {
|
||
+ EFI_IMAGE_NT_HEADERS32 Pe32;
|
||
+ EFI_IMAGE_NT_HEADERS64 Pe32Plus;
|
||
+ EFI_TE_IMAGE_HEADER Te;
|
||
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;
|
||
+
|
||
+typedef union {
|
||
+ EFI_IMAGE_NT_HEADERS32 *Pe32;
|
||
+ EFI_IMAGE_NT_HEADERS64 *Pe32Plus;
|
||
+ EFI_TE_IMAGE_HEADER *Te;
|
||
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *Union;
|
||
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;
|
||
+
|
||
+typedef struct {
|
||
+ WIN_CERTIFICATE Hdr;
|
||
+ UINT8 CertData[1];
|
||
+} WIN_CERTIFICATE_EFI_PKCS;
|
||
+
|
||
+#define SHA256_DIGEST_SIZE 32
|
||
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||
+
|
||
+typedef struct {
|
||
+ UINT64 ImageAddress;
|
||
+ UINT64 ImageSize;
|
||
+ UINT64 EntryPoint;
|
||
+ UINTN SizeOfHeaders;
|
||
+ UINT16 ImageType;
|
||
+ UINT16 NumberOfSections;
|
||
+ EFI_IMAGE_SECTION_HEADER *FirstSection;
|
||
+ EFI_IMAGE_DATA_DIRECTORY *RelocDir;
|
||
+ EFI_IMAGE_DATA_DIRECTORY *SecDir;
|
||
+ UINT64 NumberOfRvaAndSizes;
|
||
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr;
|
||
+} PE_COFF_LOADER_IMAGE_CONTEXT;
|
||
+
|
||
+#endif
|
||
diff --git a/efitools/include/configtable.h b/efitools/include/configtable.h
|
||
new file mode 100644
|
||
index 0000000..fa2b505
|
||
--- /dev/null
|
||
+++ b/efitools/include/configtable.h
|
||
@@ -0,0 +1,68 @@
|
||
+/* definitions straight from TianoCore */
|
||
+
|
||
+typedef UINT32 EFI_IMAGE_EXECUTION_ACTION;
|
||
+
|
||
+#define EFI_IMAGE_EXECUTION_AUTHENTICATION 0x00000007
|
||
+#define EFI_IMAGE_EXECUTION_AUTH_UNTESTED 0x00000000
|
||
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED 0x00000001
|
||
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED 0x00000002
|
||
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND 0x00000003
|
||
+#define EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND 0x00000004
|
||
+#define EFI_IMAGE_EXECUTION_POLICY_FAILED 0x00000005
|
||
+#define EFI_IMAGE_EXECUTION_INITIALIZED 0x00000008
|
||
+
|
||
+typedef struct {
|
||
+ ///
|
||
+ /// Describes the action taken by the firmware regarding this image.
|
||
+ ///
|
||
+ EFI_IMAGE_EXECUTION_ACTION Action;
|
||
+ ///
|
||
+ /// Size of all of the entire structure.
|
||
+ ///
|
||
+ UINT32 InfoSize;
|
||
+ ///
|
||
+ /// If this image was a UEFI device driver (for option ROM, for example) this is the
|
||
+ /// null-terminated, user-friendly name for the device. If the image was for an application,
|
||
+ /// then this is the name of the application. If this cannot be determined, then a simple
|
||
+ /// NULL character should be put in this position.
|
||
+ /// CHAR16 Name[];
|
||
+ ///
|
||
+
|
||
+ ///
|
||
+ /// For device drivers, this is the device path of the device for which this device driver
|
||
+ /// was intended. In some cases, the driver itself may be stored as part of the system
|
||
+ /// firmware, but this field should record the device's path, not the firmware path. For
|
||
+ /// applications, this is the device path of the application. If this cannot be determined,
|
||
+ /// a simple end-of-path device node should be put in this position.
|
||
+ /// EFI_DEVICE_PATH_PROTOCOL DevicePath;
|
||
+ ///
|
||
+
|
||
+ ///
|
||
+ /// Zero or more image signatures. If the image contained no signatures,
|
||
+ /// then this field is empty.
|
||
+ ///
|
||
+ ///EFI_SIGNATURE_LIST Signature;
|
||
+ UINT8 Data[];
|
||
+} EFI_IMAGE_EXECUTION_INFO;
|
||
+
|
||
+typedef struct {
|
||
+ ///
|
||
+ /// Number of EFI_IMAGE_EXECUTION_INFO structures.
|
||
+ ///
|
||
+ UINTN NumberOfImages;
|
||
+ ///
|
||
+ /// Number of image instances of EFI_IMAGE_EXECUTION_INFO structures.
|
||
+ ///
|
||
+ EFI_IMAGE_EXECUTION_INFO InformationInfo[];
|
||
+} EFI_IMAGE_EXECUTION_INFO_TABLE;
|
||
+
|
||
+
|
||
+void *
|
||
+configtable_get_table(EFI_GUID *guid);
|
||
+EFI_IMAGE_EXECUTION_INFO_TABLE *
|
||
+configtable_get_image_table(void);
|
||
+EFI_IMAGE_EXECUTION_INFO *
|
||
+configtable_find_image(const EFI_DEVICE_PATH *DevicePath);
|
||
+int
|
||
+configtable_image_is_forbidden(const EFI_DEVICE_PATH *DevicePath);
|
||
+
|
||
diff --git a/efitools/include/console.h b/efitools/include/console.h
|
||
new file mode 100644
|
||
index 0000000..5ab5d6b
|
||
--- /dev/null
|
||
+++ b/efitools/include/console.h
|
||
@@ -0,0 +1,21 @@
|
||
+EFI_INPUT_KEY
|
||
+console_get_keystroke(void);
|
||
+int
|
||
+console_check_for_keystroke(CHAR16 key);
|
||
+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);
|
||
+void
|
||
+console_reset(void);
|
||
+#define NOSEL 0x7fffffff
|
||
diff --git a/efitools/include/efiauthenticated.h b/efitools/include/efiauthenticated.h
|
||
new file mode 100644
|
||
index 0000000..f7d6bcb
|
||
--- /dev/null
|
||
+++ b/efitools/include/efiauthenticated.h
|
||
@@ -0,0 +1,222 @@
|
||
+#ifndef _INC_EFIAUTHENTICATED_H
|
||
+#define _INC_EFIAUTHENTICATED_H
|
||
+#include <wincert.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 } }
|
||
+
|
||
+///
|
||
+/// 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))
|
||
+
|
||
+///
|
||
+/// 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
|
||
+
|
||
+///
|
||
+/// 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;
|
||
+
|
||
+///
|
||
+/// 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
|
||
diff --git a/efitools/include/errors.h b/efitools/include/errors.h
|
||
new file mode 100644
|
||
index 0000000..0da4bb5
|
||
--- /dev/null
|
||
+++ b/efitools/include/errors.h
|
||
@@ -0,0 +1,9 @@
|
||
+#include <efierr.h>
|
||
+
|
||
+#ifndef EFI_INCOMPATIBLE_VERSION
|
||
+#define EFI_INCOMPATIBLE_VERSION EFIERR(25)
|
||
+#endif
|
||
+#ifndef EFI_SECURITY_VIOLATION
|
||
+#define EFI_SECURITY_VIOLATION EFIERR(26)
|
||
+#endif
|
||
+
|
||
diff --git a/efitools/include/execute.h b/efitools/include/execute.h
|
||
new file mode 100644
|
||
index 0000000..9aecbff
|
||
--- /dev/null
|
||
+++ b/efitools/include/execute.h
|
||
@@ -0,0 +1,5 @@
|
||
+EFI_STATUS
|
||
+generate_path(CHAR16* name, EFI_LOADED_IMAGE *li,
|
||
+ EFI_DEVICE_PATH **path, CHAR16 **PathName);
|
||
+EFI_STATUS
|
||
+execute(EFI_HANDLE image, CHAR16 *name);
|
||
diff --git a/efitools/include/guid.h b/efitools/include/guid.h
|
||
new file mode 100644
|
||
index 0000000..17aa6af
|
||
--- /dev/null
|
||
+++ b/efitools/include/guid.h
|
||
@@ -0,0 +1,19 @@
|
||
+#include <efi.h>
|
||
+
|
||
+#ifndef BUILD_EFI
|
||
+const char *guid_to_str(EFI_GUID *guid);
|
||
+int str_to_guid(const char *str, EFI_GUID *guid);
|
||
+int compare_guid(EFI_GUID *g1, EFI_GUID *g2);
|
||
+#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;
|
||
diff --git a/efitools/include/kernel_efivars.h b/efitools/include/kernel_efivars.h
|
||
new file mode 100644
|
||
index 0000000..1f5dfa0
|
||
--- /dev/null
|
||
+++ b/efitools/include/kernel_efivars.h
|
||
@@ -0,0 +1,26 @@
|
||
+#include <variables_iterators.h>
|
||
+#include <sha256.h>
|
||
+void
|
||
+kernel_variable_init(void);
|
||
+int
|
||
+get_variable(const char *var, EFI_GUID *guid, uint32_t *attributes,
|
||
+ uint32_t *size, void *buf);
|
||
+int
|
||
+get_variable_alloc(const char *var, EFI_GUID *guid, uint32_t *attributes,
|
||
+ uint32_t *size, uint8_t **buf);
|
||
+int
|
||
+variable_is_setupmode(void);
|
||
+int
|
||
+variable_is_secureboot(void);
|
||
+int
|
||
+set_variable(const char *var, EFI_GUID *guid, uint32_t attributes,
|
||
+ uint32_t size, void *buf);
|
||
+int
|
||
+set_variable_esl(const char *var, EFI_GUID *guid, uint32_t attributes,
|
||
+ uint32_t size, void *buf);
|
||
+int
|
||
+set_variable_hash(const char *var, EFI_GUID *owner, uint32_t attributes,
|
||
+ uint8_t hash[SHA256_DIGEST_SIZE]);
|
||
+uint8_t *
|
||
+hash_to_esl(EFI_GUID *owner, int *len,
|
||
+ uint8_t hash[SHA256_DIGEST_SIZE]);
|
||
diff --git a/efitools/include/pecoff.h b/efitools/include/pecoff.h
|
||
new file mode 100644
|
||
index 0000000..4265906
|
||
--- /dev/null
|
||
+++ b/efitools/include/pecoff.h
|
||
@@ -0,0 +1,23 @@
|
||
+#include <PeImage.h>
|
||
+
|
||
+EFI_STATUS
|
||
+pecoff_read_header(PE_COFF_LOADER_IMAGE_CONTEXT *context, void *data);
|
||
+EFI_STATUS
|
||
+pecoff_relocate(PE_COFF_LOADER_IMAGE_CONTEXT *context, void **data);
|
||
+EFI_STATUS
|
||
+pecoff_image_layout(PE_COFF_LOADER_IMAGE_CONTEXT *context, void **data);
|
||
+EFI_STATUS
|
||
+pecoff_execute_checked(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab,
|
||
+ CHAR16 *name);
|
||
+EFI_STATUS
|
||
+pecoff_execute_image(EFI_FILE *file, CHAR16 *name, EFI_HANDLE image,
|
||
+ EFI_SYSTEM_TABLE *systab);
|
||
+
|
||
+static inline void*
|
||
+pecoff_image_address(void *image, int size, unsigned int address)
|
||
+{
|
||
+ if (address > size)
|
||
+ return NULL;
|
||
+
|
||
+ return image + address;
|
||
+}
|
||
diff --git a/efitools/include/security_policy.h b/efitools/include/security_policy.h
|
||
new file mode 100644
|
||
index 0000000..a1c1002
|
||
--- /dev/null
|
||
+++ b/efitools/include/security_policy.h
|
||
@@ -0,0 +1,6 @@
|
||
+EFI_STATUS
|
||
+security_policy_install(void);
|
||
+EFI_STATUS
|
||
+security_policy_uninstall(void);
|
||
+void
|
||
+security_protocol_set_hashes(unsigned char *esl, int len);
|
||
diff --git a/efitools/include/sha256.h b/efitools/include/sha256.h
|
||
new file mode 100644
|
||
index 0000000..07c531d
|
||
--- /dev/null
|
||
+++ b/efitools/include/sha256.h
|
||
@@ -0,0 +1,33 @@
|
||
+#ifndef _SHA256_H
|
||
+#define _SHA256_H
|
||
+
|
||
+#ifndef uint8
|
||
+#define uint8 unsigned char
|
||
+#endif
|
||
+
|
||
+#ifndef uint32
|
||
+#define uint32 unsigned long int
|
||
+#endif
|
||
+
|
||
+#define SHA256_DIGEST_SIZE 32
|
||
+
|
||
+typedef struct
|
||
+{
|
||
+ uint32 total[2];
|
||
+ uint32 state[8];
|
||
+ uint8 buffer[64];
|
||
+}
|
||
+sha256_context;
|
||
+
|
||
+void sha256_starts( sha256_context *ctx );
|
||
+void sha256_update( sha256_context *ctx, uint8 *input, uint32 length );
|
||
+void sha256_finish( sha256_context *ctx, uint8 digest[32] );
|
||
+EFI_STATUS
|
||
+sha256_get_pecoff_digest_mem(void *buffer, UINTN DataSize,
|
||
+ UINT8 hash[SHA256_DIGEST_SIZE]);
|
||
+void
|
||
+sha256_StrCat_hash(CHAR16 *str, UINT8 hash[SHA256_DIGEST_SIZE]);
|
||
+EFI_STATUS
|
||
+sha256_get_pecoff_digest(EFI_HANDLE device, CHAR16 *name, uint8 digest[SHA256_DIGEST_SIZE]);
|
||
+#endif /* sha256.h */
|
||
+
|
||
diff --git a/efitools/include/shell.h b/efitools/include/shell.h
|
||
new file mode 100644
|
||
index 0000000..9cb5d47
|
||
--- /dev/null
|
||
+++ b/efitools/include/shell.h
|
||
@@ -0,0 +1,2 @@
|
||
+EFI_STATUS
|
||
+argsplit(EFI_HANDLE image, int *argc, CHAR16*** ARGV);
|
||
diff --git a/efitools/include/simple_file.h b/efitools/include/simple_file.h
|
||
new file mode 100644
|
||
index 0000000..fe4fd97
|
||
--- /dev/null
|
||
+++ b/efitools/include/simple_file.h
|
||
@@ -0,0 +1,21 @@
|
||
+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);
|
||
+EFI_STATUS
|
||
+simple_file_write_all(EFI_FILE *file, UINTN size, void *buffer);
|
||
+void
|
||
+simple_file_close(EFI_FILE *file);
|
||
+EFI_STATUS
|
||
+simple_dir_read_all(EFI_HANDLE image, CHAR16 *name, EFI_FILE_INFO **Entries,
|
||
+ int *count);
|
||
+EFI_STATUS
|
||
+simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
|
||
+ CHAR16 ***result, int *count, EFI_FILE_INFO **entries);
|
||
+void
|
||
+simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
+ CHAR16 *filter, CHAR16 **result);
|
||
+EFI_STATUS
|
||
+simple_volume_selector(CHAR16 **title, CHAR16 **selected, EFI_HANDLE *h);
|
||
diff --git a/efitools/include/variables.h b/efitools/include/variables.h
|
||
new file mode 100644
|
||
index 0000000..f14a320
|
||
--- /dev/null
|
||
+++ b/efitools/include/variables.h
|
||
@@ -0,0 +1,45 @@
|
||
+#include <efiauthenticated.h>
|
||
+
|
||
+#include <sha256.h> /* for SHA256_DIGEST_SIZE */
|
||
+#include <variables_iterators.h>
|
||
+
|
||
+EFI_STATUS
|
||
+CreatePkX509SignatureList (
|
||
+ IN UINT8 *X509Data,
|
||
+ IN UINTN X509DataSize,
|
||
+ IN EFI_GUID owner,
|
||
+ OUT EFI_SIGNATURE_LIST **PkCert
|
||
+ );
|
||
+EFI_STATUS
|
||
+CreateTimeBasedPayload (
|
||
+ IN OUT UINTN *DataSize,
|
||
+ IN OUT UINT8 **Data
|
||
+ );
|
||
+EFI_STATUS
|
||
+SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner, UINT32 options, int createtimebased);
|
||
+EFI_STATUS
|
||
+get_variable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner);
|
||
+EFI_STATUS
|
||
+get_variable_attr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
|
||
+ UINT32 *attributes);
|
||
+EFI_STATUS
|
||
+find_in_esl(UINT8 *Data, UINTN DataSize, UINT8 *key, UINTN keylen);
|
||
+EFI_STATUS
|
||
+find_in_variable_esl(CHAR16* var, EFI_GUID owner, UINT8 *key, UINTN keylen);
|
||
+
|
||
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
|
||
+
|
||
+UINT64
|
||
+GetOSIndications(void);
|
||
+EFI_STATUS
|
||
+SETOSIndicationsAndReboot(UINT64 indications);
|
||
+int
|
||
+variable_is_secureboot(void);
|
||
+int
|
||
+variable_is_setupmode(void);
|
||
+EFI_STATUS
|
||
+variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
|
||
+ UINT8 hash[SHA256_DIGEST_SIZE]);
|
||
+EFI_STATUS
|
||
+variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
|
||
+ void **out, int *outlen);
|
||
diff --git a/efitools/include/variables_iterators.h b/efitools/include/variables_iterators.h
|
||
new file mode 100644
|
||
index 0000000..fc2df0c
|
||
--- /dev/null
|
||
+++ b/efitools/include/variables_iterators.h
|
||
@@ -0,0 +1,16 @@
|
||
+
|
||
+#define certlist_for_each_certentry(cl, cl_init, s, s_init) \
|
||
+ for (cl = (EFI_SIGNATURE_LIST *)(cl_init), s = (s_init); \
|
||
+ s > 0 && s >= cl->SignatureListSize; \
|
||
+ s -= cl->SignatureListSize, \
|
||
+ cl = (EFI_SIGNATURE_LIST *) ((UINT8 *)cl + cl->SignatureListSize))
|
||
+
|
||
+/*
|
||
+ * Warning: this assumes (cl)->SignatureHeaderSize is zero. It is for all
|
||
+ * the signatures we process (X509, RSA2048, SHA256)
|
||
+ */
|
||
+#define certentry_for_each_cert(c, cl) \
|
||
+ for (c = (EFI_SIGNATURE_DATA *)((UINT8 *) (cl) + sizeof(EFI_SIGNATURE_LIST) + (cl)->SignatureHeaderSize); \
|
||
+ (UINT8 *)c < ((UINT8 *)(cl)) + (cl)->SignatureListSize; \
|
||
+ c = (EFI_SIGNATURE_DATA *)((UINT8 *)c + (cl)->SignatureSize))
|
||
+
|
||
diff --git a/efitools/include/version.h b/efitools/include/version.h
|
||
new file mode 100644
|
||
index 0000000..897bbc4
|
||
--- /dev/null
|
||
+++ b/efitools/include/version.h
|
||
@@ -0,0 +1,8 @@
|
||
+#define VERSION "1.4.1"
|
||
+
|
||
+static void
|
||
+version(const char *progname)
|
||
+{
|
||
+ printf("%s " VERSION "\n", progname);
|
||
+}
|
||
+
|
||
diff --git a/efitools/include/wincert.h b/efitools/include/wincert.h
|
||
new file mode 100644
|
||
index 0000000..68d1974
|
||
--- /dev/null
|
||
+++ b/efitools/include/wincert.h
|
||
@@ -0,0 +1,33 @@
|
||
+#ifndef _INC_WINCERT_H
|
||
+#define _INC_WINCERT_H
|
||
+
|
||
+///
|
||
+/// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
|
||
+///
|
||
+typedef struct {
|
||
+ ///
|
||
+ /// The length of the entire certificate,
|
||
+ /// including the length of the header, in bytes.
|
||
+ ///
|
||
+ UINT32 dwLength;
|
||
+ ///
|
||
+ /// The revision level of the WIN_CERTIFICATE
|
||
+ /// structure. The current revision level is 0x0200.
|
||
+ ///
|
||
+ UINT16 wRevision;
|
||
+ ///
|
||
+ /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI
|
||
+ /// certificate types. The UEFI specification reserves the range of
|
||
+ /// certificate type values from 0x0EF0 to 0x0EFF.
|
||
+ ///
|
||
+ UINT16 wCertificateType;
|
||
+ ///
|
||
+ /// The following is the actual certificate. The format of
|
||
+ /// the certificate depends on wCertificateType.
|
||
+ ///
|
||
+ /// UINT8 bCertificate[ANYSIZE_ARRAY];
|
||
+ ///
|
||
+} WIN_CERTIFICATE;
|
||
+
|
||
+
|
||
+#endif
|
||
diff --git a/efitools/include/x509.h b/efitools/include/x509.h
|
||
new file mode 100644
|
||
index 0000000..f072702
|
||
--- /dev/null
|
||
+++ b/efitools/include/x509.h
|
||
@@ -0,0 +1,23 @@
|
||
+#ifndef STR
|
||
+#define STR CHAR16
|
||
+#endif
|
||
+
|
||
+#define X509_OBJ_TBS_CERTIFICATE 1
|
||
+#define X509_OBJ_VERSION 3
|
||
+#define X509_OBJ_SERIAL_NUMBER 4
|
||
+#define X509_OBJ_SIG_ALG 5
|
||
+#define X509_OBJ_ISSUER 6
|
||
+#define X509_OBJ_NOT_BEFORE 8
|
||
+#define X509_OBJ_NOT_AFTER 9
|
||
+#define X509_OBJ_SUBJECT 10
|
||
+#define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
|
||
+#define X509_OBJ_OPTIONAL_EXTENSIONS 16
|
||
+#define X509_OBJ_EXTN_ID 19
|
||
+#define X509_OBJ_CRITICAL 20
|
||
+#define X509_OBJ_EXTN_VALUE 21
|
||
+#define X509_OBJ_ALGORITHM 24
|
||
+#define X509_OBJ_SIGNATURE 25
|
||
+
|
||
+int
|
||
+x509_to_str(void *cert, int cert_size, int tag,
|
||
+ STR *buf, int len);
|
||
diff --git a/efitools/lib/Makefile b/efitools/lib/Makefile
|
||
new file mode 100644
|
||
index 0000000..6cfe503
|
||
--- /dev/null
|
||
+++ b/efitools/lib/Makefile
|
||
@@ -0,0 +1,12 @@
|
||
+FILES = simple_file.o pecoff.o guid.o sha256.o console.o \
|
||
+ security_policy.o execute.o configtable.o shell.o
|
||
+EFILIBFILES = $(patsubst %.o,%.efi.o,$(FILES)) variables.o
|
||
+
|
||
+include ../Make.rules
|
||
+
|
||
+lib-efi.a: $(EFILIBFILES)
|
||
+
|
||
+clean:
|
||
+ rm -f lib-efi.a
|
||
+ rm -f $(EFILIBFILES)
|
||
+
|
||
diff --git a/efitools/lib/asn1/.gitignore b/efitools/lib/asn1/.gitignore
|
||
new file mode 100644
|
||
index 0000000..9daeafb
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/.gitignore
|
||
@@ -0,0 +1 @@
|
||
+test
|
||
diff --git a/efitools/lib/asn1/Makefile b/efitools/lib/asn1/Makefile
|
||
new file mode 100644
|
||
index 0000000..b683b50
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/Makefile
|
||
@@ -0,0 +1,11 @@
|
||
+LIBFILES = asn1.o asn1_parser.o enumerator.o chunk.o oid.o identification.o \
|
||
+ x509.o
|
||
+EFILIBFILES = $(patsubst %.o,%.efi.o,$(LIBFILES))
|
||
+
|
||
+include ../../Make.rules
|
||
+
|
||
+libasn1-efi.a: $(EFILIBFILES)
|
||
+
|
||
+clean:
|
||
+ rm -f libasn1-efi.a
|
||
+ rm -f $(EFILIBFILES)
|
||
diff --git a/efitools/lib/asn1/asn1.c b/efitools/lib/asn1/asn1.c
|
||
new file mode 100644
|
||
index 0000000..e28f467
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/asn1.c
|
||
@@ -0,0 +1,197 @@
|
||
+/*
|
||
+ * Copyright (C) 2006 Martin Will
|
||
+ * Copyright (C) 2000-2008 Andreas Steffen
|
||
+ *
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+#include "typedefs.h"
|
||
+#include "enumerator.h"
|
||
+#include "chunk.h"
|
||
+#include "oid.h"
|
||
+#include "asn1.h"
|
||
+#include "asn1_parser.h"
|
||
+
|
||
+/*
|
||
+ * Defined in header.
|
||
+ */
|
||
+int asn1_known_oid(chunk_t object)
|
||
+{
|
||
+ int oid = 0;
|
||
+
|
||
+ while (object.len)
|
||
+ {
|
||
+ if (oid_names[oid].octet == *object.ptr)
|
||
+ {
|
||
+ if (--object.len == 0 || oid_names[oid].down == 0)
|
||
+ {
|
||
+ return oid; /* found terminal symbol */
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ object.ptr++; oid++; /* advance to next hex octet */
|
||
+ }
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ if (oid_names[oid].next)
|
||
+ {
|
||
+ oid = oid_names[oid].next;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ return OID_UNKNOWN;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ return -1;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Defined in header.
|
||
+ */
|
||
+chunk_t asn1_build_known_oid(int n)
|
||
+{
|
||
+ chunk_t oid;
|
||
+ int i;
|
||
+
|
||
+ if (n < 0 || n >= OID_MAX)
|
||
+ {
|
||
+ return chunk_empty;
|
||
+ }
|
||
+
|
||
+ i = oid_names[n].level + 1;
|
||
+ oid = chunk_alloc(2 + i);
|
||
+ oid.ptr[0] = ASN1_OID;
|
||
+ oid.ptr[1] = i;
|
||
+
|
||
+ do
|
||
+ {
|
||
+ if (oid_names[n].level >= i)
|
||
+ {
|
||
+ n--;
|
||
+ continue;
|
||
+ }
|
||
+ oid.ptr[--i + 2] = oid_names[n--].octet;
|
||
+ }
|
||
+ while (i > 0);
|
||
+
|
||
+ return oid;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Defined in header.
|
||
+ */
|
||
+size_t asn1_length(chunk_t *blob)
|
||
+{
|
||
+ u_char n;
|
||
+ size_t len;
|
||
+
|
||
+ if (blob->len < 2)
|
||
+ {
|
||
+ DBG1("insufficient number of octets to parse ASN.1 length");
|
||
+ return ASN1_INVALID_LENGTH;
|
||
+ }
|
||
+
|
||
+ /* read length field, skip tag and length */
|
||
+ n = blob->ptr[1];
|
||
+ blob->ptr += 2;
|
||
+ blob->len -= 2;
|
||
+
|
||
+ if ((n & 0x80) == 0)
|
||
+ { /* single length octet */
|
||
+ if (n > blob->len)
|
||
+ {
|
||
+ DBG1("length is larger than remaining blob size");
|
||
+ return ASN1_INVALID_LENGTH;
|
||
+ }
|
||
+ return n;
|
||
+ }
|
||
+
|
||
+ /* composite length, determine number of length octets */
|
||
+ n &= 0x7f;
|
||
+
|
||
+ if (n == 0 || n > blob->len)
|
||
+ {
|
||
+ DBG1("number of length octets invalid");
|
||
+ return ASN1_INVALID_LENGTH;
|
||
+ }
|
||
+
|
||
+ if (n > sizeof(len))
|
||
+ {
|
||
+ DBG1("number of length octets is larger than limit of"
|
||
+ " %d octets", (int)sizeof(len));
|
||
+ return ASN1_INVALID_LENGTH;
|
||
+ }
|
||
+
|
||
+ len = 0;
|
||
+
|
||
+ while (n-- > 0)
|
||
+ {
|
||
+ len = 256*len + *blob->ptr++;
|
||
+ blob->len--;
|
||
+ }
|
||
+ if (len > blob->len)
|
||
+ {
|
||
+ DBG1("length is larger than remaining blob size");
|
||
+ return ASN1_INVALID_LENGTH;
|
||
+ }
|
||
+ return len;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * See header.
|
||
+ */
|
||
+int asn1_unwrap(chunk_t *blob, chunk_t *inner)
|
||
+{
|
||
+ chunk_t res;
|
||
+ u_char len;
|
||
+ int type;
|
||
+
|
||
+ if (blob->len < 2)
|
||
+ {
|
||
+ return ASN1_INVALID;
|
||
+ }
|
||
+ type = blob->ptr[0];
|
||
+ len = blob->ptr[1];
|
||
+ *blob = chunk_skip(*blob, 2);
|
||
+
|
||
+ if ((len & 0x80) == 0)
|
||
+ { /* single length octet */
|
||
+ res.len = len;
|
||
+ }
|
||
+ else
|
||
+ { /* composite length, determine number of length octets */
|
||
+ len &= 0x7f;
|
||
+ if (len == 0 || len > sizeof(res.len))
|
||
+ {
|
||
+ return ASN1_INVALID;
|
||
+ }
|
||
+ res.len = 0;
|
||
+ while (len-- > 0)
|
||
+ {
|
||
+ res.len = 256 * res.len + blob->ptr[0];
|
||
+ *blob = chunk_skip(*blob, 1);
|
||
+ }
|
||
+ }
|
||
+ if (res.len > blob->len)
|
||
+ {
|
||
+ return ASN1_INVALID;
|
||
+ }
|
||
+ res.ptr = blob->ptr;
|
||
+ *blob = chunk_skip(*blob, res.len);
|
||
+ /* updating inner not before we are finished allows a caller to pass
|
||
+ * blob = inner */
|
||
+ *inner = res;
|
||
+ return type;
|
||
+}
|
||
diff --git a/efitools/lib/asn1/asn1.h b/efitools/lib/asn1/asn1.h
|
||
new file mode 100644
|
||
index 0000000..97ae9bd
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/asn1.h
|
||
@@ -0,0 +1,115 @@
|
||
+/*
|
||
+ * Copyright (C) 2006 Martin Will
|
||
+ * Copyright (C) 2000-2008 Andreas Steffen
|
||
+ *
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+/**
|
||
+ * @defgroup asn1i asn1
|
||
+ * @{ @ingroup asn1
|
||
+ */
|
||
+
|
||
+#ifndef ASN1_H_
|
||
+#define ASN1_H_
|
||
+
|
||
+/**
|
||
+ * Definition of some primitive ASN1 types
|
||
+ */
|
||
+typedef enum {
|
||
+ ASN1_EOC = 0x00,
|
||
+ ASN1_BOOLEAN = 0x01,
|
||
+ ASN1_INTEGER = 0x02,
|
||
+ ASN1_BIT_STRING = 0x03,
|
||
+ ASN1_OCTET_STRING = 0x04,
|
||
+ ASN1_NULL = 0x05,
|
||
+ ASN1_OID = 0x06,
|
||
+ ASN1_ENUMERATED = 0x0A,
|
||
+ ASN1_UTF8STRING = 0x0C,
|
||
+ ASN1_NUMERICSTRING = 0x12,
|
||
+ ASN1_PRINTABLESTRING = 0x13,
|
||
+ ASN1_T61STRING = 0x14,
|
||
+ ASN1_VIDEOTEXSTRING = 0x15,
|
||
+ ASN1_IA5STRING = 0x16,
|
||
+ ASN1_UTCTIME = 0x17,
|
||
+ ASN1_GENERALIZEDTIME = 0x18,
|
||
+ ASN1_GRAPHICSTRING = 0x19,
|
||
+ ASN1_VISIBLESTRING = 0x1A,
|
||
+ ASN1_GENERALSTRING = 0x1B,
|
||
+ ASN1_UNIVERSALSTRING = 0x1C,
|
||
+ ASN1_BMPSTRING = 0x1E,
|
||
+
|
||
+ ASN1_CONSTRUCTED = 0x20,
|
||
+
|
||
+ ASN1_SEQUENCE = 0x30,
|
||
+ ASN1_SET = 0x31,
|
||
+
|
||
+ ASN1_CONTEXT_S_0 = 0x80,
|
||
+ ASN1_CONTEXT_S_1 = 0x81,
|
||
+ ASN1_CONTEXT_S_2 = 0x82,
|
||
+ ASN1_CONTEXT_S_3 = 0x83,
|
||
+ ASN1_CONTEXT_S_4 = 0x84,
|
||
+ ASN1_CONTEXT_S_5 = 0x85,
|
||
+ ASN1_CONTEXT_S_6 = 0x86,
|
||
+ ASN1_CONTEXT_S_7 = 0x87,
|
||
+ ASN1_CONTEXT_S_8 = 0x88,
|
||
+
|
||
+ ASN1_CONTEXT_C_0 = 0xA0,
|
||
+ ASN1_CONTEXT_C_1 = 0xA1,
|
||
+ ASN1_CONTEXT_C_2 = 0xA2,
|
||
+ ASN1_CONTEXT_C_3 = 0xA3,
|
||
+ ASN1_CONTEXT_C_4 = 0xA4,
|
||
+ ASN1_CONTEXT_C_5 = 0xA5,
|
||
+
|
||
+ ASN1_INVALID = 0x100,
|
||
+} asn1_t;
|
||
+
|
||
+#define ASN1_INVALID_LENGTH 0xffffffff
|
||
+
|
||
+/** Some ASN.1 analysis functions */
|
||
+
|
||
+/**
|
||
+ * Converts an ASN.1 OID into a known OID index
|
||
+ *
|
||
+ * @param object body of an OID
|
||
+ * @return index into the oid_names[] table or OID_UNKNOWN
|
||
+ */
|
||
+int asn1_known_oid(chunk_t object);
|
||
+
|
||
+/**
|
||
+ * Converts a known OID index to an ASN.1 OID
|
||
+ *
|
||
+ * @param n index into the oid_names[] table
|
||
+ * @return allocated OID chunk, chunk_empty if index out of range
|
||
+ */
|
||
+chunk_t asn1_build_known_oid(int n);
|
||
+
|
||
+/**
|
||
+ * Returns the length of an ASN.1 object
|
||
+ * The blob pointer is advanced past the tag length fields
|
||
+ *
|
||
+ * @param blob pointer to an ASN.1 coded blob
|
||
+ * @return length of ASN.1 object
|
||
+ */
|
||
+size_t asn1_length(chunk_t *blob);
|
||
+
|
||
+/**
|
||
+ * Unwrap the inner content of an ASN.1 type/length wrapped object.
|
||
+ *
|
||
+ * @param blob blob to parse header from, moved behind parsed content
|
||
+ * @param content inner content
|
||
+ * @return parsed type, ASN1_INVALID if length parsing failed
|
||
+ */
|
||
+int asn1_unwrap(chunk_t *blob, chunk_t *content);
|
||
+
|
||
+#endif /** ASN1_H_ @}*/
|
||
diff --git a/efitools/lib/asn1/asn1_parser.c b/efitools/lib/asn1/asn1_parser.c
|
||
new file mode 100644
|
||
index 0000000..ca3626a
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/asn1_parser.c
|
||
@@ -0,0 +1,286 @@
|
||
+/*
|
||
+ * Copyright (C) 2006 Martin Will
|
||
+ * Copyright (C) 2000-2008 Andreas Steffen
|
||
+ *
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+#include "typedefs.h"
|
||
+#include "chunk.h"
|
||
+#include "asn1.h"
|
||
+#include "asn1_parser.h"
|
||
+
|
||
+#define ASN1_MAX_LEVEL 10
|
||
+
|
||
+typedef struct private_asn1_parser_t private_asn1_parser_t;
|
||
+
|
||
+/**
|
||
+ * Private data of an asn1_cxt_t object.
|
||
+ */
|
||
+struct private_asn1_parser_t {
|
||
+ /**
|
||
+ * Public interface.
|
||
+ */
|
||
+ asn1_parser_t public;
|
||
+
|
||
+ /**
|
||
+ * Syntax definition of ASN.1 object
|
||
+ */
|
||
+ asn1Object_t const *objects;
|
||
+
|
||
+ /**
|
||
+ * Current syntax definition line
|
||
+ */
|
||
+ int line;
|
||
+
|
||
+ /**
|
||
+ * Current stat of the parsing operation
|
||
+ */
|
||
+ bool success;
|
||
+
|
||
+ /**
|
||
+ * Declare object data as private - use debug level 4 to log it
|
||
+ */
|
||
+ bool private;
|
||
+
|
||
+ /**
|
||
+ * Top-most type is implicit - ignore it
|
||
+ */
|
||
+ bool implicit;
|
||
+
|
||
+ /**
|
||
+ * Top-most parsing level - defaults to 0
|
||
+ */
|
||
+ u_int level0;
|
||
+
|
||
+ /**
|
||
+ * Jump back address for loops for each level
|
||
+ */
|
||
+ int loopAddr[ASN1_MAX_LEVEL + 1];
|
||
+
|
||
+ /**
|
||
+ * Current parsing pointer for each level
|
||
+ */
|
||
+ chunk_t blobs[ASN1_MAX_LEVEL + 2];
|
||
+};
|
||
+
|
||
+METHOD(asn1_parser_t, iterate, bool,
|
||
+ private_asn1_parser_t *this, int *objectID, chunk_t *object)
|
||
+{
|
||
+ chunk_t *blob, *blob1;
|
||
+ u_char *start_ptr;
|
||
+ u_int level;
|
||
+ asn1Object_t obj;
|
||
+
|
||
+ *object = chunk_empty;
|
||
+
|
||
+ /* Advance to the next object syntax definition line */
|
||
+ obj = this->objects[++(this->line)];
|
||
+
|
||
+ /* Terminate if the end of the object syntax definition has been reached */
|
||
+ if (obj.flags & ASN1_EXIT)
|
||
+ {
|
||
+ return FALSE;
|
||
+ }
|
||
+
|
||
+ if (obj.flags & ASN1_END) /* end of loop or option found */
|
||
+ {
|
||
+ if (this->loopAddr[obj.level] && this->blobs[obj.level+1].len > 0)
|
||
+ {
|
||
+ this->line = this->loopAddr[obj.level]; /* another iteration */
|
||
+ obj = this->objects[this->line];
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ this->loopAddr[obj.level] = 0; /* exit loop or option*/
|
||
+ goto end;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ level = this->level0 + obj.level;
|
||
+ blob = this->blobs + obj.level;
|
||
+ blob1 = blob + 1;
|
||
+ start_ptr = blob->ptr;
|
||
+
|
||
+ /* handle ASN.1 defaults values */
|
||
+ if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) )
|
||
+ {
|
||
+ /* field is missing */
|
||
+ DBG1("L%d - %a:", level, obj.name);
|
||
+ if (obj.type & ASN1_CONSTRUCTED)
|
||
+ {
|
||
+ this->line++ ; /* skip context-specific tag */
|
||
+ }
|
||
+ goto end;
|
||
+ }
|
||
+
|
||
+ /* handle ASN.1 options */
|
||
+
|
||
+ if ((obj.flags & ASN1_OPT)
|
||
+ && (blob->len == 0 || *start_ptr != obj.type))
|
||
+ {
|
||
+ /* advance to end of missing option field */
|
||
+ do
|
||
+ {
|
||
+ this->line++;
|
||
+ }
|
||
+ while (!((this->objects[this->line].flags & ASN1_END) &&
|
||
+ (this->objects[this->line].level == obj.level)));
|
||
+ goto end;
|
||
+ }
|
||
+
|
||
+ /* an ASN.1 object must possess at least a tag and length field */
|
||
+
|
||
+ if (blob->len < 2)
|
||
+ {
|
||
+ DBG1("L%d - %a: ASN.1 object smaller than 2 octets",
|
||
+ level, obj.name);
|
||
+ this->success = FALSE;
|
||
+ goto end;
|
||
+ }
|
||
+
|
||
+ blob1->len = asn1_length(blob);
|
||
+
|
||
+ if (blob1->len == ASN1_INVALID_LENGTH)
|
||
+ {
|
||
+ DBG1("L%d - %a: length of ASN.1 object invalid or too large",
|
||
+ level, obj.name);
|
||
+ this->success = FALSE;
|
||
+ }
|
||
+
|
||
+ blob1->ptr = blob->ptr;
|
||
+ blob->ptr += blob1->len;
|
||
+ blob->len -= blob1->len;
|
||
+
|
||
+ /* return raw ASN.1 object without prior type checking */
|
||
+
|
||
+ if (obj.flags & ASN1_RAW)
|
||
+ {
|
||
+ DBG1("L%d - %a:", level, obj.name);
|
||
+ object->ptr = start_ptr;
|
||
+ object->len = (size_t)(blob->ptr - start_ptr);
|
||
+ goto end;
|
||
+ }
|
||
+
|
||
+ if (*start_ptr != obj.type && !(this->implicit && this->line == 0))
|
||
+ {
|
||
+ DBG1("L%d - %a: ASN1 tag 0x%02x expected, but is 0x%02x",
|
||
+ level, obj.name, obj.type, *start_ptr);
|
||
+ DBG1("%b", start_ptr, (u_int)(blob->ptr - start_ptr));
|
||
+ this->success = FALSE;
|
||
+ goto end;
|
||
+ }
|
||
+
|
||
+ DBG1("L%d - %a:", level, obj.name);
|
||
+
|
||
+ /* In case of "SEQUENCE OF" or "SET OF" start a loop */
|
||
+ if (obj.flags & ASN1_LOOP)
|
||
+ {
|
||
+ if (blob1->len > 0)
|
||
+ {
|
||
+ /* at least one item, start the loop */
|
||
+ this->loopAddr[obj.level] = this->line + 1;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* no items, advance directly to end of loop */
|
||
+ do
|
||
+ {
|
||
+ this->line++;
|
||
+ }
|
||
+ while (!((this->objects[this->line].flags & ASN1_END) &&
|
||
+ (this->objects[this->line].level == obj.level)));
|
||
+ goto end;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (obj.flags & ASN1_OBJ)
|
||
+ {
|
||
+ object->ptr = start_ptr;
|
||
+ object->len = (size_t)(blob->ptr - start_ptr);
|
||
+ if (this->private)
|
||
+ {
|
||
+ DBG1("%B", object);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ DBG1("%B", object);
|
||
+ }
|
||
+ }
|
||
+ else if (obj.flags & ASN1_BODY)
|
||
+ {
|
||
+ *object = *blob1;
|
||
+ }
|
||
+
|
||
+end:
|
||
+ *objectID = this->line;
|
||
+ return this->success;
|
||
+}
|
||
+
|
||
+METHOD(asn1_parser_t, get_level, u_int,
|
||
+private_asn1_parser_t *this)
|
||
+{
|
||
+ return this->level0 + this->objects[this->line].level;
|
||
+}
|
||
+
|
||
+METHOD(asn1_parser_t, set_top_level, void,
|
||
+ private_asn1_parser_t *this, u_int level0)
|
||
+{
|
||
+ this->level0 = level0;
|
||
+}
|
||
+
|
||
+METHOD(asn1_parser_t, set_flags, void,
|
||
+ private_asn1_parser_t *this, bool implicit, bool private)
|
||
+{
|
||
+ this->implicit = implicit;
|
||
+ this->private = private;
|
||
+}
|
||
+
|
||
+METHOD(asn1_parser_t, success, bool,
|
||
+ private_asn1_parser_t *this)
|
||
+{
|
||
+ return this->success;
|
||
+}
|
||
+
|
||
+METHOD(asn1_parser_t, destroy, void,
|
||
+ private_asn1_parser_t *this)
|
||
+{
|
||
+ free(this);
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Defined in header.
|
||
+ */
|
||
+asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob)
|
||
+{
|
||
+ private_asn1_parser_t *this;
|
||
+
|
||
+ this = malloc(sizeof(*this));
|
||
+
|
||
+ *this = (private_asn1_parser_t) {
|
||
+ .public = {
|
||
+ .iterate = _iterate,
|
||
+ .get_level = _get_level,
|
||
+ .set_top_level = _set_top_level,
|
||
+ .set_flags = _set_flags,
|
||
+ .success = _success,
|
||
+ .destroy = _destroy,
|
||
+ },
|
||
+ .objects = objects,
|
||
+ .blobs[0] = blob,
|
||
+ .line = -1,
|
||
+ .success = TRUE,
|
||
+ };
|
||
+
|
||
+ return &this->public;
|
||
+}
|
||
diff --git a/efitools/lib/asn1/asn1_parser.h b/efitools/lib/asn1/asn1_parser.h
|
||
new file mode 100644
|
||
index 0000000..4b5320f
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/asn1_parser.h
|
||
@@ -0,0 +1,117 @@
|
||
+/*
|
||
+ * Copyright (C) 2006 Martin Will
|
||
+ * Copyright (C) 2000-2008 Andreas Steffen
|
||
+ *
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+/**
|
||
+ * @defgroup asn1_parser asn1_parser
|
||
+ * @{ @ingroup asn1
|
||
+ */
|
||
+
|
||
+#ifndef ASN1_PARSER_H_
|
||
+#define ASN1_PARSER_H_
|
||
+
|
||
+#include <stdarg.h>
|
||
+
|
||
+#include "asn1.h"
|
||
+
|
||
+/**
|
||
+ * Definition of ASN.1 flags
|
||
+ */
|
||
+#define ASN1_NONE 0x00
|
||
+#define ASN1_DEF 0x01
|
||
+#define ASN1_OPT 0x02
|
||
+#define ASN1_LOOP 0x04
|
||
+#define ASN1_END 0x08
|
||
+#define ASN1_OBJ 0x10
|
||
+#define ASN1_BODY 0x20
|
||
+#define ASN1_RAW 0x40
|
||
+#define ASN1_EXIT 0x80
|
||
+
|
||
+typedef struct asn1Object_t asn1Object_t;
|
||
+
|
||
+/**
|
||
+ * Syntax definition of an ASN.1 object
|
||
+ */
|
||
+struct asn1Object_t{
|
||
+ u_int level;
|
||
+ const u_char *name;
|
||
+ asn1_t type;
|
||
+ u_char flags;
|
||
+};
|
||
+
|
||
+typedef struct asn1_parser_t asn1_parser_t;
|
||
+
|
||
+/**
|
||
+ * Public interface of an ASN.1 parser
|
||
+ */
|
||
+struct asn1_parser_t {
|
||
+
|
||
+ /**
|
||
+ * Parse the next ASN.1 object in the hierarchy and return it
|
||
+ *
|
||
+ * @param objectID current line in the object syntax definition
|
||
+ * @param object current object
|
||
+ * @return - FALSE if end of object syntax definition was reached
|
||
+ * or a parsing error occurred
|
||
+ * - TRUE otherwise
|
||
+ */
|
||
+ bool (*iterate)(asn1_parser_t *this, int *objectID, chunk_t *object);
|
||
+
|
||
+ /**
|
||
+ * Get the current parsing level
|
||
+ *
|
||
+ * @return current level
|
||
+ */
|
||
+ u_int (*get_level)(asn1_parser_t *this);
|
||
+
|
||
+ /**
|
||
+ * Set the top-most level
|
||
+ *
|
||
+ * @param level top-most level
|
||
+ */
|
||
+ void (*set_top_level)(asn1_parser_t *this, u_int level0);
|
||
+
|
||
+ /**
|
||
+ * Set implicit and private flags
|
||
+ *
|
||
+ * @param implicit top-most type of object is implicit
|
||
+ * @param private object data is private (use debug level 4)
|
||
+ */
|
||
+ void (*set_flags)(asn1_parser_t *this, bool implicit, bool private);
|
||
+
|
||
+ /**
|
||
+ * Show final parsing status
|
||
+ *
|
||
+ * @return TRUE if parsing was successful, FALSE otherwise
|
||
+ */
|
||
+ bool (*success)(asn1_parser_t *this);
|
||
+
|
||
+ /**
|
||
+ * Destroy the ASN.1 parser
|
||
+ */
|
||
+ void (*destroy)(asn1_parser_t *this);
|
||
+};
|
||
+
|
||
+/**
|
||
+ * Create an ASN.1 parser
|
||
+ *
|
||
+ * @param objects syntax definition of the ASN.1 object to be parsed
|
||
+ * @param blob ASN.1 coded binary blob
|
||
+ * @return ASN.1 context
|
||
+ */
|
||
+asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob);
|
||
+
|
||
+#endif /** ASN1_PARSER_H_ @}*/
|
||
diff --git a/efitools/lib/asn1/chunk.c b/efitools/lib/asn1/chunk.c
|
||
new file mode 100644
|
||
index 0000000..38baf07
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/chunk.c
|
||
@@ -0,0 +1,83 @@
|
||
+/*
|
||
+ * Copyright (C) 2008-2009 Tobias Brunner
|
||
+ * Copyright (C) 2005-2006 Martin Willi
|
||
+ * Copyright (C) 2005 Jan Hutter
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+#include "typedefs.h"
|
||
+#include "chunk.h"
|
||
+
|
||
+/**
|
||
+ * Empty chunk.
|
||
+ */
|
||
+chunk_t chunk_empty = { NULL, 0 };
|
||
+
|
||
+ /**
|
||
+ * Described in header.
|
||
+ */
|
||
+chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk)
|
||
+{
|
||
+ chunk_t clone = chunk_empty;
|
||
+
|
||
+ if (chunk.ptr && chunk.len > 0)
|
||
+ {
|
||
+ clone.ptr = ptr;
|
||
+ clone.len = chunk.len;
|
||
+ memcpy(clone.ptr, chunk.ptr, chunk.len);
|
||
+ }
|
||
+
|
||
+ return clone;
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Described in header.
|
||
+ */
|
||
+int chunk_compare(chunk_t a, chunk_t b)
|
||
+{
|
||
+ int compare_len = a.len - b.len;
|
||
+ int len = (compare_len < 0)? a.len : b.len;
|
||
+
|
||
+ if (compare_len != 0 || len == 0)
|
||
+ {
|
||
+ return compare_len;
|
||
+ }
|
||
+ return memcmp(a.ptr, b.ptr, len);
|
||
+};
|
||
+
|
||
+
|
||
+/**
|
||
+ * Remove non-printable characters from a chunk.
|
||
+ */
|
||
+bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace)
|
||
+{
|
||
+ bool printable = TRUE;
|
||
+ int i;
|
||
+
|
||
+ if (sane)
|
||
+ {
|
||
+ *sane = chunk_clone(chunk);
|
||
+ }
|
||
+ for (i = 0; i < chunk.len; i++)
|
||
+ {
|
||
+ if (!isprint(chunk.ptr[i]))
|
||
+ {
|
||
+ if (sane)
|
||
+ {
|
||
+ sane->ptr[i] = replace;
|
||
+ }
|
||
+ printable = FALSE;
|
||
+ }
|
||
+ }
|
||
+ return printable;
|
||
+}
|
||
diff --git a/efitools/lib/asn1/chunk.h b/efitools/lib/asn1/chunk.h
|
||
new file mode 100644
|
||
index 0000000..c375e79
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/chunk.h
|
||
@@ -0,0 +1,164 @@
|
||
+/*
|
||
+ * Copyright (C) 2008-2009 Tobias Brunner
|
||
+ * Copyright (C) 2005-2008 Martin Willi
|
||
+ * Copyright (C) 2005 Jan Hutter
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+/**
|
||
+ * @defgroup chunk chunk
|
||
+ * @{ @ingroup libstrongswan
|
||
+ */
|
||
+
|
||
+#ifndef CHUNK_H_
|
||
+#define CHUNK_H_
|
||
+
|
||
+typedef struct chunk_t chunk_t;
|
||
+
|
||
+/**
|
||
+ * General purpose pointer/length abstraction.
|
||
+ */
|
||
+struct chunk_t {
|
||
+ /** Pointer to start of data */
|
||
+ u_char *ptr;
|
||
+ /** Length of data in bytes */
|
||
+ size_t len;
|
||
+};
|
||
+
|
||
+/**
|
||
+ * A { NULL, 0 }-chunk handy for initialization.
|
||
+ */
|
||
+extern chunk_t chunk_empty;
|
||
+
|
||
+/**
|
||
+ * Create a new chunk pointing to "ptr" with length "len"
|
||
+ */
|
||
+static inline chunk_t chunk_create(u_char *ptr, size_t len)
|
||
+{
|
||
+ chunk_t chunk = {ptr, len};
|
||
+ return chunk;
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Free contents of a chunk
|
||
+ */
|
||
+static inline void chunk_free(chunk_t *chunk)
|
||
+{
|
||
+ free(chunk->ptr);
|
||
+ *chunk = chunk_empty;
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Overwrite the contents of a chunk and free it
|
||
+ */
|
||
+static inline void chunk_clear(chunk_t *chunk)
|
||
+{
|
||
+ if (chunk->ptr)
|
||
+ {
|
||
+ memset(chunk->ptr, 0, chunk->len);
|
||
+ chunk_free(chunk);
|
||
+ }
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Initialize a chunk using a char array
|
||
+ */
|
||
+#define chunk_from_chars(...) ((chunk_t){(char[]){__VA_ARGS__}, sizeof((char[]){__VA_ARGS__})})
|
||
+
|
||
+/**
|
||
+ * Initialize a chunk to point to a thing
|
||
+ */
|
||
+#define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing))
|
||
+
|
||
+/**
|
||
+ * Allocate a chunk on the heap
|
||
+ */
|
||
+#define chunk_alloc(bytes) ({size_t x = (bytes); chunk_create(x ? malloc(x) : NULL, x);})
|
||
+
|
||
+/**
|
||
+ * Allocate a chunk on the stack
|
||
+ */
|
||
+#define chunk_alloca(bytes) ({size_t x = (bytes); chunk_create(x ? alloca(x) : NULL, x);})
|
||
+
|
||
+/**
|
||
+ * Clone a chunk on heap
|
||
+ */
|
||
+#define chunk_clone(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? malloc(x.len) : NULL, x);})
|
||
+
|
||
+/**
|
||
+ * Skip n bytes in chunk (forward pointer, shorten length)
|
||
+ */
|
||
+static inline chunk_t chunk_skip(chunk_t chunk, size_t bytes)
|
||
+{
|
||
+ if (chunk.len > bytes)
|
||
+ {
|
||
+ chunk.ptr += bytes;
|
||
+ chunk.len -= bytes;
|
||
+ return chunk;
|
||
+ }
|
||
+ return chunk_empty;
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Skip a leading zero-valued byte
|
||
+ */
|
||
+static inline chunk_t chunk_skip_zero(chunk_t chunk)
|
||
+{
|
||
+ if (chunk.len > 1 && *chunk.ptr == 0x00)
|
||
+ {
|
||
+ chunk.ptr++;
|
||
+ chunk.len--;
|
||
+ }
|
||
+ return chunk;
|
||
+}
|
||
+
|
||
+
|
||
+/**
|
||
+ * Compare two chunks, returns zero if a equals b
|
||
+ * or negative/positive if a is small/greater than b
|
||
+ */
|
||
+int chunk_compare(chunk_t a, chunk_t b);
|
||
+
|
||
+/**
|
||
+ * Compare two chunks for equality,
|
||
+ * NULL chunks are never equal.
|
||
+ */
|
||
+static inline bool chunk_equals(chunk_t a, chunk_t b)
|
||
+{
|
||
+ return a.ptr != NULL && b.ptr != NULL &&
|
||
+ a.len == b.len && memeq(a.ptr, b.ptr, a.len);
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Compare two chunks (given as pointers) for equality (useful as callback),
|
||
+ * NULL chunks are never equal.
|
||
+ */
|
||
+static inline bool chunk_equals_ptr(chunk_t *a, chunk_t *b)
|
||
+{
|
||
+ return a != NULL && b != NULL && chunk_equals(*a, *b);
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Check if a chunk has printable characters only.
|
||
+ *
|
||
+ * If sane is given, chunk is cloned into sane and all non printable characters
|
||
+ * get replaced by "replace".
|
||
+ *
|
||
+ * @param chunk chunk to check for printability
|
||
+ * @param sane pointer where sane version is allocated, or NULL
|
||
+ * @param replace character to use for replaceing unprintable characters
|
||
+ * @return TRUE if all characters in chunk are printable
|
||
+ */
|
||
+bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace);
|
||
+
|
||
+#endif
|
||
diff --git a/efitools/lib/asn1/enumerator.c b/efitools/lib/asn1/enumerator.c
|
||
new file mode 100644
|
||
index 0000000..ac716db
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/enumerator.c
|
||
@@ -0,0 +1,37 @@
|
||
+/*
|
||
+ * Copyright (C) 2008 Tobias Brunner
|
||
+ * Copyright (C) 2007 Martin Willi
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+#include "typedefs.h"
|
||
+#include "enumerator.h"
|
||
+
|
||
+/**
|
||
+ * Implementation of enumerator_create_empty().enumerate
|
||
+ */
|
||
+static bool enumerate_empty(enumerator_t *enumerator, ...)
|
||
+{
|
||
+ return FALSE;
|
||
+}
|
||
+
|
||
+/**
|
||
+ * See header
|
||
+ */
|
||
+enumerator_t* enumerator_create_empty(void)
|
||
+{
|
||
+ enumerator_t *this = malloc_thing(enumerator_t);
|
||
+ this->enumerate = enumerate_empty;
|
||
+ this->destroy = (void*)free;
|
||
+ return this;
|
||
+}
|
||
diff --git a/efitools/lib/asn1/enumerator.h b/efitools/lib/asn1/enumerator.h
|
||
new file mode 100644
|
||
index 0000000..a09edec
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/enumerator.h
|
||
@@ -0,0 +1,55 @@
|
||
+/*
|
||
+ * Copyright (C) 2007 Martin Willi
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+/**
|
||
+ * @defgroup enumerator enumerator
|
||
+ * @{ @ingroup utils
|
||
+ */
|
||
+
|
||
+#ifndef ENUMERATOR_H_
|
||
+#define ENUMERATOR_H_
|
||
+
|
||
+typedef struct enumerator_t enumerator_t;
|
||
+
|
||
+/**
|
||
+ * Enumerator interface, allows enumeration over collections.
|
||
+ */
|
||
+struct enumerator_t {
|
||
+
|
||
+ /**
|
||
+ * Enumerate collection.
|
||
+ *
|
||
+ * The enumerate function takes a variable argument list containing
|
||
+ * pointers where the enumerated values get written.
|
||
+ *
|
||
+ * @param ... variable list of enumerated items, implementation dependent
|
||
+ * @return TRUE if pointers returned
|
||
+ */
|
||
+ bool (*enumerate)(enumerator_t *this, ...);
|
||
+
|
||
+ /**
|
||
+ * Destroy a enumerator instance.
|
||
+ */
|
||
+ void (*destroy)(enumerator_t *this);
|
||
+};
|
||
+
|
||
+/**
|
||
+ * Create an enumerator which enumerates over nothing
|
||
+ *
|
||
+ * @return an enumerator over no values
|
||
+ */
|
||
+enumerator_t* enumerator_create_empty();
|
||
+
|
||
+#endif /** ENUMERATOR_H_ @}*/
|
||
diff --git a/efitools/lib/asn1/identification.c b/efitools/lib/asn1/identification.c
|
||
new file mode 100644
|
||
index 0000000..73cc96b
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/identification.c
|
||
@@ -0,0 +1,226 @@
|
||
+/*
|
||
+ * Copyright (C) 2009-2012 Tobias Brunner
|
||
+ * Copyright (C) 2005-2009 Martin Willi
|
||
+ * Copyright (C) 2005 Jan Hutter
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+#include "typedefs.h"
|
||
+#include "identification.h"
|
||
+
|
||
+#include "oid.h"
|
||
+#include "asn1.h"
|
||
+
|
||
+/**
|
||
+ * coding of X.501 distinguished name
|
||
+ */
|
||
+typedef struct {
|
||
+ const u_char *name;
|
||
+ int oid;
|
||
+ u_char type;
|
||
+} x501rdn_t;
|
||
+
|
||
+static const x501rdn_t x501rdns[] = {
|
||
+ {"ND", OID_NAME_DISTINGUISHER, ASN1_PRINTABLESTRING},
|
||
+ {"UID", OID_PILOT_USERID, ASN1_PRINTABLESTRING},
|
||
+ {"DC", OID_PILOT_DOMAIN_COMPONENT, ASN1_PRINTABLESTRING},
|
||
+ {"CN", OID_COMMON_NAME, ASN1_PRINTABLESTRING},
|
||
+ {"S", OID_SURNAME, ASN1_PRINTABLESTRING},
|
||
+ {"SN", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
|
||
+ {"serialNumber", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
|
||
+ {"C", OID_COUNTRY, ASN1_PRINTABLESTRING},
|
||
+ {"L", OID_LOCALITY, ASN1_PRINTABLESTRING},
|
||
+ {"ST", OID_STATE_OR_PROVINCE, ASN1_PRINTABLESTRING},
|
||
+ {"O", OID_ORGANIZATION, ASN1_PRINTABLESTRING},
|
||
+ {"OU", OID_ORGANIZATION_UNIT, ASN1_PRINTABLESTRING},
|
||
+ {"T", OID_TITLE, ASN1_PRINTABLESTRING},
|
||
+ {"D", OID_DESCRIPTION, ASN1_PRINTABLESTRING},
|
||
+ {"N", OID_NAME, ASN1_PRINTABLESTRING},
|
||
+ {"G", OID_GIVEN_NAME, ASN1_PRINTABLESTRING},
|
||
+ {"I", OID_INITIALS, ASN1_PRINTABLESTRING},
|
||
+ {"dnQualifier", OID_DN_QUALIFIER, ASN1_PRINTABLESTRING},
|
||
+ {"ID", OID_UNIQUE_IDENTIFIER, ASN1_PRINTABLESTRING},
|
||
+ {"EN", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
|
||
+ {"employeeNumber", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
|
||
+ {"E", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
|
||
+ {"Email", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
|
||
+ {"emailAddress", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
|
||
+ {"UN", OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
|
||
+ {"unstructuredName", OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
|
||
+ {"UA", OID_UNSTRUCTURED_ADDRESS, ASN1_PRINTABLESTRING},
|
||
+ {"unstructuredAddress", OID_UNSTRUCTURED_ADDRESS, ASN1_PRINTABLESTRING},
|
||
+ {"TCGID", OID_TCGID, ASN1_PRINTABLESTRING}
|
||
+};
|
||
+
|
||
+/**
|
||
+ * maximum number of RDNs in atodn()
|
||
+ */
|
||
+#define RDN_MAX 20
|
||
+
|
||
+
|
||
+typedef struct private_identification_t private_identification_t;
|
||
+
|
||
+/**
|
||
+ * Private data of an identification_t object.
|
||
+ */
|
||
+struct private_identification_t {
|
||
+ /**
|
||
+ * Public interface.
|
||
+ */
|
||
+ identification_t public;
|
||
+
|
||
+ /**
|
||
+ * Encoded representation of this ID.
|
||
+ */
|
||
+ chunk_t encoded;
|
||
+
|
||
+ /**
|
||
+ * Type of this ID.
|
||
+ */
|
||
+ id_type_t type;
|
||
+};
|
||
+
|
||
+/**
|
||
+ * Enumerator over RDNs
|
||
+ */
|
||
+typedef struct {
|
||
+ /* implements enumerator interface */
|
||
+ enumerator_t public;
|
||
+ /* next set to parse, if any */
|
||
+ chunk_t sets;
|
||
+ /* next sequence in set, if any */
|
||
+ chunk_t seqs;
|
||
+} rdn_enumerator_t;
|
||
+
|
||
+METHOD(enumerator_t, rdn_enumerate, bool,
|
||
+ rdn_enumerator_t *this, chunk_t *oid, u_char *type, chunk_t *data)
|
||
+{
|
||
+ chunk_t rdn;
|
||
+
|
||
+ /* a DN contains one or more SET, each containing one or more SEQUENCES,
|
||
+ * each containing a OID/value RDN */
|
||
+ if (!this->seqs.len)
|
||
+ {
|
||
+ /* no SEQUENCEs in current SET, parse next SET */
|
||
+ if (asn1_unwrap(&this->sets, &this->seqs) != ASN1_SET)
|
||
+ {
|
||
+ return FALSE;
|
||
+ }
|
||
+ }
|
||
+ if (asn1_unwrap(&this->seqs, &rdn) == ASN1_SEQUENCE &&
|
||
+ asn1_unwrap(&rdn, oid) == ASN1_OID)
|
||
+ {
|
||
+ int t = asn1_unwrap(&rdn, data);
|
||
+
|
||
+ if (t != ASN1_INVALID)
|
||
+ {
|
||
+ *type = t;
|
||
+ return TRUE;
|
||
+ }
|
||
+ }
|
||
+ return FALSE;
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Create an enumerator over all RDNs (oid, string type, data) of a DN
|
||
+ */
|
||
+static enumerator_t* create_rdn_enumerator(chunk_t dn)
|
||
+{
|
||
+ rdn_enumerator_t *e;
|
||
+
|
||
+ INIT(e,
|
||
+ .public = {
|
||
+ .enumerate = (void*)_rdn_enumerate,
|
||
+ .destroy = (void*)free,
|
||
+ },
|
||
+ );
|
||
+
|
||
+ /* a DN is a SEQUENCE, get the first SET of it */
|
||
+ if (asn1_unwrap(&dn, &e->sets) == ASN1_SEQUENCE)
|
||
+ {
|
||
+ e->seqs = chunk_empty;
|
||
+ return &e->public;
|
||
+ }
|
||
+ free(e);
|
||
+ return enumerator_create_empty();
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Print a DN with all its RDN in a buffer to present it to the user
|
||
+ */
|
||
+void dntoa(chunk_t dn, STR *buf, size_t len)
|
||
+{
|
||
+ enumerator_t *e;
|
||
+ chunk_t oid_data, data, printable;
|
||
+ u_char type;
|
||
+ int oid, written;
|
||
+ bool finished = FALSE, empty = TRUE;
|
||
+
|
||
+ e = create_rdn_enumerator(dn);
|
||
+ while (e->enumerate(e, &oid_data, &type, &data))
|
||
+ {
|
||
+ empty = FALSE;
|
||
+
|
||
+ oid = asn1_known_oid(oid_data);
|
||
+
|
||
+ if (oid == OID_UNKNOWN)
|
||
+ {
|
||
+ written = snprintf(buf, len, "UNKNOWN-OID=");
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ written = snprintf(buf, len,"%" STRA "=", oid_names[oid].name);
|
||
+ }
|
||
+ if (written < 0 || written >= len)
|
||
+ {
|
||
+ break;
|
||
+ }
|
||
+ buf += written;
|
||
+ len -= written;
|
||
+
|
||
+ chunk_printable(data, &printable, '?');
|
||
+ written = snprintf(buf, len, "%.*" STRA, (int)printable.len, printable.ptr);
|
||
+ chunk_free(&printable);
|
||
+ if (written < 0 || written >= len)
|
||
+ {
|
||
+ break;
|
||
+ }
|
||
+ buf += written;
|
||
+ len -= written;
|
||
+
|
||
+ if (data.ptr + data.len != dn.ptr + dn.len)
|
||
+ {
|
||
+ written = snprintf(buf, len, ", ");
|
||
+ if (written < 0 || written >= len)
|
||
+ {
|
||
+ break;
|
||
+ }
|
||
+ buf += written;
|
||
+ len -= written;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ finished = TRUE;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ if (empty)
|
||
+ {
|
||
+ snprintf(buf, len, "");
|
||
+ }
|
||
+ else if (!finished)
|
||
+ {
|
||
+ snprintf(buf, len, "(invalid ID_DER_ASN1_DN)");
|
||
+ }
|
||
+ e->destroy(e);
|
||
+}
|
||
diff --git a/efitools/lib/asn1/identification.h b/efitools/lib/asn1/identification.h
|
||
new file mode 100644
|
||
index 0000000..8231a63
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/identification.h
|
||
@@ -0,0 +1,285 @@
|
||
+/*
|
||
+ * Copyright (C) 2009 Tobias Brunner
|
||
+ * Copyright (C) 2005-2009 Martin Willi
|
||
+ * Copyright (C) 2005 Jan Hutter
|
||
+ * Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+ *
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+/**
|
||
+ * @defgroup identification identification
|
||
+ * @{ @ingroup utils
|
||
+ */
|
||
+
|
||
+
|
||
+#ifndef IDENTIFICATION_H_
|
||
+#define IDENTIFICATION_H_
|
||
+
|
||
+typedef enum id_type_t id_type_t;
|
||
+typedef struct identification_t identification_t;
|
||
+typedef enum id_match_t id_match_t;
|
||
+typedef enum id_part_t id_part_t;
|
||
+
|
||
+#include "chunk.h"
|
||
+#include "enumerator.h"
|
||
+
|
||
+/**
|
||
+ * Matches returned from identification_t.match
|
||
+ */
|
||
+enum id_match_t {
|
||
+ /* no match */
|
||
+ ID_MATCH_NONE = 0,
|
||
+ /* match to %any ID */
|
||
+ ID_MATCH_ANY = 1,
|
||
+ /* match with maximum allowed wildcards */
|
||
+ ID_MATCH_MAX_WILDCARDS = 2,
|
||
+ /* match with only one wildcard */
|
||
+ ID_MATCH_ONE_WILDCARD = 19,
|
||
+ /* perfect match, won't get better */
|
||
+ ID_MATCH_PERFECT = 20,
|
||
+};
|
||
+
|
||
+/**
|
||
+ * ID Types in a ID payload.
|
||
+ */
|
||
+enum id_type_t {
|
||
+
|
||
+ /**
|
||
+ * private type which matches any other id.
|
||
+ */
|
||
+ ID_ANY = 0,
|
||
+
|
||
+ /**
|
||
+ * ID data is a single four (4) octet IPv4 address.
|
||
+ */
|
||
+ ID_IPV4_ADDR = 1,
|
||
+
|
||
+ /**
|
||
+ * ID data is a fully-qualified domain name string.
|
||
+ * An example of a ID_FQDN is "example.com".
|
||
+ * The string MUST not contain any terminators (e.g., NULL, CR, etc.).
|
||
+ */
|
||
+ ID_FQDN = 2,
|
||
+
|
||
+ /**
|
||
+ * ID data is a fully-qualified RFC822 email address string.
|
||
+ * An example of an ID_RFC822_ADDR is "jsmith@example.com".
|
||
+ * The string MUST NOT contain any terminators.
|
||
+ */
|
||
+ ID_USER_FQDN = 3, /* IKEv1 only */
|
||
+ ID_RFC822_ADDR = 3, /* IKEv2 only */
|
||
+
|
||
+ /**
|
||
+ * ID data is an IPv4 subnet (IKEv1 only)
|
||
+ */
|
||
+ ID_IPV4_ADDR_SUBNET = 4,
|
||
+
|
||
+ /**
|
||
+ * ID data is a single sixteen (16) octet IPv6 address.
|
||
+ */
|
||
+ ID_IPV6_ADDR = 5,
|
||
+
|
||
+ /**
|
||
+ * ID data is an IPv6 subnet (IKEv1 only)
|
||
+ */
|
||
+ ID_IPV6_ADDR_SUBNET = 6,
|
||
+
|
||
+ /**
|
||
+ * ID data is an IPv4 address range (IKEv1 only)
|
||
+ */
|
||
+ ID_IPV4_ADDR_RANGE = 7,
|
||
+
|
||
+ /**
|
||
+ * ID data is an IPv6 address range (IKEv1 only)
|
||
+ */
|
||
+ ID_IPV6_ADDR_RANGE = 8,
|
||
+
|
||
+ /**
|
||
+ * ID data is the binary DER encoding of an ASN.1 X.501 Distinguished Name
|
||
+ */
|
||
+ ID_DER_ASN1_DN = 9,
|
||
+
|
||
+ /**
|
||
+ * ID data is the binary DER encoding of an ASN.1 X.509 GeneralName
|
||
+ */
|
||
+ ID_DER_ASN1_GN = 10,
|
||
+
|
||
+ /**
|
||
+ * ID data is an opaque octet stream which may be used to pass vendor-
|
||
+ * specific information necessary to do certain proprietary
|
||
+ * types of identification.
|
||
+ */
|
||
+ ID_KEY_ID = 11,
|
||
+
|
||
+ /**
|
||
+ * private type which represents a GeneralName of type URI
|
||
+ */
|
||
+ ID_DER_ASN1_GN_URI = 201,
|
||
+
|
||
+ /**
|
||
+ * Private ID used by the pluto daemon for opportunistic encryption
|
||
+ */
|
||
+ ID_MYID = 203,
|
||
+};
|
||
+
|
||
+/**
|
||
+ * Type of an ID sub part.
|
||
+ */
|
||
+enum id_part_t {
|
||
+ /** Username part of an RFC822_ADDR */
|
||
+ ID_PART_USERNAME,
|
||
+ /** Domain part of an RFC822_ADDR */
|
||
+ ID_PART_DOMAIN,
|
||
+
|
||
+ /** Top-Level domain of a FQDN */
|
||
+ ID_PART_TLD,
|
||
+ /** Second-Level domain of a FQDN */
|
||
+ ID_PART_SLD,
|
||
+ /** Another Level domain of a FQDN */
|
||
+ ID_PART_ALD,
|
||
+
|
||
+ /** Country RDN of a DN */
|
||
+ ID_PART_RDN_C,
|
||
+ /** CommonName RDN of a DN */
|
||
+ ID_PART_RDN_CN,
|
||
+ /** Description RDN of a DN */
|
||
+ ID_PART_RDN_D,
|
||
+ /** Email RDN of a DN */
|
||
+ ID_PART_RDN_E,
|
||
+ /** EmployeeNumber RDN of a DN */
|
||
+ ID_PART_RDN_EN,
|
||
+ /** GivenName RDN of a DN */
|
||
+ ID_PART_RDN_G,
|
||
+ /** Initials RDN of a DN */
|
||
+ ID_PART_RDN_I,
|
||
+ /** DN Qualifier RDN of a DN */
|
||
+ ID_PART_RDN_DNQ,
|
||
+ /** UniqueIdentifier RDN of a DN */
|
||
+ ID_PART_RDN_ID,
|
||
+ /** Locality RDN of a DN */
|
||
+ ID_PART_RDN_L,
|
||
+ /** Name RDN of a DN */
|
||
+ ID_PART_RDN_N,
|
||
+ /** Organization RDN of a DN */
|
||
+ ID_PART_RDN_O,
|
||
+ /** OrganizationUnit RDN of a DN */
|
||
+ ID_PART_RDN_OU,
|
||
+ /** Surname RDN of a DN */
|
||
+ ID_PART_RDN_S,
|
||
+ /** SerialNumber RDN of a DN */
|
||
+ ID_PART_RDN_SN,
|
||
+ /** StateOrProvince RDN of a DN */
|
||
+ ID_PART_RDN_ST,
|
||
+ /** Title RDN of a DN */
|
||
+ ID_PART_RDN_T,
|
||
+};
|
||
+
|
||
+/**
|
||
+ * Generic identification, such as used in ID payload.
|
||
+ *
|
||
+ * @todo Support for ID_DER_ASN1_GN is minimal right now. Comparison
|
||
+ * between them and ID_IPV4_ADDR/RFC822_ADDR would be nice.
|
||
+ */
|
||
+struct identification_t {
|
||
+
|
||
+ /**
|
||
+ * Get the encoding of this id, to send over
|
||
+ * the network.
|
||
+ *
|
||
+ * Result points to internal data, do not free.
|
||
+ *
|
||
+ * @return a chunk containing the encoded bytes
|
||
+ */
|
||
+ chunk_t (*get_encoding) (identification_t *this);
|
||
+
|
||
+ /**
|
||
+ * Get the type of this identification.
|
||
+ *
|
||
+ * @return id_type_t
|
||
+ */
|
||
+ id_type_t (*get_type) (identification_t *this);
|
||
+
|
||
+ /**
|
||
+ * Check if two identification_t objects are equal.
|
||
+ *
|
||
+ * @param other other identification_t object
|
||
+ * @return TRUE if the IDs are equal
|
||
+ */
|
||
+ bool (*equals) (identification_t *this, identification_t *other);
|
||
+
|
||
+ /**
|
||
+ * Check if an ID matches a wildcard ID.
|
||
+ *
|
||
+ * An identification_t may contain wildcards, such as
|
||
+ * *.strongswan.org. This call checks if a given ID
|
||
+ * (e.g. tester.strongswan.org) belongs to a such wildcard
|
||
+ * ID. Returns > 0 if
|
||
+ * - IDs are identical
|
||
+ * - other is of type ID_ANY
|
||
+ * - other contains a wildcard and matches this
|
||
+ *
|
||
+ * The larger the return value is, the better is the match. Zero means
|
||
+ * no match at all, 1 means a bad match, and 2 a slightly better match.
|
||
+ *
|
||
+ * @param other the ID containing one or more wildcards
|
||
+ * @param wildcards returns the number of wildcards, may be NULL
|
||
+ * @return match value as described above
|
||
+ */
|
||
+ id_match_t (*matches) (identification_t *this, identification_t *other);
|
||
+
|
||
+ /**
|
||
+ * Check if an ID is a wildcard ID.
|
||
+ *
|
||
+ * If the ID represents multiple IDs (with wildcards, or
|
||
+ * as the type ID_ANY), TRUE is returned. If it is unique,
|
||
+ * FALSE is returned.
|
||
+ *
|
||
+ * @return TRUE if ID contains wildcards
|
||
+ */
|
||
+ bool (*contains_wildcards) (identification_t *this);
|
||
+
|
||
+ /**
|
||
+ * Create an enumerator over subparts of an identity.
|
||
+ *
|
||
+ * Some identities are built from several parts, e.g. an E-Mail consists
|
||
+ * of a username and a domain part, or a DistinguishedName contains several
|
||
+ * RDNs.
|
||
+ * For identity without subtypes (support), an empty enumerator is
|
||
+ * returned.
|
||
+ *
|
||
+ * @return an enumerator over (id_part_t type, chunk_t data)
|
||
+ */
|
||
+ enumerator_t* (*create_part_enumerator)(identification_t *this);
|
||
+
|
||
+ /**
|
||
+ * Clone a identification_t instance.
|
||
+ *
|
||
+ * @return clone of this
|
||
+ */
|
||
+ identification_t *(*clone) (identification_t *this);
|
||
+
|
||
+ /**
|
||
+ * Destroys a identification_t object.
|
||
+ */
|
||
+ void (*destroy) (identification_t *this);
|
||
+};
|
||
+
|
||
+/**
|
||
+ * creates an ascii representation of a DN
|
||
+ *
|
||
+ * @param dn chunk pointing to DN
|
||
+ * @param buf buffer to have string written to it
|
||
+ * @param len length of buf
|
||
+ */
|
||
+void dntoa(chunk_t dn, STR *buf, size_t len);
|
||
+
|
||
+#endif /** IDENTIFICATION_H_ @}*/
|
||
diff --git a/efitools/lib/asn1/oid.c b/efitools/lib/asn1/oid.c
|
||
new file mode 100644
|
||
index 0000000..b212996
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/oid.c
|
||
@@ -0,0 +1,390 @@
|
||
+/* List of some useful object identifiers (OIDs)
|
||
+ * Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * This file has been automatically generated by the script oid.pl
|
||
+ * Do not edit manually!
|
||
+ */
|
||
+
|
||
+#include <stdlib.h>
|
||
+
|
||
+#include "oid.h"
|
||
+
|
||
+const oid_t oid_names[] = {
|
||
+ {0x02, 7, 1, 0, "ITU-T Administration" }, /* 0 */
|
||
+ { 0x82, 0, 1, 1, "" }, /* 1 */
|
||
+ { 0x06, 0, 1, 2, "Germany ITU-T member" }, /* 2 */
|
||
+ { 0x01, 0, 1, 3, "Deutsche Telekom AG" }, /* 3 */
|
||
+ { 0x0A, 0, 1, 4, "" }, /* 4 */
|
||
+ { 0x07, 0, 1, 5, "" }, /* 5 */
|
||
+ { 0x14, 0, 0, 6, "ND" }, /* 6 */
|
||
+ {0x09, 18, 1, 0, "data" }, /* 7 */
|
||
+ { 0x92, 0, 1, 1, "" }, /* 8 */
|
||
+ { 0x26, 0, 1, 2, "" }, /* 9 */
|
||
+ { 0x89, 0, 1, 3, "" }, /* 10 */
|
||
+ { 0x93, 0, 1, 4, "" }, /* 11 */
|
||
+ { 0xF2, 0, 1, 5, "" }, /* 12 */
|
||
+ { 0x2C, 0, 1, 6, "" }, /* 13 */
|
||
+ { 0x64, 0, 1, 7, "pilot" }, /* 14 */
|
||
+ { 0x01, 0, 1, 8, "pilotAttributeType" }, /* 15 */
|
||
+ { 0x01, 17, 0, 9, "UID" }, /* 16 */
|
||
+ { 0x19, 0, 0, 9, "DC" }, /* 17 */
|
||
+ {0x55, 65, 1, 0, "X.500" }, /* 18 */
|
||
+ { 0x04, 37, 1, 1, "X.509" }, /* 19 */
|
||
+ { 0x03, 21, 0, 2, "CN" }, /* 20 */
|
||
+ { 0x04, 22, 0, 2, "S" }, /* 21 */
|
||
+ { 0x05, 23, 0, 2, "SN" }, /* 22 */
|
||
+ { 0x06, 24, 0, 2, "C" }, /* 23 */
|
||
+ { 0x07, 25, 0, 2, "L" }, /* 24 */
|
||
+ { 0x08, 26, 0, 2, "ST" }, /* 25 */
|
||
+ { 0x0A, 27, 0, 2, "O" }, /* 26 */
|
||
+ { 0x0B, 28, 0, 2, "OU" }, /* 27 */
|
||
+ { 0x0C, 29, 0, 2, "T" }, /* 28 */
|
||
+ { 0x0D, 30, 0, 2, "D" }, /* 29 */
|
||
+ { 0x24, 31, 0, 2, "userCertificate" }, /* 30 */
|
||
+ { 0x29, 32, 0, 2, "N" }, /* 31 */
|
||
+ { 0x2A, 33, 0, 2, "G" }, /* 32 */
|
||
+ { 0x2B, 34, 0, 2, "I" }, /* 33 */
|
||
+ { 0x2D, 35, 0, 2, "ID" }, /* 34 */
|
||
+ { 0x2E, 36, 0, 2, "dnQualifier" }, /* 35 */
|
||
+ { 0x48, 0, 0, 2, "role" }, /* 36 */
|
||
+ { 0x1D, 0, 1, 1, "id-ce" }, /* 37 */
|
||
+ { 0x09, 39, 0, 2, "subjectDirectoryAttrs" }, /* 38 */
|
||
+ { 0x0E, 40, 0, 2, "subjectKeyIdentifier" }, /* 39 */
|
||
+ { 0x0F, 41, 0, 2, "keyUsage" }, /* 40 */
|
||
+ { 0x10, 42, 0, 2, "privateKeyUsagePeriod" }, /* 41 */
|
||
+ { 0x11, 43, 0, 2, "subjectAltName" }, /* 42 */
|
||
+ { 0x12, 44, 0, 2, "issuerAltName" }, /* 43 */
|
||
+ { 0x13, 45, 0, 2, "basicConstraints" }, /* 44 */
|
||
+ { 0x14, 46, 0, 2, "crlNumber" }, /* 45 */
|
||
+ { 0x15, 47, 0, 2, "reasonCode" }, /* 46 */
|
||
+ { 0x17, 48, 0, 2, "holdInstructionCode" }, /* 47 */
|
||
+ { 0x18, 49, 0, 2, "invalidityDate" }, /* 48 */
|
||
+ { 0x1B, 50, 0, 2, "deltaCrlIndicator" }, /* 49 */
|
||
+ { 0x1C, 51, 0, 2, "issuingDistributionPoint" }, /* 50 */
|
||
+ { 0x1D, 52, 0, 2, "certificateIssuer" }, /* 51 */
|
||
+ { 0x1E, 53, 0, 2, "nameConstraints" }, /* 52 */
|
||
+ { 0x1F, 54, 0, 2, "crlDistributionPoints" }, /* 53 */
|
||
+ { 0x20, 56, 1, 2, "certificatePolicies" }, /* 54 */
|
||
+ { 0x00, 0, 0, 3, "anyPolicy" }, /* 55 */
|
||
+ { 0x21, 57, 0, 2, "policyMappings" }, /* 56 */
|
||
+ { 0x23, 58, 0, 2, "authorityKeyIdentifier" }, /* 57 */
|
||
+ { 0x24, 59, 0, 2, "policyConstraints" }, /* 58 */
|
||
+ { 0x25, 61, 1, 2, "extendedKeyUsage" }, /* 59 */
|
||
+ { 0x00, 0, 0, 3, "anyExtendedKeyUsage" }, /* 60 */
|
||
+ { 0x2E, 62, 0, 2, "freshestCRL" }, /* 61 */
|
||
+ { 0x36, 63, 0, 2, "inhibitAnyPolicy" }, /* 62 */
|
||
+ { 0x37, 64, 0, 2, "targetInformation" }, /* 63 */
|
||
+ { 0x38, 0, 0, 2, "noRevAvail" }, /* 64 */
|
||
+ {0x2A, 169, 1, 0, "" }, /* 65 */
|
||
+ { 0x83, 78, 1, 1, "" }, /* 66 */
|
||
+ { 0x08, 0, 1, 2, "jp" }, /* 67 */
|
||
+ { 0x8C, 0, 1, 3, "" }, /* 68 */
|
||
+ { 0x9A, 0, 1, 4, "" }, /* 69 */
|
||
+ { 0x4B, 0, 1, 5, "" }, /* 70 */
|
||
+ { 0x3D, 0, 1, 6, "" }, /* 71 */
|
||
+ { 0x01, 0, 1, 7, "security" }, /* 72 */
|
||
+ { 0x01, 0, 1, 8, "algorithm" }, /* 73 */
|
||
+ { 0x01, 0, 1, 9, "symm-encryption-alg" }, /* 74 */
|
||
+ { 0x02, 76, 0, 10, "camellia128-cbc" }, /* 75 */
|
||
+ { 0x03, 77, 0, 10, "camellia192-cbc" }, /* 76 */
|
||
+ { 0x04, 0, 0, 10, "camellia256-cbc" }, /* 77 */
|
||
+ { 0x86, 0, 1, 1, "" }, /* 78 */
|
||
+ { 0x48, 0, 1, 2, "us" }, /* 79 */
|
||
+ { 0x86, 128, 1, 3, "" }, /* 80 */
|
||
+ { 0xF6, 86, 1, 4, "" }, /* 81 */
|
||
+ { 0x7D, 0, 1, 5, "NortelNetworks" }, /* 82 */
|
||
+ { 0x07, 0, 1, 6, "Entrust" }, /* 83 */
|
||
+ { 0x41, 0, 1, 7, "nsn-ce" }, /* 84 */
|
||
+ { 0x00, 0, 0, 8, "entrustVersInfo" }, /* 85 */
|
||
+ { 0xF7, 0, 1, 4, "" }, /* 86 */
|
||
+ { 0x0D, 0, 1, 5, "RSADSI" }, /* 87 */
|
||
+ { 0x01, 123, 1, 6, "PKCS" }, /* 88 */
|
||
+ { 0x01, 100, 1, 7, "PKCS-1" }, /* 89 */
|
||
+ { 0x01, 91, 0, 8, "rsaEncryption" }, /* 90 */
|
||
+ { 0x02, 92, 0, 8, "md2WithRSAEncryption" }, /* 91 */
|
||
+ { 0x04, 93, 0, 8, "md5WithRSAEncryption" }, /* 92 */
|
||
+ { 0x05, 94, 0, 8, "sha-1WithRSAEncryption" }, /* 93 */
|
||
+ { 0x07, 95, 0, 8, "id-RSAES-OAEP" }, /* 94 */
|
||
+ { 0x09, 96, 0, 8, "id-pSpecified" }, /* 95 */
|
||
+ { 0x0B, 97, 0, 8, "sha256WithRSAEncryption" }, /* 96 */
|
||
+ { 0x0C, 98, 0, 8, "sha384WithRSAEncryption" }, /* 97 */
|
||
+ { 0x0D, 99, 0, 8, "sha512WithRSAEncryption" }, /* 98 */
|
||
+ { 0x0E, 0, 0, 8, "sha224WithRSAEncryption" }, /* 99 */
|
||
+ { 0x05, 105, 1, 7, "PKCS-5" }, /* 100 */
|
||
+ { 0x03, 102, 0, 8, "pbeWithMD5AndDES-CBC" }, /* 101 */
|
||
+ { 0x0A, 103, 0, 8, "pbeWithSHA1AndDES-CBC" }, /* 102 */
|
||
+ { 0x0C, 104, 0, 8, "id-PBKDF2" }, /* 103 */
|
||
+ { 0x0D, 0, 0, 8, "id-PBES2" }, /* 104 */
|
||
+ { 0x07, 112, 1, 7, "PKCS-7" }, /* 105 */
|
||
+ { 0x01, 107, 0, 8, "data" }, /* 106 */
|
||
+ { 0x02, 108, 0, 8, "signedData" }, /* 107 */
|
||
+ { 0x03, 109, 0, 8, "envelopedData" }, /* 108 */
|
||
+ { 0x04, 110, 0, 8, "signedAndEnvelopedData" }, /* 109 */
|
||
+ { 0x05, 111, 0, 8, "digestedData" }, /* 110 */
|
||
+ { 0x06, 0, 0, 8, "encryptedData" }, /* 111 */
|
||
+ { 0x09, 0, 1, 7, "PKCS-9" }, /* 112 */
|
||
+ { 0x01, 114, 0, 8, "E" }, /* 113 */
|
||
+ { 0x02, 115, 0, 8, "unstructuredName" }, /* 114 */
|
||
+ { 0x03, 116, 0, 8, "contentType" }, /* 115 */
|
||
+ { 0x04, 117, 0, 8, "messageDigest" }, /* 116 */
|
||
+ { 0x05, 118, 0, 8, "signingTime" }, /* 117 */
|
||
+ { 0x06, 119, 0, 8, "counterSignature" }, /* 118 */
|
||
+ { 0x07, 120, 0, 8, "challengePassword" }, /* 119 */
|
||
+ { 0x08, 121, 0, 8, "unstructuredAddress" }, /* 120 */
|
||
+ { 0x0E, 122, 0, 8, "extensionRequest" }, /* 121 */
|
||
+ { 0x0F, 0, 0, 8, "S/MIME Capabilities" }, /* 122 */
|
||
+ { 0x02, 126, 1, 6, "digestAlgorithm" }, /* 123 */
|
||
+ { 0x02, 125, 0, 7, "md2" }, /* 124 */
|
||
+ { 0x05, 0, 0, 7, "md5" }, /* 125 */
|
||
+ { 0x03, 0, 1, 6, "encryptionAlgorithm" }, /* 126 */
|
||
+ { 0x07, 0, 0, 7, "3des-ede-cbc" }, /* 127 */
|
||
+ { 0xCE, 0, 1, 3, "" }, /* 128 */
|
||
+ { 0x3D, 0, 1, 4, "ansi-X9-62" }, /* 129 */
|
||
+ { 0x02, 132, 1, 5, "id-publicKeyType" }, /* 130 */
|
||
+ { 0x01, 0, 0, 6, "id-ecPublicKey" }, /* 131 */
|
||
+ { 0x03, 162, 1, 5, "ellipticCurve" }, /* 132 */
|
||
+ { 0x00, 154, 1, 6, "c-TwoCurve" }, /* 133 */
|
||
+ { 0x01, 135, 0, 7, "c2pnb163v1" }, /* 134 */
|
||
+ { 0x02, 136, 0, 7, "c2pnb163v2" }, /* 135 */
|
||
+ { 0x03, 137, 0, 7, "c2pnb163v3" }, /* 136 */
|
||
+ { 0x04, 138, 0, 7, "c2pnb176w1" }, /* 137 */
|
||
+ { 0x05, 139, 0, 7, "c2tnb191v1" }, /* 138 */
|
||
+ { 0x06, 140, 0, 7, "c2tnb191v2" }, /* 139 */
|
||
+ { 0x07, 141, 0, 7, "c2tnb191v3" }, /* 140 */
|
||
+ { 0x08, 142, 0, 7, "c2onb191v4" }, /* 141 */
|
||
+ { 0x09, 143, 0, 7, "c2onb191v5" }, /* 142 */
|
||
+ { 0x0A, 144, 0, 7, "c2pnb208w1" }, /* 143 */
|
||
+ { 0x0B, 145, 0, 7, "c2tnb239v1" }, /* 144 */
|
||
+ { 0x0C, 146, 0, 7, "c2tnb239v2" }, /* 145 */
|
||
+ { 0x0D, 147, 0, 7, "c2tnb239v3" }, /* 146 */
|
||
+ { 0x0E, 148, 0, 7, "c2onb239v4" }, /* 147 */
|
||
+ { 0x0F, 149, 0, 7, "c2onb239v5" }, /* 148 */
|
||
+ { 0x10, 150, 0, 7, "c2pnb272w1" }, /* 149 */
|
||
+ { 0x11, 151, 0, 7, "c2pnb304w1" }, /* 150 */
|
||
+ { 0x12, 152, 0, 7, "c2tnb359v1" }, /* 151 */
|
||
+ { 0x13, 153, 0, 7, "c2pnb368w1" }, /* 152 */
|
||
+ { 0x14, 0, 0, 7, "c2tnb431r1" }, /* 153 */
|
||
+ { 0x01, 0, 1, 6, "primeCurve" }, /* 154 */
|
||
+ { 0x01, 156, 0, 7, "prime192v1" }, /* 155 */
|
||
+ { 0x02, 157, 0, 7, "prime192v2" }, /* 156 */
|
||
+ { 0x03, 158, 0, 7, "prime192v3" }, /* 157 */
|
||
+ { 0x04, 159, 0, 7, "prime239v1" }, /* 158 */
|
||
+ { 0x05, 160, 0, 7, "prime239v2" }, /* 159 */
|
||
+ { 0x06, 161, 0, 7, "prime239v3" }, /* 160 */
|
||
+ { 0x07, 0, 0, 7, "prime256v1" }, /* 161 */
|
||
+ { 0x04, 0, 1, 5, "id-ecSigType" }, /* 162 */
|
||
+ { 0x01, 164, 0, 6, "ecdsa-with-SHA1" }, /* 163 */
|
||
+ { 0x03, 0, 1, 6, "ecdsa-with-Specified" }, /* 164 */
|
||
+ { 0x01, 166, 0, 7, "ecdsa-with-SHA224" }, /* 165 */
|
||
+ { 0x02, 167, 0, 7, "ecdsa-with-SHA256" }, /* 166 */
|
||
+ { 0x03, 168, 0, 7, "ecdsa-with-SHA384" }, /* 167 */
|
||
+ { 0x04, 0, 0, 7, "ecdsa-with-SHA512" }, /* 168 */
|
||
+ {0x2B, 323, 1, 0, "" }, /* 169 */
|
||
+ { 0x06, 237, 1, 1, "dod" }, /* 170 */
|
||
+ { 0x01, 0, 1, 2, "internet" }, /* 171 */
|
||
+ { 0x04, 194, 1, 3, "private" }, /* 172 */
|
||
+ { 0x01, 0, 1, 4, "enterprise" }, /* 173 */
|
||
+ { 0x82, 187, 1, 5, "" }, /* 174 */
|
||
+ { 0x37, 184, 1, 6, "Microsoft" }, /* 175 */
|
||
+ { 0x0A, 180, 1, 7, "" }, /* 176 */
|
||
+ { 0x03, 0, 1, 8, "" }, /* 177 */
|
||
+ { 0x03, 179, 0, 9, "msSGC" }, /* 178 */
|
||
+ { 0x04, 0, 0, 9, "msEncryptingFileSystem" }, /* 179 */
|
||
+ { 0x14, 0, 1, 7, "msEnrollmentInfrastructure"}, /* 180 */
|
||
+ { 0x02, 0, 1, 8, "msCertificateTypeExtension"}, /* 181 */
|
||
+ { 0x02, 183, 0, 9, "msSmartcardLogon" }, /* 182 */
|
||
+ { 0x03, 0, 0, 9, "msUPN" }, /* 183 */
|
||
+ { 0xA0, 0, 1, 6, "" }, /* 184 */
|
||
+ { 0x2A, 0, 1, 7, "ITA" }, /* 185 */
|
||
+ { 0x01, 0, 0, 8, "strongSwan" }, /* 186 */
|
||
+ { 0x89, 0, 1, 5, "" }, /* 187 */
|
||
+ { 0x31, 0, 1, 6, "" }, /* 188 */
|
||
+ { 0x01, 0, 1, 7, "" }, /* 189 */
|
||
+ { 0x01, 0, 1, 8, "" }, /* 190 */
|
||
+ { 0x02, 0, 1, 9, "" }, /* 191 */
|
||
+ { 0x02, 0, 1, 10, "" }, /* 192 */
|
||
+ { 0x4B, 0, 0, 11, "TCGID" }, /* 193 */
|
||
+ { 0x05, 0, 1, 3, "security" }, /* 194 */
|
||
+ { 0x05, 0, 1, 4, "mechanisms" }, /* 195 */
|
||
+ { 0x07, 234, 1, 5, "id-pkix" }, /* 196 */
|
||
+ { 0x01, 201, 1, 6, "id-pe" }, /* 197 */
|
||
+ { 0x01, 199, 0, 7, "authorityInfoAccess" }, /* 198 */
|
||
+ { 0x03, 200, 0, 7, "qcStatements" }, /* 199 */
|
||
+ { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 200 */
|
||
+ { 0x02, 204, 1, 6, "id-qt" }, /* 201 */
|
||
+ { 0x01, 203, 0, 7, "cps" }, /* 202 */
|
||
+ { 0x02, 0, 0, 7, "unotice" }, /* 203 */
|
||
+ { 0x03, 214, 1, 6, "id-kp" }, /* 204 */
|
||
+ { 0x01, 206, 0, 7, "serverAuth" }, /* 205 */
|
||
+ { 0x02, 207, 0, 7, "clientAuth" }, /* 206 */
|
||
+ { 0x03, 208, 0, 7, "codeSigning" }, /* 207 */
|
||
+ { 0x04, 209, 0, 7, "emailProtection" }, /* 208 */
|
||
+ { 0x05, 210, 0, 7, "ipsecEndSystem" }, /* 209 */
|
||
+ { 0x06, 211, 0, 7, "ipsecTunnel" }, /* 210 */
|
||
+ { 0x07, 212, 0, 7, "ipsecUser" }, /* 211 */
|
||
+ { 0x08, 213, 0, 7, "timeStamping" }, /* 212 */
|
||
+ { 0x09, 0, 0, 7, "ocspSigning" }, /* 213 */
|
||
+ { 0x08, 216, 1, 6, "id-otherNames" }, /* 214 */
|
||
+ { 0x05, 0, 0, 7, "xmppAddr" }, /* 215 */
|
||
+ { 0x0A, 221, 1, 6, "id-aca" }, /* 216 */
|
||
+ { 0x01, 218, 0, 7, "authenticationInfo" }, /* 217 */
|
||
+ { 0x02, 219, 0, 7, "accessIdentity" }, /* 218 */
|
||
+ { 0x03, 220, 0, 7, "chargingIdentity" }, /* 219 */
|
||
+ { 0x04, 0, 0, 7, "group" }, /* 220 */
|
||
+ { 0x0B, 222, 0, 6, "subjectInfoAccess" }, /* 221 */
|
||
+ { 0x30, 0, 1, 6, "id-ad" }, /* 222 */
|
||
+ { 0x01, 231, 1, 7, "ocsp" }, /* 223 */
|
||
+ { 0x01, 225, 0, 8, "basic" }, /* 224 */
|
||
+ { 0x02, 226, 0, 8, "nonce" }, /* 225 */
|
||
+ { 0x03, 227, 0, 8, "crl" }, /* 226 */
|
||
+ { 0x04, 228, 0, 8, "response" }, /* 227 */
|
||
+ { 0x05, 229, 0, 8, "noCheck" }, /* 228 */
|
||
+ { 0x06, 230, 0, 8, "archiveCutoff" }, /* 229 */
|
||
+ { 0x07, 0, 0, 8, "serviceLocator" }, /* 230 */
|
||
+ { 0x02, 232, 0, 7, "caIssuers" }, /* 231 */
|
||
+ { 0x03, 233, 0, 7, "timeStamping" }, /* 232 */
|
||
+ { 0x05, 0, 0, 7, "caRepository" }, /* 233 */
|
||
+ { 0x08, 0, 1, 5, "ipsec" }, /* 234 */
|
||
+ { 0x02, 0, 1, 6, "certificate" }, /* 235 */
|
||
+ { 0x02, 0, 0, 7, "iKEIntermediate" }, /* 236 */
|
||
+ { 0x0E, 243, 1, 1, "oiw" }, /* 237 */
|
||
+ { 0x03, 0, 1, 2, "secsig" }, /* 238 */
|
||
+ { 0x02, 0, 1, 3, "algorithms" }, /* 239 */
|
||
+ { 0x07, 241, 0, 4, "des-cbc" }, /* 240 */
|
||
+ { 0x1A, 242, 0, 4, "sha-1" }, /* 241 */
|
||
+ { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 242 */
|
||
+ { 0x24, 289, 1, 1, "TeleTrusT" }, /* 243 */
|
||
+ { 0x03, 0, 1, 2, "algorithm" }, /* 244 */
|
||
+ { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 245 */
|
||
+ { 0x01, 250, 1, 4, "rsaSignature" }, /* 246 */
|
||
+ { 0x02, 248, 0, 5, "rsaSigWithripemd160" }, /* 247 */
|
||
+ { 0x03, 249, 0, 5, "rsaSigWithripemd128" }, /* 248 */
|
||
+ { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 249 */
|
||
+ { 0x02, 0, 1, 4, "ecSign" }, /* 250 */
|
||
+ { 0x01, 252, 0, 5, "ecSignWithsha1" }, /* 251 */
|
||
+ { 0x02, 253, 0, 5, "ecSignWithripemd160" }, /* 252 */
|
||
+ { 0x03, 254, 0, 5, "ecSignWithmd2" }, /* 253 */
|
||
+ { 0x04, 255, 0, 5, "ecSignWithmd5" }, /* 254 */
|
||
+ { 0x05, 272, 1, 5, "ttt-ecg" }, /* 255 */
|
||
+ { 0x01, 260, 1, 6, "fieldType" }, /* 256 */
|
||
+ { 0x01, 0, 1, 7, "characteristictwoField" }, /* 257 */
|
||
+ { 0x01, 0, 1, 8, "basisType" }, /* 258 */
|
||
+ { 0x01, 0, 0, 9, "ipBasis" }, /* 259 */
|
||
+ { 0x02, 262, 1, 6, "keyType" }, /* 260 */
|
||
+ { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 261 */
|
||
+ { 0x03, 263, 0, 6, "curve" }, /* 262 */
|
||
+ { 0x04, 270, 1, 6, "signatures" }, /* 263 */
|
||
+ { 0x01, 265, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 264 */
|
||
+ { 0x02, 266, 0, 7, "ecgdsa-with-SHA1" }, /* 265 */
|
||
+ { 0x03, 267, 0, 7, "ecgdsa-with-SHA224" }, /* 266 */
|
||
+ { 0x04, 268, 0, 7, "ecgdsa-with-SHA256" }, /* 267 */
|
||
+ { 0x05, 269, 0, 7, "ecgdsa-with-SHA384" }, /* 268 */
|
||
+ { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 269 */
|
||
+ { 0x05, 0, 1, 6, "module" }, /* 270 */
|
||
+ { 0x01, 0, 0, 7, "1" }, /* 271 */
|
||
+ { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 272 */
|
||
+ { 0x01, 0, 1, 6, "ellipticCurve" }, /* 273 */
|
||
+ { 0x01, 0, 1, 7, "versionOne" }, /* 274 */
|
||
+ { 0x01, 276, 0, 8, "brainpoolP160r1" }, /* 275 */
|
||
+ { 0x02, 277, 0, 8, "brainpoolP160t1" }, /* 276 */
|
||
+ { 0x03, 278, 0, 8, "brainpoolP192r1" }, /* 277 */
|
||
+ { 0x04, 279, 0, 8, "brainpoolP192t1" }, /* 278 */
|
||
+ { 0x05, 280, 0, 8, "brainpoolP224r1" }, /* 279 */
|
||
+ { 0x06, 281, 0, 8, "brainpoolP224t1" }, /* 280 */
|
||
+ { 0x07, 282, 0, 8, "brainpoolP256r1" }, /* 281 */
|
||
+ { 0x08, 283, 0, 8, "brainpoolP256t1" }, /* 282 */
|
||
+ { 0x09, 284, 0, 8, "brainpoolP320r1" }, /* 283 */
|
||
+ { 0x0A, 285, 0, 8, "brainpoolP320t1" }, /* 284 */
|
||
+ { 0x0B, 286, 0, 8, "brainpoolP384r1" }, /* 285 */
|
||
+ { 0x0C, 287, 0, 8, "brainpoolP384t1" }, /* 286 */
|
||
+ { 0x0D, 288, 0, 8, "brainpoolP512r1" }, /* 287 */
|
||
+ { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 288 */
|
||
+ { 0x81, 0, 1, 1, "" }, /* 289 */
|
||
+ { 0x04, 0, 1, 2, "Certicom" }, /* 290 */
|
||
+ { 0x00, 0, 1, 3, "curve" }, /* 291 */
|
||
+ { 0x01, 293, 0, 4, "sect163k1" }, /* 292 */
|
||
+ { 0x02, 294, 0, 4, "sect163r1" }, /* 293 */
|
||
+ { 0x03, 295, 0, 4, "sect239k1" }, /* 294 */
|
||
+ { 0x04, 296, 0, 4, "sect113r1" }, /* 295 */
|
||
+ { 0x05, 297, 0, 4, "sect113r2" }, /* 296 */
|
||
+ { 0x06, 298, 0, 4, "secp112r1" }, /* 297 */
|
||
+ { 0x07, 299, 0, 4, "secp112r2" }, /* 298 */
|
||
+ { 0x08, 300, 0, 4, "secp160r1" }, /* 299 */
|
||
+ { 0x09, 301, 0, 4, "secp160k1" }, /* 300 */
|
||
+ { 0x0A, 302, 0, 4, "secp256k1" }, /* 301 */
|
||
+ { 0x0F, 303, 0, 4, "sect163r2" }, /* 302 */
|
||
+ { 0x10, 304, 0, 4, "sect283k1" }, /* 303 */
|
||
+ { 0x11, 305, 0, 4, "sect283r1" }, /* 304 */
|
||
+ { 0x16, 306, 0, 4, "sect131r1" }, /* 305 */
|
||
+ { 0x17, 307, 0, 4, "sect131r2" }, /* 306 */
|
||
+ { 0x18, 308, 0, 4, "sect193r1" }, /* 307 */
|
||
+ { 0x19, 309, 0, 4, "sect193r2" }, /* 308 */
|
||
+ { 0x1A, 310, 0, 4, "sect233k1" }, /* 309 */
|
||
+ { 0x1B, 311, 0, 4, "sect233r1" }, /* 310 */
|
||
+ { 0x1C, 312, 0, 4, "secp128r1" }, /* 311 */
|
||
+ { 0x1D, 313, 0, 4, "secp128r2" }, /* 312 */
|
||
+ { 0x1E, 314, 0, 4, "secp160r2" }, /* 313 */
|
||
+ { 0x1F, 315, 0, 4, "secp192k1" }, /* 314 */
|
||
+ { 0x20, 316, 0, 4, "secp224k1" }, /* 315 */
|
||
+ { 0x21, 317, 0, 4, "secp224r1" }, /* 316 */
|
||
+ { 0x22, 318, 0, 4, "secp384r1" }, /* 317 */
|
||
+ { 0x23, 319, 0, 4, "secp521r1" }, /* 318 */
|
||
+ { 0x24, 320, 0, 4, "sect409k1" }, /* 319 */
|
||
+ { 0x25, 321, 0, 4, "sect409r1" }, /* 320 */
|
||
+ { 0x26, 322, 0, 4, "sect571k1" }, /* 321 */
|
||
+ { 0x27, 0, 0, 4, "sect571r1" }, /* 322 */
|
||
+ {0x60, 369, 1, 0, "" }, /* 323 */
|
||
+ { 0x86, 0, 1, 1, "" }, /* 324 */
|
||
+ { 0x48, 0, 1, 2, "" }, /* 325 */
|
||
+ { 0x01, 0, 1, 3, "organization" }, /* 326 */
|
||
+ { 0x65, 345, 1, 4, "gov" }, /* 327 */
|
||
+ { 0x03, 0, 1, 5, "csor" }, /* 328 */
|
||
+ { 0x04, 0, 1, 6, "nistalgorithm" }, /* 329 */
|
||
+ { 0x01, 340, 1, 7, "aes" }, /* 330 */
|
||
+ { 0x02, 332, 0, 8, "id-aes128-CBC" }, /* 331 */
|
||
+ { 0x06, 333, 0, 8, "id-aes128-GCM" }, /* 332 */
|
||
+ { 0x07, 334, 0, 8, "id-aes128-CCM" }, /* 333 */
|
||
+ { 0x16, 335, 0, 8, "id-aes192-CBC" }, /* 334 */
|
||
+ { 0x1A, 336, 0, 8, "id-aes192-GCM" }, /* 335 */
|
||
+ { 0x1B, 337, 0, 8, "id-aes192-CCM" }, /* 336 */
|
||
+ { 0x2A, 338, 0, 8, "id-aes256-CBC" }, /* 337 */
|
||
+ { 0x2E, 339, 0, 8, "id-aes256-GCM" }, /* 338 */
|
||
+ { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 339 */
|
||
+ { 0x02, 0, 1, 7, "hashalgs" }, /* 340 */
|
||
+ { 0x01, 342, 0, 8, "id-SHA-256" }, /* 341 */
|
||
+ { 0x02, 343, 0, 8, "id-SHA-384" }, /* 342 */
|
||
+ { 0x03, 344, 0, 8, "id-SHA-512" }, /* 343 */
|
||
+ { 0x04, 0, 0, 8, "id-SHA-224" }, /* 344 */
|
||
+ { 0x86, 0, 1, 4, "" }, /* 345 */
|
||
+ { 0xf8, 0, 1, 5, "" }, /* 346 */
|
||
+ { 0x42, 359, 1, 6, "netscape" }, /* 347 */
|
||
+ { 0x01, 354, 1, 7, "" }, /* 348 */
|
||
+ { 0x01, 350, 0, 8, "nsCertType" }, /* 349 */
|
||
+ { 0x03, 351, 0, 8, "nsRevocationUrl" }, /* 350 */
|
||
+ { 0x04, 352, 0, 8, "nsCaRevocationUrl" }, /* 351 */
|
||
+ { 0x08, 353, 0, 8, "nsCaPolicyUrl" }, /* 352 */
|
||
+ { 0x0d, 0, 0, 8, "nsComment" }, /* 353 */
|
||
+ { 0x03, 357, 1, 7, "directory" }, /* 354 */
|
||
+ { 0x01, 0, 1, 8, "" }, /* 355 */
|
||
+ { 0x03, 0, 0, 9, "employeeNumber" }, /* 356 */
|
||
+ { 0x04, 0, 1, 7, "policy" }, /* 357 */
|
||
+ { 0x01, 0, 0, 8, "nsSGC" }, /* 358 */
|
||
+ { 0x45, 0, 1, 6, "verisign" }, /* 359 */
|
||
+ { 0x01, 0, 1, 7, "pki" }, /* 360 */
|
||
+ { 0x09, 0, 1, 8, "attributes" }, /* 361 */
|
||
+ { 0x02, 363, 0, 9, "messageType" }, /* 362 */
|
||
+ { 0x03, 364, 0, 9, "pkiStatus" }, /* 363 */
|
||
+ { 0x04, 365, 0, 9, "failInfo" }, /* 364 */
|
||
+ { 0x05, 366, 0, 9, "senderNonce" }, /* 365 */
|
||
+ { 0x06, 367, 0, 9, "recipientNonce" }, /* 366 */
|
||
+ { 0x07, 368, 0, 9, "transID" }, /* 367 */
|
||
+ { 0x08, 0, 0, 9, "extensionReq" }, /* 368 */
|
||
+ {0x67, 0, 1, 0, "" }, /* 369 */
|
||
+ { 0x81, 0, 1, 1, "" }, /* 370 */
|
||
+ { 0x05, 0, 1, 2, "" }, /* 371 */
|
||
+ { 0x02, 0, 1, 3, "tcg-attribute" }, /* 372 */
|
||
+ { 0x01, 374, 0, 4, "tcg-at-tpmManufacturer" }, /* 373 */
|
||
+ { 0x02, 375, 0, 4, "tcg-at-tpmModel" }, /* 374 */
|
||
+ { 0x03, 376, 0, 4, "tcg-at-tpmVersion" }, /* 375 */
|
||
+ { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 376 */
|
||
+};
|
||
diff --git a/efitools/lib/asn1/oid.h b/efitools/lib/asn1/oid.h
|
||
new file mode 100644
|
||
index 0000000..05aa606
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/oid.h
|
||
@@ -0,0 +1,224 @@
|
||
+/* Object identifiers (OIDs) used by strongSwan
|
||
+ * Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil
|
||
+ *
|
||
+ * This file has been automatically generated by the script oid.pl
|
||
+ * Do not edit manually!
|
||
+ */
|
||
+
|
||
+#ifndef OID_H_
|
||
+#define OID_H_
|
||
+
|
||
+typedef struct {
|
||
+ u_char octet;
|
||
+ u_int next;
|
||
+ u_int down;
|
||
+ u_int level;
|
||
+ const u_char *name;
|
||
+} oid_t;
|
||
+
|
||
+extern const oid_t oid_names[];
|
||
+
|
||
+#define OID_UNKNOWN -1
|
||
+#define OID_NAME_DISTINGUISHER 6
|
||
+#define OID_PILOT_USERID 16
|
||
+#define OID_PILOT_DOMAIN_COMPONENT 17
|
||
+#define OID_COMMON_NAME 20
|
||
+#define OID_SURNAME 21
|
||
+#define OID_SERIAL_NUMBER 22
|
||
+#define OID_COUNTRY 23
|
||
+#define OID_LOCALITY 24
|
||
+#define OID_STATE_OR_PROVINCE 25
|
||
+#define OID_ORGANIZATION 26
|
||
+#define OID_ORGANIZATION_UNIT 27
|
||
+#define OID_TITLE 28
|
||
+#define OID_DESCRIPTION 29
|
||
+#define OID_USER_CERTIFICATE 30
|
||
+#define OID_NAME 31
|
||
+#define OID_GIVEN_NAME 32
|
||
+#define OID_INITIALS 33
|
||
+#define OID_UNIQUE_IDENTIFIER 34
|
||
+#define OID_DN_QUALIFIER 35
|
||
+#define OID_ROLE 36
|
||
+#define OID_SUBJECT_KEY_ID 39
|
||
+#define OID_KEY_USAGE 40
|
||
+#define OID_SUBJECT_ALT_NAME 42
|
||
+#define OID_BASIC_CONSTRAINTS 44
|
||
+#define OID_CRL_NUMBER 45
|
||
+#define OID_CRL_REASON_CODE 46
|
||
+#define OID_DELTA_CRL_INDICATOR 49
|
||
+#define OID_NAME_CONSTRAINTS 52
|
||
+#define OID_CRL_DISTRIBUTION_POINTS 53
|
||
+#define OID_CERTIFICATE_POLICIES 54
|
||
+#define OID_ANY_POLICY 55
|
||
+#define OID_POLICY_MAPPINGS 56
|
||
+#define OID_AUTHORITY_KEY_ID 57
|
||
+#define OID_POLICY_CONSTRAINTS 58
|
||
+#define OID_EXTENDED_KEY_USAGE 59
|
||
+#define OID_FRESHEST_CRL 61
|
||
+#define OID_INHIBIT_ANY_POLICY 62
|
||
+#define OID_TARGET_INFORMATION 63
|
||
+#define OID_NO_REV_AVAIL 64
|
||
+#define OID_CAMELLIA128_CBC 75
|
||
+#define OID_CAMELLIA192_CBC 76
|
||
+#define OID_CAMELLIA256_CBC 77
|
||
+#define OID_RSA_ENCRYPTION 90
|
||
+#define OID_MD2_WITH_RSA 91
|
||
+#define OID_MD5_WITH_RSA 92
|
||
+#define OID_SHA1_WITH_RSA 93
|
||
+#define OID_RSAES_OAEP 94
|
||
+#define OID_SHA256_WITH_RSA 96
|
||
+#define OID_SHA384_WITH_RSA 97
|
||
+#define OID_SHA512_WITH_RSA 98
|
||
+#define OID_SHA224_WITH_RSA 99
|
||
+#define OID_PBE_MD5_DES_CBC 101
|
||
+#define OID_PBE_SHA1_DES_CBC 102
|
||
+#define OID_PBKDF2 103
|
||
+#define OID_PBES2 104
|
||
+#define OID_PKCS7_DATA 106
|
||
+#define OID_PKCS7_SIGNED_DATA 107
|
||
+#define OID_PKCS7_ENVELOPED_DATA 108
|
||
+#define OID_PKCS7_SIGNED_ENVELOPED_DATA 109
|
||
+#define OID_PKCS7_DIGESTED_DATA 110
|
||
+#define OID_PKCS7_ENCRYPTED_DATA 111
|
||
+#define OID_EMAIL_ADDRESS 113
|
||
+#define OID_UNSTRUCTURED_NAME 114
|
||
+#define OID_PKCS9_CONTENT_TYPE 115
|
||
+#define OID_PKCS9_MESSAGE_DIGEST 116
|
||
+#define OID_PKCS9_SIGNING_TIME 117
|
||
+#define OID_CHALLENGE_PASSWORD 119
|
||
+#define OID_UNSTRUCTURED_ADDRESS 120
|
||
+#define OID_EXTENSION_REQUEST 121
|
||
+#define OID_MD2 124
|
||
+#define OID_MD5 125
|
||
+#define OID_3DES_EDE_CBC 127
|
||
+#define OID_EC_PUBLICKEY 131
|
||
+#define OID_C2PNB163V1 134
|
||
+#define OID_C2PNB163V2 135
|
||
+#define OID_C2PNB163V3 136
|
||
+#define OID_C2PNB176W1 137
|
||
+#define OID_C2PNB191V1 138
|
||
+#define OID_C2PNB191V2 139
|
||
+#define OID_C2PNB191V3 140
|
||
+#define OID_C2PNB191V4 141
|
||
+#define OID_C2PNB191V5 142
|
||
+#define OID_C2PNB208W1 143
|
||
+#define OID_C2PNB239V1 144
|
||
+#define OID_C2PNB239V2 145
|
||
+#define OID_C2PNB239V3 146
|
||
+#define OID_C2PNB239V4 147
|
||
+#define OID_C2PNB239V5 148
|
||
+#define OID_C2PNB272W1 149
|
||
+#define OID_C2PNB304W1 150
|
||
+#define OID_C2PNB359V1 151
|
||
+#define OID_C2PNB368W1 152
|
||
+#define OID_C2PNB431R1 153
|
||
+#define OID_PRIME192V1 155
|
||
+#define OID_PRIME192V2 156
|
||
+#define OID_PRIME192V3 157
|
||
+#define OID_PRIME239V1 158
|
||
+#define OID_PRIME239V2 159
|
||
+#define OID_PRIME239V3 160
|
||
+#define OID_PRIME256V1 161
|
||
+#define OID_ECDSA_WITH_SHA1 163
|
||
+#define OID_ECDSA_WITH_SHA224 165
|
||
+#define OID_ECDSA_WITH_SHA256 166
|
||
+#define OID_ECDSA_WITH_SHA384 167
|
||
+#define OID_ECDSA_WITH_SHA512 168
|
||
+#define OID_USER_PRINCIPAL_NAME 183
|
||
+#define OID_STRONGSWAN 186
|
||
+#define OID_TCGID 193
|
||
+#define OID_AUTHORITY_INFO_ACCESS 198
|
||
+#define OID_IP_ADDR_BLOCKS 200
|
||
+#define OID_POLICY_QUALIFIER_CPS 202
|
||
+#define OID_POLICY_QUALIFIER_UNOTICE 203
|
||
+#define OID_SERVER_AUTH 205
|
||
+#define OID_CLIENT_AUTH 206
|
||
+#define OID_OCSP_SIGNING 213
|
||
+#define OID_XMPP_ADDR 215
|
||
+#define OID_AUTHENTICATION_INFO 217
|
||
+#define OID_ACCESS_IDENTITY 218
|
||
+#define OID_CHARGING_IDENTITY 219
|
||
+#define OID_GROUP 220
|
||
+#define OID_OCSP 223
|
||
+#define OID_BASIC 224
|
||
+#define OID_NONCE 225
|
||
+#define OID_CRL 226
|
||
+#define OID_RESPONSE 227
|
||
+#define OID_NO_CHECK 228
|
||
+#define OID_ARCHIVE_CUTOFF 229
|
||
+#define OID_SERVICE_LOCATOR 230
|
||
+#define OID_CA_ISSUERS 231
|
||
+#define OID_IKE_INTERMEDIATE 236
|
||
+#define OID_DES_CBC 240
|
||
+#define OID_SHA1 241
|
||
+#define OID_SHA1_WITH_RSA_OIW 242
|
||
+#define OID_ECGDSA_PUBKEY 261
|
||
+#define OID_ECGDSA_SIG_WITH_RIPEMD160 264
|
||
+#define OID_ECGDSA_SIG_WITH_SHA1 265
|
||
+#define OID_ECGDSA_SIG_WITH_SHA224 266
|
||
+#define OID_ECGDSA_SIG_WITH_SHA256 267
|
||
+#define OID_ECGDSA_SIG_WITH_SHA384 268
|
||
+#define OID_ECGDSA_SIG_WITH_SHA512 269
|
||
+#define OID_SECT163K1 292
|
||
+#define OID_SECT163R1 293
|
||
+#define OID_SECT239K1 294
|
||
+#define OID_SECT113R1 295
|
||
+#define OID_SECT113R2 296
|
||
+#define OID_SECT112R1 297
|
||
+#define OID_SECT112R2 298
|
||
+#define OID_SECT160R1 299
|
||
+#define OID_SECT160K1 300
|
||
+#define OID_SECT256K1 301
|
||
+#define OID_SECT163R2 302
|
||
+#define OID_SECT283K1 303
|
||
+#define OID_SECT283R1 304
|
||
+#define OID_SECT131R1 305
|
||
+#define OID_SECT131R2 306
|
||
+#define OID_SECT193R1 307
|
||
+#define OID_SECT193R2 308
|
||
+#define OID_SECT233K1 309
|
||
+#define OID_SECT233R1 310
|
||
+#define OID_SECT128R1 311
|
||
+#define OID_SECT128R2 312
|
||
+#define OID_SECT160R2 313
|
||
+#define OID_SECT192K1 314
|
||
+#define OID_SECT224K1 315
|
||
+#define OID_SECT224R1 316
|
||
+#define OID_SECT384R1 317
|
||
+#define OID_SECT521R1 318
|
||
+#define OID_SECT409K1 319
|
||
+#define OID_SECT409R1 320
|
||
+#define OID_SECT571K1 321
|
||
+#define OID_SECT571R1 322
|
||
+#define OID_AES128_CBC 331
|
||
+#define OID_AES128_GCM 332
|
||
+#define OID_AES128_CCM 333
|
||
+#define OID_AES192_CBC 334
|
||
+#define OID_AES192_GCM 335
|
||
+#define OID_AES192_CCM 336
|
||
+#define OID_AES256_CBC 337
|
||
+#define OID_AES256_GCM 338
|
||
+#define OID_AES256_CCM 339
|
||
+#define OID_SHA256 341
|
||
+#define OID_SHA384 342
|
||
+#define OID_SHA512 343
|
||
+#define OID_SHA224 344
|
||
+#define OID_NS_REVOCATION_URL 350
|
||
+#define OID_NS_CA_REVOCATION_URL 351
|
||
+#define OID_NS_CA_POLICY_URL 352
|
||
+#define OID_NS_COMMENT 353
|
||
+#define OID_EMPLOYEE_NUMBER 356
|
||
+#define OID_PKI_MESSAGE_TYPE 362
|
||
+#define OID_PKI_STATUS 363
|
||
+#define OID_PKI_FAIL_INFO 364
|
||
+#define OID_PKI_SENDER_NONCE 365
|
||
+#define OID_PKI_RECIPIENT_NONCE 366
|
||
+#define OID_PKI_TRANS_ID 367
|
||
+#define OID_TPM_MANUFACTURER 373
|
||
+#define OID_TPM_MODEL 374
|
||
+#define OID_TPM_VERSION 375
|
||
+#define OID_TPM_ID_LABEL 376
|
||
+
|
||
+#define OID_MAX 377
|
||
+
|
||
+#endif /* OID_H_ */
|
||
diff --git a/efitools/lib/asn1/oid.pl b/efitools/lib/asn1/oid.pl
|
||
new file mode 100644
|
||
index 0000000..ed26feb
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/oid.pl
|
||
@@ -0,0 +1,134 @@
|
||
+#!/usr/bin/perl
|
||
+# Generates oid.h and oid.c out of oid.txt
|
||
+#
|
||
+# Copyright (C) 2003-2008 Andreas Steffen
|
||
+# Hochschule fuer Technik Rapperswil
|
||
+#
|
||
+# 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. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||
+#
|
||
+# 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.
|
||
+#
|
||
+
|
||
+$copyright="Copyright (C) 2003-2008 Andreas Steffen, Hochschule fuer Technik Rapperswil";
|
||
+$automatic="This file has been automatically generated by the script oid.pl";
|
||
+$warning="Do not edit manually!";
|
||
+
|
||
+print "oid.pl generating oid.h and oid.c\n";
|
||
+
|
||
+# Generate oid.h
|
||
+
|
||
+open(OID_H, ">oid.h")
|
||
+ or die "could not open 'oid.h': $!";
|
||
+
|
||
+print OID_H "/* Object identifiers (OIDs) used by strongSwan\n",
|
||
+ " * ", $copyright, "\n",
|
||
+ " * \n",
|
||
+ " * ", $automatic, "\n",
|
||
+ " * ", $warning, "\n",
|
||
+ " */\n\n",
|
||
+ "#include <sys/types.h>\n\n",
|
||
+ "#ifndef OID_H_\n",
|
||
+ "#define OID_H_\n\n",
|
||
+ "typedef struct {\n",
|
||
+ " u_char octet;\n",
|
||
+ " u_int next;\n",
|
||
+ " u_int down;\n",
|
||
+ " u_int level;\n",
|
||
+ " const u_char *name;\n",
|
||
+ "} oid_t;\n",
|
||
+ "\n",
|
||
+ "extern const oid_t oid_names[];\n",
|
||
+ "\n",
|
||
+ "#define OID_UNKNOWN -1\n";
|
||
+
|
||
+# parse oid.txt
|
||
+
|
||
+open(SRC, "<oid.txt")
|
||
+ or die "could not open 'oid.txt': $!";
|
||
+
|
||
+$counter = 0;
|
||
+$max_name = 0;
|
||
+$max_order = 0;
|
||
+
|
||
+while ($line = <SRC>)
|
||
+{
|
||
+ $line =~ m/( *?)(0x\w{2})\s+(".*?")[ \t]*?([\w_]*?)\Z/;
|
||
+
|
||
+ @order[$counter] = length($1);
|
||
+ @octet[$counter] = $2;
|
||
+ @name[$counter] = $3;
|
||
+
|
||
+ if (length($1) > $max_order)
|
||
+ {
|
||
+ $max_order = length($1);
|
||
+ }
|
||
+ if (length($3) > $max_name)
|
||
+ {
|
||
+ $max_name = length($3);
|
||
+ }
|
||
+ if (length($4) > 0)
|
||
+ {
|
||
+ printf OID_H "#define %s%s%d\n", $4, "\t" x ((39-length($4))/4), $counter;
|
||
+ }
|
||
+ $counter++;
|
||
+}
|
||
+
|
||
+printf OID_H "\n#define OID_MAX%s%d\n", "\t" x 8, $counter;
|
||
+
|
||
+print OID_H "\n#endif /* OID_H_ */\n";
|
||
+
|
||
+close SRC;
|
||
+close OID_H;
|
||
+
|
||
+# Generate oid.c
|
||
+
|
||
+open(OID_C, ">oid.c")
|
||
+ or die "could not open 'oid.c': $!";
|
||
+
|
||
+print OID_C "/* List of some useful object identifiers (OIDs)\n",
|
||
+ " * ", $copyright, "\n",
|
||
+ " * \n",
|
||
+ " * ", $automatic, "\n",
|
||
+ " * ", $warning, "\n",
|
||
+ " */\n",
|
||
+ "\n",
|
||
+ "#include <stdlib.h>\n",
|
||
+ "\n",
|
||
+ "#include \"oid.h\"\n",
|
||
+ "\n",
|
||
+ "const oid_t oid_names[] = {\n";
|
||
+
|
||
+for ($c = 0; $c < $counter; $c++)
|
||
+{
|
||
+ $next = 0;
|
||
+
|
||
+ for ($d = $c+1; $d < $counter && @order[$d] >= @order[$c]; $d++)
|
||
+ {
|
||
+ if (@order[$d] == @order[$c])
|
||
+ {
|
||
+ @next[$c] = $d;
|
||
+ last;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ printf OID_C " {%s%s,%s%3d, %d, %2d, %s%s}%s /* %3d */\n"
|
||
+ ,' ' x @order[$c]
|
||
+ , @octet[$c]
|
||
+ , ' ' x (1 + $max_order - @order[$c])
|
||
+ , @next[$c]
|
||
+ , @order[$c+1] > @order[$c]
|
||
+ , @order[$c] / 2
|
||
+ , @name[$c]
|
||
+ , ' ' x ($max_name - length(@name[$c]))
|
||
+ , $c != $counter-1 ? "," : " "
|
||
+ , $c;
|
||
+}
|
||
+
|
||
+print OID_C "};\n" ;
|
||
+close OID_C;
|
||
diff --git a/efitools/lib/asn1/oid.txt b/efitools/lib/asn1/oid.txt
|
||
new file mode 100644
|
||
index 0000000..51a29eb
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/oid.txt
|
||
@@ -0,0 +1,377 @@
|
||
+0x02 "ITU-T Administration"
|
||
+ 0x82 ""
|
||
+ 0x06 "Germany ITU-T member"
|
||
+ 0x01 "Deutsche Telekom AG"
|
||
+ 0x0A ""
|
||
+ 0x07 ""
|
||
+ 0x14 "ND" OID_NAME_DISTINGUISHER
|
||
+0x09 "data"
|
||
+ 0x92 ""
|
||
+ 0x26 ""
|
||
+ 0x89 ""
|
||
+ 0x93 ""
|
||
+ 0xF2 ""
|
||
+ 0x2C ""
|
||
+ 0x64 "pilot"
|
||
+ 0x01 "pilotAttributeType"
|
||
+ 0x01 "UID" OID_PILOT_USERID
|
||
+ 0x19 "DC" OID_PILOT_DOMAIN_COMPONENT
|
||
+0x55 "X.500"
|
||
+ 0x04 "X.509"
|
||
+ 0x03 "CN" OID_COMMON_NAME
|
||
+ 0x04 "S" OID_SURNAME
|
||
+ 0x05 "SN" OID_SERIAL_NUMBER
|
||
+ 0x06 "C" OID_COUNTRY
|
||
+ 0x07 "L" OID_LOCALITY
|
||
+ 0x08 "ST" OID_STATE_OR_PROVINCE
|
||
+ 0x0A "O" OID_ORGANIZATION
|
||
+ 0x0B "OU" OID_ORGANIZATION_UNIT
|
||
+ 0x0C "T" OID_TITLE
|
||
+ 0x0D "D" OID_DESCRIPTION
|
||
+ 0x24 "userCertificate" OID_USER_CERTIFICATE
|
||
+ 0x29 "N" OID_NAME
|
||
+ 0x2A "G" OID_GIVEN_NAME
|
||
+ 0x2B "I" OID_INITIALS
|
||
+ 0x2D "ID" OID_UNIQUE_IDENTIFIER
|
||
+ 0x2E "dnQualifier" OID_DN_QUALIFIER
|
||
+ 0x48 "role" OID_ROLE
|
||
+ 0x1D "id-ce"
|
||
+ 0x09 "subjectDirectoryAttrs"
|
||
+ 0x0E "subjectKeyIdentifier" OID_SUBJECT_KEY_ID
|
||
+ 0x0F "keyUsage" OID_KEY_USAGE
|
||
+ 0x10 "privateKeyUsagePeriod"
|
||
+ 0x11 "subjectAltName" OID_SUBJECT_ALT_NAME
|
||
+ 0x12 "issuerAltName"
|
||
+ 0x13 "basicConstraints" OID_BASIC_CONSTRAINTS
|
||
+ 0x14 "crlNumber" OID_CRL_NUMBER
|
||
+ 0x15 "reasonCode" OID_CRL_REASON_CODE
|
||
+ 0x17 "holdInstructionCode"
|
||
+ 0x18 "invalidityDate"
|
||
+ 0x1B "deltaCrlIndicator" OID_DELTA_CRL_INDICATOR
|
||
+ 0x1C "issuingDistributionPoint"
|
||
+ 0x1D "certificateIssuer"
|
||
+ 0x1E "nameConstraints" OID_NAME_CONSTRAINTS
|
||
+ 0x1F "crlDistributionPoints" OID_CRL_DISTRIBUTION_POINTS
|
||
+ 0x20 "certificatePolicies" OID_CERTIFICATE_POLICIES
|
||
+ 0x00 "anyPolicy" OID_ANY_POLICY
|
||
+ 0x21 "policyMappings" OID_POLICY_MAPPINGS
|
||
+ 0x23 "authorityKeyIdentifier" OID_AUTHORITY_KEY_ID
|
||
+ 0x24 "policyConstraints" OID_POLICY_CONSTRAINTS
|
||
+ 0x25 "extendedKeyUsage" OID_EXTENDED_KEY_USAGE
|
||
+ 0x00 "anyExtendedKeyUsage"
|
||
+ 0x2E "freshestCRL" OID_FRESHEST_CRL
|
||
+ 0x36 "inhibitAnyPolicy" OID_INHIBIT_ANY_POLICY
|
||
+ 0x37 "targetInformation" OID_TARGET_INFORMATION
|
||
+ 0x38 "noRevAvail" OID_NO_REV_AVAIL
|
||
+0x2A ""
|
||
+ 0x83 ""
|
||
+ 0x08 "jp"
|
||
+ 0x8C ""
|
||
+ 0x9A ""
|
||
+ 0x4B ""
|
||
+ 0x3D ""
|
||
+ 0x01 "security"
|
||
+ 0x01 "algorithm"
|
||
+ 0x01 "symm-encryption-alg"
|
||
+ 0x02 "camellia128-cbc" OID_CAMELLIA128_CBC
|
||
+ 0x03 "camellia192-cbc" OID_CAMELLIA192_CBC
|
||
+ 0x04 "camellia256-cbc" OID_CAMELLIA256_CBC
|
||
+ 0x86 ""
|
||
+ 0x48 "us"
|
||
+ 0x86 ""
|
||
+ 0xF6 ""
|
||
+ 0x7D "NortelNetworks"
|
||
+ 0x07 "Entrust"
|
||
+ 0x41 "nsn-ce"
|
||
+ 0x00 "entrustVersInfo"
|
||
+ 0xF7 ""
|
||
+ 0x0D "RSADSI"
|
||
+ 0x01 "PKCS"
|
||
+ 0x01 "PKCS-1"
|
||
+ 0x01 "rsaEncryption" OID_RSA_ENCRYPTION
|
||
+ 0x02 "md2WithRSAEncryption" OID_MD2_WITH_RSA
|
||
+ 0x04 "md5WithRSAEncryption" OID_MD5_WITH_RSA
|
||
+ 0x05 "sha-1WithRSAEncryption" OID_SHA1_WITH_RSA
|
||
+ 0x07 "id-RSAES-OAEP" OID_RSAES_OAEP
|
||
+ 0x09 "id-pSpecified"
|
||
+ 0x0B "sha256WithRSAEncryption" OID_SHA256_WITH_RSA
|
||
+ 0x0C "sha384WithRSAEncryption" OID_SHA384_WITH_RSA
|
||
+ 0x0D "sha512WithRSAEncryption" OID_SHA512_WITH_RSA
|
||
+ 0x0E "sha224WithRSAEncryption" OID_SHA224_WITH_RSA
|
||
+ 0x05 "PKCS-5"
|
||
+ 0x03 "pbeWithMD5AndDES-CBC" OID_PBE_MD5_DES_CBC
|
||
+ 0x0A "pbeWithSHA1AndDES-CBC" OID_PBE_SHA1_DES_CBC
|
||
+ 0x0C "id-PBKDF2" OID_PBKDF2
|
||
+ 0x0D "id-PBES2" OID_PBES2
|
||
+ 0x07 "PKCS-7"
|
||
+ 0x01 "data" OID_PKCS7_DATA
|
||
+ 0x02 "signedData" OID_PKCS7_SIGNED_DATA
|
||
+ 0x03 "envelopedData" OID_PKCS7_ENVELOPED_DATA
|
||
+ 0x04 "signedAndEnvelopedData" OID_PKCS7_SIGNED_ENVELOPED_DATA
|
||
+ 0x05 "digestedData" OID_PKCS7_DIGESTED_DATA
|
||
+ 0x06 "encryptedData" OID_PKCS7_ENCRYPTED_DATA
|
||
+ 0x09 "PKCS-9"
|
||
+ 0x01 "E" OID_EMAIL_ADDRESS
|
||
+ 0x02 "unstructuredName" OID_UNSTRUCTURED_NAME
|
||
+ 0x03 "contentType" OID_PKCS9_CONTENT_TYPE
|
||
+ 0x04 "messageDigest" OID_PKCS9_MESSAGE_DIGEST
|
||
+ 0x05 "signingTime" OID_PKCS9_SIGNING_TIME
|
||
+ 0x06 "counterSignature"
|
||
+ 0x07 "challengePassword" OID_CHALLENGE_PASSWORD
|
||
+ 0x08 "unstructuredAddress" OID_UNSTRUCTURED_ADDRESS
|
||
+ 0x0E "extensionRequest" OID_EXTENSION_REQUEST
|
||
+ 0x0F "S/MIME Capabilities"
|
||
+ 0x02 "digestAlgorithm"
|
||
+ 0x02 "md2" OID_MD2
|
||
+ 0x05 "md5" OID_MD5
|
||
+ 0x03 "encryptionAlgorithm"
|
||
+ 0x07 "3des-ede-cbc" OID_3DES_EDE_CBC
|
||
+ 0xCE ""
|
||
+ 0x3D "ansi-X9-62"
|
||
+ 0x02 "id-publicKeyType"
|
||
+ 0x01 "id-ecPublicKey" OID_EC_PUBLICKEY
|
||
+ 0x03 "ellipticCurve"
|
||
+ 0x00 "c-TwoCurve"
|
||
+ 0x01 "c2pnb163v1" OID_C2PNB163V1
|
||
+ 0x02 "c2pnb163v2" OID_C2PNB163V2
|
||
+ 0x03 "c2pnb163v3" OID_C2PNB163V3
|
||
+ 0x04 "c2pnb176w1" OID_C2PNB176W1
|
||
+ 0x05 "c2tnb191v1" OID_C2PNB191V1
|
||
+ 0x06 "c2tnb191v2" OID_C2PNB191V2
|
||
+ 0x07 "c2tnb191v3" OID_C2PNB191V3
|
||
+ 0x08 "c2onb191v4" OID_C2PNB191V4
|
||
+ 0x09 "c2onb191v5" OID_C2PNB191V5
|
||
+ 0x0A "c2pnb208w1" OID_C2PNB208W1
|
||
+ 0x0B "c2tnb239v1" OID_C2PNB239V1
|
||
+ 0x0C "c2tnb239v2" OID_C2PNB239V2
|
||
+ 0x0D "c2tnb239v3" OID_C2PNB239V3
|
||
+ 0x0E "c2onb239v4" OID_C2PNB239V4
|
||
+ 0x0F "c2onb239v5" OID_C2PNB239V5
|
||
+ 0x10 "c2pnb272w1" OID_C2PNB272W1
|
||
+ 0x11 "c2pnb304w1" OID_C2PNB304W1
|
||
+ 0x12 "c2tnb359v1" OID_C2PNB359V1
|
||
+ 0x13 "c2pnb368w1" OID_C2PNB368W1
|
||
+ 0x14 "c2tnb431r1" OID_C2PNB431R1
|
||
+ 0x01 "primeCurve"
|
||
+ 0x01 "prime192v1" OID_PRIME192V1
|
||
+ 0x02 "prime192v2" OID_PRIME192V2
|
||
+ 0x03 "prime192v3" OID_PRIME192V3
|
||
+ 0x04 "prime239v1" OID_PRIME239V1
|
||
+ 0x05 "prime239v2" OID_PRIME239V2
|
||
+ 0x06 "prime239v3" OID_PRIME239V3
|
||
+ 0x07 "prime256v1" OID_PRIME256V1
|
||
+ 0x04 "id-ecSigType"
|
||
+ 0x01 "ecdsa-with-SHA1" OID_ECDSA_WITH_SHA1
|
||
+ 0x03 "ecdsa-with-Specified"
|
||
+ 0x01 "ecdsa-with-SHA224" OID_ECDSA_WITH_SHA224
|
||
+ 0x02 "ecdsa-with-SHA256" OID_ECDSA_WITH_SHA256
|
||
+ 0x03 "ecdsa-with-SHA384" OID_ECDSA_WITH_SHA384
|
||
+ 0x04 "ecdsa-with-SHA512" OID_ECDSA_WITH_SHA512
|
||
+0x2B ""
|
||
+ 0x06 "dod"
|
||
+ 0x01 "internet"
|
||
+ 0x04 "private"
|
||
+ 0x01 "enterprise"
|
||
+ 0x82 ""
|
||
+ 0x37 "Microsoft"
|
||
+ 0x0A ""
|
||
+ 0x03 ""
|
||
+ 0x03 "msSGC"
|
||
+ 0x04 "msEncryptingFileSystem"
|
||
+ 0x14 "msEnrollmentInfrastructure"
|
||
+ 0x02 "msCertificateTypeExtension"
|
||
+ 0x02 "msSmartcardLogon"
|
||
+ 0x03 "msUPN" OID_USER_PRINCIPAL_NAME
|
||
+ 0xA0 ""
|
||
+ 0x2A "ITA"
|
||
+ 0x01 "strongSwan" OID_STRONGSWAN
|
||
+ 0x89 ""
|
||
+ 0x31 ""
|
||
+ 0x01 ""
|
||
+ 0x01 ""
|
||
+ 0x02 ""
|
||
+ 0x02 ""
|
||
+ 0x4B "TCGID" OID_TCGID
|
||
+ 0x05 "security"
|
||
+ 0x05 "mechanisms"
|
||
+ 0x07 "id-pkix"
|
||
+ 0x01 "id-pe"
|
||
+ 0x01 "authorityInfoAccess" OID_AUTHORITY_INFO_ACCESS
|
||
+ 0x03 "qcStatements"
|
||
+ 0x07 "ipAddrBlocks" OID_IP_ADDR_BLOCKS
|
||
+ 0x02 "id-qt"
|
||
+ 0x01 "cps" OID_POLICY_QUALIFIER_CPS
|
||
+ 0x02 "unotice" OID_POLICY_QUALIFIER_UNOTICE
|
||
+ 0x03 "id-kp"
|
||
+ 0x01 "serverAuth" OID_SERVER_AUTH
|
||
+ 0x02 "clientAuth" OID_CLIENT_AUTH
|
||
+ 0x03 "codeSigning"
|
||
+ 0x04 "emailProtection"
|
||
+ 0x05 "ipsecEndSystem"
|
||
+ 0x06 "ipsecTunnel"
|
||
+ 0x07 "ipsecUser"
|
||
+ 0x08 "timeStamping"
|
||
+ 0x09 "ocspSigning" OID_OCSP_SIGNING
|
||
+ 0x08 "id-otherNames"
|
||
+ 0x05 "xmppAddr" OID_XMPP_ADDR
|
||
+ 0x0A "id-aca"
|
||
+ 0x01 "authenticationInfo" OID_AUTHENTICATION_INFO
|
||
+ 0x02 "accessIdentity" OID_ACCESS_IDENTITY
|
||
+ 0x03 "chargingIdentity" OID_CHARGING_IDENTITY
|
||
+ 0x04 "group" OID_GROUP
|
||
+ 0x0B "subjectInfoAccess"
|
||
+ 0x30 "id-ad"
|
||
+ 0x01 "ocsp" OID_OCSP
|
||
+ 0x01 "basic" OID_BASIC
|
||
+ 0x02 "nonce" OID_NONCE
|
||
+ 0x03 "crl" OID_CRL
|
||
+ 0x04 "response" OID_RESPONSE
|
||
+ 0x05 "noCheck" OID_NO_CHECK
|
||
+ 0x06 "archiveCutoff" OID_ARCHIVE_CUTOFF
|
||
+ 0x07 "serviceLocator" OID_SERVICE_LOCATOR
|
||
+ 0x02 "caIssuers" OID_CA_ISSUERS
|
||
+ 0x03 "timeStamping"
|
||
+ 0x05 "caRepository"
|
||
+ 0x08 "ipsec"
|
||
+ 0x02 "certificate"
|
||
+ 0x02 "iKEIntermediate" OID_IKE_INTERMEDIATE
|
||
+ 0x0E "oiw"
|
||
+ 0x03 "secsig"
|
||
+ 0x02 "algorithms"
|
||
+ 0x07 "des-cbc" OID_DES_CBC
|
||
+ 0x1A "sha-1" OID_SHA1
|
||
+ 0x1D "sha-1WithRSASignature" OID_SHA1_WITH_RSA_OIW
|
||
+ 0x24 "TeleTrusT"
|
||
+ 0x03 "algorithm"
|
||
+ 0x03 "signatureAlgorithm"
|
||
+ 0x01 "rsaSignature"
|
||
+ 0x02 "rsaSigWithripemd160"
|
||
+ 0x03 "rsaSigWithripemd128"
|
||
+ 0x04 "rsaSigWithripemd256"
|
||
+ 0x02 "ecSign"
|
||
+ 0x01 "ecSignWithsha1"
|
||
+ 0x02 "ecSignWithripemd160"
|
||
+ 0x03 "ecSignWithmd2"
|
||
+ 0x04 "ecSignWithmd5"
|
||
+ 0x05 "ttt-ecg"
|
||
+ 0x01 "fieldType"
|
||
+ 0x01 "characteristictwoField"
|
||
+ 0x01 "basisType"
|
||
+ 0x01 "ipBasis"
|
||
+ 0x02 "keyType"
|
||
+ 0x01 "ecgPublicKey" OID_ECGDSA_PUBKEY
|
||
+ 0x03 "curve"
|
||
+ 0x04 "signatures"
|
||
+ 0x01 "ecgdsa-with-RIPEMD160" OID_ECGDSA_SIG_WITH_RIPEMD160
|
||
+ 0x02 "ecgdsa-with-SHA1" OID_ECGDSA_SIG_WITH_SHA1
|
||
+ 0x03 "ecgdsa-with-SHA224" OID_ECGDSA_SIG_WITH_SHA224
|
||
+ 0x04 "ecgdsa-with-SHA256" OID_ECGDSA_SIG_WITH_SHA256
|
||
+ 0x05 "ecgdsa-with-SHA384" OID_ECGDSA_SIG_WITH_SHA384
|
||
+ 0x06 "ecgdsa-with-SHA512" OID_ECGDSA_SIG_WITH_SHA512
|
||
+ 0x05 "module"
|
||
+ 0x01 "1"
|
||
+ 0x08 "ecStdCurvesAndGeneration"
|
||
+ 0x01 "ellipticCurve"
|
||
+ 0x01 "versionOne"
|
||
+ 0x01 "brainpoolP160r1"
|
||
+ 0x02 "brainpoolP160t1"
|
||
+ 0x03 "brainpoolP192r1"
|
||
+ 0x04 "brainpoolP192t1"
|
||
+ 0x05 "brainpoolP224r1"
|
||
+ 0x06 "brainpoolP224t1"
|
||
+ 0x07 "brainpoolP256r1"
|
||
+ 0x08 "brainpoolP256t1"
|
||
+ 0x09 "brainpoolP320r1"
|
||
+ 0x0A "brainpoolP320t1"
|
||
+ 0x0B "brainpoolP384r1"
|
||
+ 0x0C "brainpoolP384t1"
|
||
+ 0x0D "brainpoolP512r1"
|
||
+ 0x0E "brainpoolP512t1"
|
||
+ 0x81 ""
|
||
+ 0x04 "Certicom"
|
||
+ 0x00 "curve"
|
||
+ 0x01 "sect163k1" OID_SECT163K1
|
||
+ 0x02 "sect163r1" OID_SECT163R1
|
||
+ 0x03 "sect239k1" OID_SECT239K1
|
||
+ 0x04 "sect113r1" OID_SECT113R1
|
||
+ 0x05 "sect113r2" OID_SECT113R2
|
||
+ 0x06 "secp112r1" OID_SECT112R1
|
||
+ 0x07 "secp112r2" OID_SECT112R2
|
||
+ 0x08 "secp160r1" OID_SECT160R1
|
||
+ 0x09 "secp160k1" OID_SECT160K1
|
||
+ 0x0A "secp256k1" OID_SECT256K1
|
||
+ 0x0F "sect163r2" OID_SECT163R2
|
||
+ 0x10 "sect283k1" OID_SECT283K1
|
||
+ 0x11 "sect283r1" OID_SECT283R1
|
||
+ 0x16 "sect131r1" OID_SECT131R1
|
||
+ 0x17 "sect131r2" OID_SECT131R2
|
||
+ 0x18 "sect193r1" OID_SECT193R1
|
||
+ 0x19 "sect193r2" OID_SECT193R2
|
||
+ 0x1A "sect233k1" OID_SECT233K1
|
||
+ 0x1B "sect233r1" OID_SECT233R1
|
||
+ 0x1C "secp128r1" OID_SECT128R1
|
||
+ 0x1D "secp128r2" OID_SECT128R2
|
||
+ 0x1E "secp160r2" OID_SECT160R2
|
||
+ 0x1F "secp192k1" OID_SECT192K1
|
||
+ 0x20 "secp224k1" OID_SECT224K1
|
||
+ 0x21 "secp224r1" OID_SECT224R1
|
||
+ 0x22 "secp384r1" OID_SECT384R1
|
||
+ 0x23 "secp521r1" OID_SECT521R1
|
||
+ 0x24 "sect409k1" OID_SECT409K1
|
||
+ 0x25 "sect409r1" OID_SECT409R1
|
||
+ 0x26 "sect571k1" OID_SECT571K1
|
||
+ 0x27 "sect571r1" OID_SECT571R1
|
||
+0x60 ""
|
||
+ 0x86 ""
|
||
+ 0x48 ""
|
||
+ 0x01 "organization"
|
||
+ 0x65 "gov"
|
||
+ 0x03 "csor"
|
||
+ 0x04 "nistalgorithm"
|
||
+ 0x01 "aes"
|
||
+ 0x02 "id-aes128-CBC" OID_AES128_CBC
|
||
+ 0x06 "id-aes128-GCM" OID_AES128_GCM
|
||
+ 0x07 "id-aes128-CCM" OID_AES128_CCM
|
||
+ 0x16 "id-aes192-CBC" OID_AES192_CBC
|
||
+ 0x1A "id-aes192-GCM" OID_AES192_GCM
|
||
+ 0x1B "id-aes192-CCM" OID_AES192_CCM
|
||
+ 0x2A "id-aes256-CBC" OID_AES256_CBC
|
||
+ 0x2E "id-aes256-GCM" OID_AES256_GCM
|
||
+ 0x2F "id-aes256-CCM" OID_AES256_CCM
|
||
+ 0x02 "hashalgs"
|
||
+ 0x01 "id-SHA-256" OID_SHA256
|
||
+ 0x02 "id-SHA-384" OID_SHA384
|
||
+ 0x03 "id-SHA-512" OID_SHA512
|
||
+ 0x04 "id-SHA-224" OID_SHA224
|
||
+ 0x86 ""
|
||
+ 0xf8 ""
|
||
+ 0x42 "netscape"
|
||
+ 0x01 ""
|
||
+ 0x01 "nsCertType"
|
||
+ 0x03 "nsRevocationUrl" OID_NS_REVOCATION_URL
|
||
+ 0x04 "nsCaRevocationUrl" OID_NS_CA_REVOCATION_URL
|
||
+ 0x08 "nsCaPolicyUrl" OID_NS_CA_POLICY_URL
|
||
+ 0x0d "nsComment" OID_NS_COMMENT
|
||
+ 0x03 "directory"
|
||
+ 0x01 ""
|
||
+ 0x03 "employeeNumber" OID_EMPLOYEE_NUMBER
|
||
+ 0x04 "policy"
|
||
+ 0x01 "nsSGC"
|
||
+ 0x45 "verisign"
|
||
+ 0x01 "pki"
|
||
+ 0x09 "attributes"
|
||
+ 0x02 "messageType" OID_PKI_MESSAGE_TYPE
|
||
+ 0x03 "pkiStatus" OID_PKI_STATUS
|
||
+ 0x04 "failInfo" OID_PKI_FAIL_INFO
|
||
+ 0x05 "senderNonce" OID_PKI_SENDER_NONCE
|
||
+ 0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE
|
||
+ 0x07 "transID" OID_PKI_TRANS_ID
|
||
+ 0x08 "extensionReq"
|
||
+0x67 ""
|
||
+ 0x81 ""
|
||
+ 0x05 ""
|
||
+ 0x02 "tcg-attribute"
|
||
+ 0x01 "tcg-at-tpmManufacturer" OID_TPM_MANUFACTURER
|
||
+ 0x02 "tcg-at-tpmModel" OID_TPM_MODEL
|
||
+ 0x03 "tcg-at-tpmVersion" OID_TPM_VERSION
|
||
+ 0x0F "tcg-at-tpmIdLabel" OID_TPM_ID_LABEL
|
||
diff --git a/efitools/lib/asn1/test.c b/efitools/lib/asn1/test.c
|
||
new file mode 100644
|
||
index 0000000..9e8c05f
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/test.c
|
||
@@ -0,0 +1,29 @@
|
||
+#include "typedefs.h"
|
||
+
|
||
+#include <fcntl.h>
|
||
+
|
||
+#include <x509.h>
|
||
+
|
||
+int main(int argc, char *argv[])
|
||
+{
|
||
+ void *buf;
|
||
+ int fd;
|
||
+ struct stat st;
|
||
+ char out[512];
|
||
+
|
||
+ fd = open(argv[1], O_RDONLY);
|
||
+ if (fd<0) {
|
||
+ fprintf(stderr, "Failed to open file %s\n", argv[1]);
|
||
+ perror("");
|
||
+ exit(1);
|
||
+ }
|
||
+ fstat(fd, &st);
|
||
+ buf = malloc(st.st_size);
|
||
+ read(fd, buf, st.st_size);
|
||
+ x509_to_str(buf, st.st_size, X509_OBJ_SUBJECT, out, sizeof(out));
|
||
+ printf("Subject: %s\n", out);
|
||
+ x509_to_str(buf, st.st_size, X509_OBJ_ISSUER, out, sizeof(out));
|
||
+ printf("Issuer: %s\n", out);
|
||
+
|
||
+ exit(0);
|
||
+}
|
||
diff --git a/efitools/lib/asn1/typedefs.h b/efitools/lib/asn1/typedefs.h
|
||
new file mode 100644
|
||
index 0000000..756a629
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/typedefs.h
|
||
@@ -0,0 +1,117 @@
|
||
+#ifdef BUILD_EFI
|
||
+#include <efi.h>
|
||
+#include <efilib.h>
|
||
+
|
||
+#define malloc(x) AllocatePool(x)
|
||
+#define free FreePool
|
||
+#define strcmp(x,y) StrCmp(x,y)
|
||
+#define memset(m,c,l) ZeroMem(m,l)
|
||
+#define memcmp(x,y,z) strncmpa(x,y,z)
|
||
+#define isprint(x) (1)
|
||
+#define snprintf(s, l, f...) SPrint(s, l, L ## f)
|
||
+
|
||
+/* STR is the native string and STRA is how to printf and ASCII string */
|
||
+#define STR CHAR16
|
||
+#define STRA "a"
|
||
+#define size_t UINTN
|
||
+
|
||
+static inline void
|
||
+MEMCPY(void *dest, void *src, size_t n)
|
||
+{
|
||
+ UINTN i;
|
||
+ char *d = dest, *s = src;
|
||
+
|
||
+ for (i = 0; i < n; i++)
|
||
+ d[i] = s[i];
|
||
+}
|
||
+
|
||
+#define memcpy MEMCPY
|
||
+
|
||
+typedef unsigned char u_char;
|
||
+
|
||
+#else
|
||
+
|
||
+#include <stdio.h>
|
||
+#include <stdlib.h>
|
||
+#include <stdarg.h>
|
||
+#include <sys/stat.h>
|
||
+#include <sys/types.h>
|
||
+#include <unistd.h>
|
||
+#include <errno.h>
|
||
+#include <ctype.h>
|
||
+#include <string.h>
|
||
+#include <limits.h>
|
||
+#include <dirent.h>
|
||
+#include <time.h>
|
||
+
|
||
+#define STR char
|
||
+#define STRA "s"
|
||
+
|
||
+#define FALSE 0
|
||
+#define TRUE 1
|
||
+
|
||
+#endif
|
||
+
|
||
+typedef unsigned char bool;
|
||
+typedef unsigned int u_int;
|
||
+
|
||
+#define DBG1(s...)
|
||
+#define DBG2(s...)
|
||
+
|
||
+/**
|
||
+ * Method declaration/definition macro, providing private and public interface.
|
||
+ *
|
||
+ * Defines a method name with this as first parameter and a return value ret,
|
||
+ * and an alias for this method with a _ prefix, having the this argument
|
||
+ * safely casted to the public interface iface.
|
||
+ * _name is provided a function pointer, but will get optimized out by GCC.
|
||
+ */
|
||
+#define METHOD(iface, name, ret, this, ...) \
|
||
+ static ret name(union {iface *_public; this;} \
|
||
+ __attribute__((transparent_union)), ##__VA_ARGS__); \
|
||
+ static typeof(name) *_##name = (typeof(name)*)name; \
|
||
+ static ret name(this, ##__VA_ARGS__)
|
||
+
|
||
+/**
|
||
+ * Object allocation/initialization macro, using designated initializer.
|
||
+ */
|
||
+#define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \
|
||
+ *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
|
||
+
|
||
+/**
|
||
+ * Macro to allocate a sized type.
|
||
+ */
|
||
+#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
|
||
+/**
|
||
+ * Get the number of elements in an array
|
||
+ */
|
||
+#define countof(array) (sizeof(array)/sizeof(array[0]))
|
||
+
|
||
+/**
|
||
+ * Helper function that compares two strings for equality
|
||
+ */
|
||
+static inline bool streq(STR *x, STR *y)
|
||
+{
|
||
+ return strcmp(x, y) == 0;
|
||
+}
|
||
+
|
||
+/**
|
||
+ * Macro compares two binary blobs for equality
|
||
+ */
|
||
+#define memeq(x,y,len) (memcmp(x, y, len) == 0)
|
||
+
|
||
+/**
|
||
+ * Call destructor of an object, if object != NULL
|
||
+ */
|
||
+#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
|
||
+/**
|
||
+ * Macro gives back smaller of two values.
|
||
+ */
|
||
+#define min(x,y) ({ \
|
||
+ typeof(x) _x = (x); \
|
||
+ typeof(y) _y = (y); \
|
||
+ _x < _y ? _x : _y; })
|
||
+
|
||
+
|
||
+#define TIME_32_BIT_SIGNED_MAX 0x7fffffff
|
||
+#define BUF_LEN 512
|
||
diff --git a/efitools/lib/asn1/x509.c b/efitools/lib/asn1/x509.c
|
||
new file mode 100644
|
||
index 0000000..bb313c2
|
||
--- /dev/null
|
||
+++ b/efitools/lib/asn1/x509.c
|
||
@@ -0,0 +1,58 @@
|
||
+#include "typedefs.h"
|
||
+#include "identification.h"
|
||
+#include "asn1_parser.h"
|
||
+
|
||
+/**
|
||
+ * ASN.1 definition of an X.509v3 x509_cert
|
||
+ */
|
||
+const asn1Object_t x509_certObjects[] = {
|
||
+ { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
|
||
+ { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
|
||
+ { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
|
||
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
|
||
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
|
||
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
|
||
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
|
||
+ { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
|
||
+ { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
|
||
+ { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
|
||
+ { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
|
||
+ { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_RAW }, /* 11 */
|
||
+ { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
|
||
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
|
||
+ { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 14 */
|
||
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
|
||
+ { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 16 */
|
||
+ { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 17 */
|
||
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 18 */
|
||
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 19 */
|
||
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 20 */
|
||
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 21 */
|
||
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 22 */
|
||
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 23 */
|
||
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 24 */
|
||
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 25 */
|
||
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
|
||
+};
|
||
+
|
||
+int
|
||
+x509_to_str(void *cert, int cert_size, int tag,
|
||
+ STR *buf, int len)
|
||
+{
|
||
+ asn1_parser_t *parser;
|
||
+ chunk_t object, blob;
|
||
+ int objectID;
|
||
+
|
||
+ blob = chunk_create(cert, cert_size);
|
||
+
|
||
+ parser = asn1_parser_create(x509_certObjects, blob);
|
||
+ parser->set_top_level(parser, 0);
|
||
+
|
||
+ snprintf(buf, sizeof(buf), "MISPARSE");
|
||
+
|
||
+ while (parser->iterate(parser, &objectID, &object)) {
|
||
+ if (objectID == tag)
|
||
+ dntoa(object, buf, len);
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
diff --git a/efitools/lib/configtable.c b/efitools/lib/configtable.c
|
||
new file mode 100644
|
||
index 0000000..735ce8f
|
||
--- /dev/null
|
||
+++ b/efitools/lib/configtable.c
|
||
@@ -0,0 +1,144 @@
|
||
+/*
|
||
+ * Copyright 2013 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ *
|
||
+ * read some platform configuration tables
|
||
+ */
|
||
+#include <efi.h>
|
||
+#include <efilib.h>
|
||
+
|
||
+#include <guid.h>
|
||
+#include <configtable.h>
|
||
+
|
||
+void *
|
||
+configtable_get_table(EFI_GUID *guid)
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < ST->NumberOfTableEntries; i++) {
|
||
+ EFI_CONFIGURATION_TABLE *CT = &ST->ConfigurationTable[i];
|
||
+
|
||
+ if (CompareGuid(guid, &CT->VendorGuid) == 0) {
|
||
+ return CT->VendorTable;
|
||
+ }
|
||
+ }
|
||
+ return NULL;
|
||
+}
|
||
+
|
||
+EFI_IMAGE_EXECUTION_INFO_TABLE *
|
||
+configtable_get_image_table(void)
|
||
+{
|
||
+ return configtable_get_table(&SIG_DB);
|
||
+}
|
||
+
|
||
+EFI_IMAGE_EXECUTION_INFO *
|
||
+configtable_find_image(const EFI_DEVICE_PATH *DevicePath)
|
||
+{
|
||
+ EFI_IMAGE_EXECUTION_INFO_TABLE *t = configtable_get_image_table();
|
||
+
|
||
+ if (!t)
|
||
+ return NULL;
|
||
+
|
||
+ int entries = t->NumberOfImages;
|
||
+ EFI_IMAGE_EXECUTION_INFO *e = t->InformationInfo;
|
||
+
|
||
+ int i;
|
||
+ for (i = 0; i < entries; i++) {
|
||
+#ifdef DEBUG_CONFIG
|
||
+ Print(L"InfoSize = %d Action = %d\n", e->InfoSize, e->Action);
|
||
+
|
||
+ /* print what we have for debugging */
|
||
+ UINT8 *d = (UINT8 *)e; // + sizeof(UINT32)*2;
|
||
+ Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||
+ d += 16;
|
||
+ Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||
+ d += 16;
|
||
+ Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||
+ d += 16;
|
||
+ Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||
+ d += 16;
|
||
+ Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||
+ d += 16;
|
||
+ Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||
+#endif
|
||
+ CHAR16 *name = (CHAR16 *)(e->Data);
|
||
+ int skip = 0;
|
||
+
|
||
+ /* There's a bug in a lot of EFI platforms and they forget to
|
||
+ * put the name here. The only real way of detecting it is to
|
||
+ * look for either a UC16 NULL or ASCII as UC16 */
|
||
+ if (name[0] == '\0' || (e->Data[1] == 0 && e->Data[3] == 0)) {
|
||
+ skip = StrSize(name);
|
||
+#ifdef DEBUG_CONFIG
|
||
+ Print(L"FOUND NAME %s (%d)\n", name, skip);
|
||
+#endif
|
||
+ }
|
||
+ EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *)(e->Data + skip), *dpn = dp;
|
||
+ if (dp->Type == 0 || dp->Type > 6 || dp->SubType == 0
|
||
+ || (((dp->Length[1] << 8) + dp->Length[0]) > e->InfoSize)) {
|
||
+ /* Parse error, table corrupt, bail */
|
||
+ Print(L"Image Execution Information table corrupt\n");
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ UINTN Size;
|
||
+ DevicePathInstance(&dpn, &Size);
|
||
+#ifdef DEBUG_CONFIG
|
||
+ Print(L"Path: %s\n", DevicePathToStr(dp));
|
||
+ Print(L"Device Path Size %d\n", Size);
|
||
+#endif
|
||
+ if (Size > e->InfoSize) {
|
||
+ /* parse error; the platform obviously has a
|
||
+ * corrupted image table; bail */
|
||
+ Print(L"Image Execution Information table corrupt\n");
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ if (CompareMem(dp, DevicePath, Size) == 0) {
|
||
+#ifdef DEBUG_CONFIG
|
||
+ Print(L"***FOUND\n");
|
||
+ console_get_keystroke();
|
||
+#endif
|
||
+ return e;
|
||
+ }
|
||
+ e = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)e + e->InfoSize);
|
||
+ }
|
||
+
|
||
+#ifdef DEBUG_CONFIG
|
||
+ Print(L"***NOT FOUND\n");
|
||
+ console_get_keystroke();
|
||
+#endif
|
||
+
|
||
+ return NULL;
|
||
+}
|
||
+
|
||
+int
|
||
+configtable_image_is_forbidden(const EFI_DEVICE_PATH *DevicePath)
|
||
+{
|
||
+ EFI_IMAGE_EXECUTION_INFO *e = configtable_find_image(DevicePath);
|
||
+
|
||
+ /* Image may not be in DB if it gets executed successfully If it is,
|
||
+ * and EFI_IMAGE_EXECUTION_INITIALIZED is not set, then the image
|
||
+ * isn't authenticated. If there's no signature, usually
|
||
+ * EFI_IMAGE_EXECUTION_AUTH_UNTESTED is set, if the hash is in dbx,
|
||
+ * EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND is returned, and if the key is
|
||
+ * in dbx, EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED is returned*/
|
||
+
|
||
+ if (e && (e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND
|
||
+ || e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED)) {
|
||
+ /* this means the images signing key is in dbx */
|
||
+#ifdef DEBUG_CONFIG
|
||
+ Print(L"SIGNATURE IS IN DBX, FORBIDDING EXECUTION\n");
|
||
+#endif
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
diff --git a/efitools/lib/console.c b/efitools/lib/console.c
|
||
new file mode 100644
|
||
index 0000000..8e209e1
|
||
--- /dev/null
|
||
+++ b/efitools/lib/console.c
|
||
@@ -0,0 +1,413 @@
|
||
+/*
|
||
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ */
|
||
+#include <efi/efi.h>
|
||
+#include <efi/efilib.h>
|
||
+
|
||
+#include <console.h>
|
||
+#include <errors.h>
|
||
+
|
||
+static int min(int a, int b)
|
||
+{
|
||
+ if (a < b)
|
||
+ return a;
|
||
+ return b;
|
||
+}
|
||
+
|
||
+static int
|
||
+count_lines(CHAR16 *str_arr[])
|
||
+{
|
||
+ int i = 0;
|
||
+
|
||
+ while (str_arr[i])
|
||
+ i++;
|
||
+ return i;
|
||
+}
|
||
+
|
||
+static void
|
||
+SetMem16(CHAR16 *dst, UINT32 n, CHAR16 c)
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < n/2; i++) {
|
||
+ dst[i] = c;
|
||
+ }
|
||
+}
|
||
+
|
||
+EFI_INPUT_KEY
|
||
+console_get_keystroke(void)
|
||
+{
|
||
+ EFI_INPUT_KEY key;
|
||
+ UINTN EventIndex;
|
||
+
|
||
+ uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &EventIndex);
|
||
+ uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
|
||
+
|
||
+ return key;
|
||
+}
|
||
+
|
||
+int
|
||
+console_check_for_keystroke(CHAR16 key)
|
||
+{
|
||
+ EFI_INPUT_KEY k;
|
||
+ EFI_STATUS status;
|
||
+ /* check for both upper and lower cases */
|
||
+ CHAR16 key_u = key & ~0x20, key_l = key | 0x20;
|
||
+
|
||
+ /* the assumption is the user has been holding the key down so empty
|
||
+ * the key buffer at this point because auto repeat may have filled
|
||
+ * it */
|
||
+
|
||
+ for(;;) {
|
||
+ status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k);
|
||
+
|
||
+ if (status != EFI_SUCCESS)
|
||
+ break;
|
||
+
|
||
+ if (key_u == k.UnicodeChar || key_l == k.UnicodeChar)
|
||
+ return 1;
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+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)
|
||
+{
|
||
+ int i;
|
||
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||
+ UINTN rows, cols;
|
||
+ CHAR16 *Line;
|
||
+
|
||
+ if (lines == 0)
|
||
+ return;
|
||
+
|
||
+ uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows);
|
||
+
|
||
+ /* last row on screen is unusable without scrolling, so ignore it */
|
||
+ rows--;
|
||
+
|
||
+ if (size_rows < 0)
|
||
+ size_rows = rows + size_rows + 1;
|
||
+ if (size_cols < 0)
|
||
+ size_cols = cols + size_cols + 1;
|
||
+
|
||
+ if (start_col < 0)
|
||
+ start_col = (cols + start_col + 2)/2;
|
||
+ if (start_row < 0)
|
||
+ start_row = (rows + start_row + 2)/2;
|
||
+ if (start_col < 0)
|
||
+ start_col = 0;
|
||
+ if (start_row < 0)
|
||
+ start_row = 0;
|
||
+
|
||
+ if (start_col > cols || start_row > rows) {
|
||
+ Print(L"Starting Position (%d,%d) is off screen\n",
|
||
+ start_col, start_row);
|
||
+ return;
|
||
+ }
|
||
+ if (size_cols + start_col > cols)
|
||
+ size_cols = cols - start_col;
|
||
+ if (size_rows + start_row > rows)
|
||
+ size_rows = rows - start_row;
|
||
+
|
||
+ if (lines > size_rows - 2)
|
||
+ lines = size_rows - 2;
|
||
+
|
||
+ Line = AllocatePool((size_cols+1)*sizeof(CHAR16));
|
||
+ if (!Line) {
|
||
+ Print(L"Failed Allocation\n");
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL);
|
||
+
|
||
+ Line[0] = BOXDRAW_DOWN_RIGHT;
|
||
+ Line[size_cols - 1] = BOXDRAW_DOWN_LEFT;
|
||
+ Line[size_cols] = L'\0';
|
||
+ uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, start_row);
|
||
+ uefi_call_wrapper(co->OutputString, 2, co, Line);
|
||
+
|
||
+ int start;
|
||
+ if (offset == 0)
|
||
+ /* middle */
|
||
+ start = (size_rows - lines)/2 + start_row + offset;
|
||
+ else if (offset < 0)
|
||
+ /* from bottom */
|
||
+ start = start_row + size_rows - lines + offset - 1;
|
||
+ else
|
||
+ /* from top */
|
||
+ start = start_row + offset;
|
||
+
|
||
+
|
||
+ for (i = start_row + 1; i < size_rows + start_row - 1; i++) {
|
||
+ int line = i - start;
|
||
+
|
||
+ SetMem16 (Line, size_cols*2, L' ');
|
||
+ Line[0] = BOXDRAW_VERTICAL;
|
||
+ Line[size_cols - 1] = BOXDRAW_VERTICAL;
|
||
+ Line[size_cols] = L'\0';
|
||
+ if (line >= 0 && line < lines) {
|
||
+ CHAR16 *s = str_arr[line];
|
||
+ int len = StrLen(s);
|
||
+ int col = (size_cols - 2 - len)/2;
|
||
+
|
||
+ if (col < 0)
|
||
+ col = 0;
|
||
+
|
||
+ CopyMem(Line + col + 1, s, min(len, size_cols - 2)*2);
|
||
+ }
|
||
+ if (line >= 0 && line == highlight)
|
||
+ uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
|
||
+ uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i);
|
||
+ uefi_call_wrapper(co->OutputString, 2, co, Line);
|
||
+ if (line >= 0 && line == highlight)
|
||
+ uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
||
+
|
||
+ }
|
||
+ SetMem16 (Line, size_cols * 2, BOXDRAW_HORIZONTAL);
|
||
+ Line[0] = BOXDRAW_UP_RIGHT;
|
||
+ Line[size_cols - 1] = BOXDRAW_UP_LEFT;
|
||
+ Line[size_cols] = L'\0';
|
||
+ uefi_call_wrapper(co->SetCursorPosition, 3, co, start_col, i);
|
||
+ uefi_call_wrapper(co->OutputString, 2, co, Line);
|
||
+
|
||
+ FreePool (Line);
|
||
+
|
||
+}
|
||
+
|
||
+void
|
||
+console_print_box(CHAR16 *str_arr[], int highlight)
|
||
+{
|
||
+ SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
|
||
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||
+ CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
|
||
+ uefi_call_wrapper(co->EnableCursor, 2, co, FALSE);
|
||
+ uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
||
+
|
||
+ console_print_box_at(str_arr, highlight, 0, 0, -1, -1, 0,
|
||
+ count_lines(str_arr));
|
||
+
|
||
+ console_get_keystroke();
|
||
+
|
||
+ uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible);
|
||
+
|
||
+ uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible);
|
||
+ uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
|
||
+ uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute);
|
||
+}
|
||
+
|
||
+int
|
||
+console_select(CHAR16 *title[], CHAR16* selectors[], int start)
|
||
+{
|
||
+ SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
|
||
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||
+ EFI_INPUT_KEY k;
|
||
+ int selector;
|
||
+ int selector_lines = count_lines(selectors);
|
||
+ int selector_max_cols = 0;
|
||
+ int i, offs_col, offs_row, size_cols, size_rows, lines;
|
||
+ int selector_offset;
|
||
+ UINTN cols, rows;
|
||
+
|
||
+ uefi_call_wrapper(co->QueryMode, 4, co, co->Mode->Mode, &cols, &rows);
|
||
+
|
||
+ for (i = 0; i < selector_lines; i++) {
|
||
+ int len = StrLen(selectors[i]);
|
||
+
|
||
+ if (len > selector_max_cols)
|
||
+ selector_max_cols = len;
|
||
+ }
|
||
+
|
||
+ if (start < 0)
|
||
+ start = 0;
|
||
+ if (start >= selector_lines)
|
||
+ start = selector_lines - 1;
|
||
+
|
||
+ offs_col = - selector_max_cols - 4;
|
||
+ size_cols = selector_max_cols + 4;
|
||
+
|
||
+ if (selector_lines > rows - 10) {
|
||
+ int title_lines = count_lines(title);
|
||
+ offs_row = title_lines + 1;
|
||
+ size_rows = rows - 3 - title_lines;
|
||
+ lines = size_rows - 2;
|
||
+ } else {
|
||
+ offs_row = - selector_lines - 4;
|
||
+ size_rows = selector_lines + 2;
|
||
+ lines = selector_lines;
|
||
+ }
|
||
+
|
||
+ if (start > lines) {
|
||
+ selector = lines;
|
||
+ selector_offset = start - lines;
|
||
+ } else {
|
||
+ selector = start;
|
||
+ selector_offset = 0;
|
||
+ }
|
||
+
|
||
+ CopyMem(&SavedConsoleMode, co->Mode, sizeof(SavedConsoleMode));
|
||
+ uefi_call_wrapper(co->EnableCursor, 2, co, FALSE);
|
||
+ uefi_call_wrapper(co->SetAttribute, 2, co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
||
+
|
||
+ console_print_box_at(title, -1, 0, 0, -1, -1, 1, count_lines(title));
|
||
+
|
||
+ console_print_box_at(selectors, selector, offs_col, offs_row,
|
||
+ size_cols, size_rows, 0, lines);
|
||
+
|
||
+ do {
|
||
+ k = console_get_keystroke();
|
||
+
|
||
+ if (k.ScanCode == SCAN_ESC) {
|
||
+ selector = -1;
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ if (k.ScanCode == SCAN_UP) {
|
||
+ if (selector > 0)
|
||
+ selector--;
|
||
+ else if (selector_offset > 0)
|
||
+ selector_offset--;
|
||
+ } else if (k.ScanCode == SCAN_DOWN) {
|
||
+ if (selector < lines - 1)
|
||
+ selector++;
|
||
+ else if (selector_offset < (selector_lines - lines))
|
||
+ selector_offset++;
|
||
+ }
|
||
+
|
||
+ console_print_box_at(&selectors[selector_offset], selector,
|
||
+ offs_col, offs_row,
|
||
+ size_cols, size_rows, 0, lines);
|
||
+ } while (!(k.ScanCode == SCAN_NULL
|
||
+ && k.UnicodeChar == CHAR_CARRIAGE_RETURN));
|
||
+
|
||
+ uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible);
|
||
+
|
||
+ uefi_call_wrapper(co->EnableCursor, 2, co, SavedConsoleMode.CursorVisible);
|
||
+ uefi_call_wrapper(co->SetCursorPosition, 3, co, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
|
||
+ uefi_call_wrapper(co->SetAttribute, 2, co, SavedConsoleMode.Attribute);
|
||
+
|
||
+ if (selector < 0)
|
||
+ /* ESC pressed */
|
||
+ return selector;
|
||
+ return selector + selector_offset;
|
||
+}
|
||
+
|
||
+
|
||
+int
|
||
+console_yes_no(CHAR16 *str_arr[])
|
||
+{
|
||
+ return console_select(str_arr, (CHAR16 *[]){ L"No", L"Yes", NULL }, 0);
|
||
+}
|
||
+
|
||
+void
|
||
+console_alertbox(CHAR16 **title)
|
||
+{
|
||
+ console_select(title, (CHAR16 *[]){ L"OK", 0 }, 0);
|
||
+}
|
||
+
|
||
+void
|
||
+console_errorbox(CHAR16 *err)
|
||
+{
|
||
+ CHAR16 **err_arr = (CHAR16 *[]){
|
||
+ L"ERROR",
|
||
+ L"",
|
||
+ 0,
|
||
+ 0,
|
||
+ };
|
||
+
|
||
+ err_arr[2] = err;
|
||
+
|
||
+ console_alertbox(err_arr);
|
||
+}
|
||
+
|
||
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
|
||
+
|
||
+/* Copy of gnu-efi-3.0 with the added secure boot strings */
|
||
+static struct {
|
||
+ EFI_STATUS Code;
|
||
+ WCHAR *Desc;
|
||
+} error_table[] = {
|
||
+ { EFI_SUCCESS, L"Success"},
|
||
+ { EFI_LOAD_ERROR, L"Load Error"},
|
||
+ { EFI_INVALID_PARAMETER, L"Invalid Parameter"},
|
||
+ { EFI_UNSUPPORTED, L"Unsupported"},
|
||
+ { EFI_BAD_BUFFER_SIZE, L"Bad Buffer Size"},
|
||
+ { EFI_BUFFER_TOO_SMALL, L"Buffer Too Small"},
|
||
+ { EFI_NOT_READY, L"Not Ready"},
|
||
+ { EFI_DEVICE_ERROR, L"Device Error"},
|
||
+ { EFI_WRITE_PROTECTED, L"Write Protected"},
|
||
+ { EFI_OUT_OF_RESOURCES, L"Out of Resources"},
|
||
+ { EFI_VOLUME_CORRUPTED, L"Volume Corrupt"},
|
||
+ { EFI_VOLUME_FULL, L"Volume Full"},
|
||
+ { EFI_NO_MEDIA, L"No Media"},
|
||
+ { EFI_MEDIA_CHANGED, L"Media changed"},
|
||
+ { EFI_NOT_FOUND, L"Not Found"},
|
||
+ { EFI_ACCESS_DENIED, L"Access Denied"},
|
||
+ { EFI_NO_RESPONSE, L"No Response"},
|
||
+ { EFI_NO_MAPPING, L"No mapping"},
|
||
+ { EFI_TIMEOUT, L"Time out"},
|
||
+ { EFI_NOT_STARTED, L"Not started"},
|
||
+ { EFI_ALREADY_STARTED, L"Already started"},
|
||
+ { EFI_ABORTED, L"Aborted"},
|
||
+ { EFI_ICMP_ERROR, L"ICMP Error"},
|
||
+ { EFI_TFTP_ERROR, L"TFTP Error"},
|
||
+ { EFI_PROTOCOL_ERROR, L"Protocol Error"},
|
||
+ { EFI_INCOMPATIBLE_VERSION, L"Incompatible Version"},
|
||
+ { EFI_SECURITY_VIOLATION, L"Security Violation"},
|
||
+
|
||
+ // warnings
|
||
+ { EFI_WARN_UNKOWN_GLYPH, L"Warning Unknown Glyph"},
|
||
+ { EFI_WARN_DELETE_FAILURE, L"Warning Delete Failure"},
|
||
+ { EFI_WARN_WRITE_FAILURE, L"Warning Write Failure"},
|
||
+ { EFI_WARN_BUFFER_TOO_SMALL, L"Warning Buffer Too Small"},
|
||
+ { 0, NULL}
|
||
+} ;
|
||
+
|
||
+
|
||
+static CHAR16 *
|
||
+err_string (
|
||
+ IN EFI_STATUS Status
|
||
+ )
|
||
+{
|
||
+ UINTN Index;
|
||
+
|
||
+ for (Index = 0; error_table[Index].Desc; Index +=1) {
|
||
+ if (error_table[Index].Code == Status) {
|
||
+ return error_table[Index].Desc;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return L"";
|
||
+}
|
||
+
|
||
+
|
||
+void
|
||
+console_error(CHAR16 *err, EFI_STATUS status)
|
||
+{
|
||
+ CHAR16 **err_arr = (CHAR16 *[]){
|
||
+ L"ERROR",
|
||
+ L"",
|
||
+ 0,
|
||
+ 0,
|
||
+ };
|
||
+ CHAR16 str[512];
|
||
+
|
||
+ SPrint(str, sizeof(str), L"%s: (%d) %s", err, status, err_string(status));
|
||
+
|
||
+ err_arr[2] = str;
|
||
+
|
||
+ console_alertbox(err_arr);
|
||
+}
|
||
+
|
||
+void
|
||
+console_reset(void)
|
||
+{
|
||
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||
+
|
||
+ uefi_call_wrapper(co->Reset, 2, co, TRUE);
|
||
+ /* set mode 0 - required to be 80x25 */
|
||
+ uefi_call_wrapper(co->SetMode, 2, co, 0);
|
||
+ uefi_call_wrapper(co->ClearScreen, 1, co);
|
||
+}
|
||
diff --git a/efitools/lib/execute.c b/efitools/lib/execute.c
|
||
new file mode 100644
|
||
index 0000000..8d726eb
|
||
--- /dev/null
|
||
+++ b/efitools/lib/execute.c
|
||
@@ -0,0 +1,127 @@
|
||
+/*
|
||
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ *
|
||
+ * --
|
||
+ *
|
||
+ * generate_path is a cut and paste from
|
||
+ *
|
||
+ * git://github.com/mjg59/shim.git
|
||
+ *
|
||
+ * Code 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.
|
||
+ *
|
||
+ */
|
||
+
|
||
+#include <efi.h>
|
||
+#include <efilib.h>
|
||
+
|
||
+#include <guid.h>
|
||
+#include <execute.h>
|
||
+
|
||
+EFI_STATUS
|
||
+generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **path, CHAR16 **PathName)
|
||
+{
|
||
+ unsigned int pathlen;
|
||
+ EFI_STATUS efi_status = EFI_SUCCESS;
|
||
+ CHAR16 *devpathstr = DevicePathToStr(li->FilePath),
|
||
+ *found = NULL;
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < StrLen(devpathstr); i++) {
|
||
+ if (devpathstr[i] == '/')
|
||
+ devpathstr[i] = '\\';
|
||
+ if (devpathstr[i] == '\\')
|
||
+ found = &devpathstr[i];
|
||
+ }
|
||
+ if (!found) {
|
||
+ pathlen = 0;
|
||
+ } else {
|
||
+ while (*(found - 1) == '\\')
|
||
+ --found;
|
||
+ *found = '\0';
|
||
+ pathlen = StrLen(devpathstr);
|
||
+ }
|
||
+
|
||
+ if (name[0] != '\\')
|
||
+ pathlen++;
|
||
+
|
||
+ *PathName = AllocatePool((pathlen + 1 + StrLen(name))*sizeof(CHAR16));
|
||
+
|
||
+ if (!*PathName) {
|
||
+ Print(L"Failed to allocate path buffer\n");
|
||
+ efi_status = EFI_OUT_OF_RESOURCES;
|
||
+ goto error;
|
||
+ }
|
||
+
|
||
+ StrCpy(*PathName, devpathstr);
|
||
+
|
||
+ if (name[0] != '\\')
|
||
+ StrCat(*PathName, L"\\");
|
||
+ StrCat(*PathName, name);
|
||
+
|
||
+ *path = FileDevicePath(li->DeviceHandle, *PathName);
|
||
+
|
||
+error:
|
||
+ FreePool(devpathstr);
|
||
+
|
||
+ return efi_status;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+execute(EFI_HANDLE image, CHAR16 *name)
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+ EFI_HANDLE h;
|
||
+ EFI_LOADED_IMAGE *li;
|
||
+ EFI_DEVICE_PATH *devpath;
|
||
+ CHAR16 *PathName;
|
||
+
|
||
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
|
||
+ &IMAGE_PROTOCOL, &li);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+
|
||
+
|
||
+ status = generate_path(name, li, &devpath, &PathName);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+
|
||
+ status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image,
|
||
+ devpath, NULL, 0, &h);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ goto out;
|
||
+
|
||
+ status = uefi_call_wrapper(BS->StartImage, 3, h, NULL, NULL);
|
||
+ uefi_call_wrapper(BS->UnloadImage, 1, h);
|
||
+
|
||
+ out:
|
||
+ FreePool(PathName);
|
||
+ FreePool(devpath);
|
||
+ return status;
|
||
+}
|
||
diff --git a/efitools/lib/guid.c b/efitools/lib/guid.c
|
||
new file mode 100644
|
||
index 0000000..e6471a5
|
||
--- /dev/null
|
||
+++ b/efitools/lib/guid.c
|
||
@@ -0,0 +1,57 @@
|
||
+/*
|
||
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ */
|
||
+
|
||
+#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;
|
||
+}
|
||
+
|
||
+int str_to_guid(const char *str, EFI_GUID *guid)
|
||
+{
|
||
+ int args;
|
||
+ args = 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);
|
||
+
|
||
+ return args != 11;
|
||
+}
|
||
+
|
||
+int
|
||
+compare_guid(EFI_GUID *g1, EFI_GUID *g2)
|
||
+{
|
||
+ return memcmp(g1, g2, sizeof(*g1));
|
||
+}
|
||
+#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 } };
|
||
diff --git a/efitools/lib/pecoff.c b/efitools/lib/pecoff.c
|
||
new file mode 100644
|
||
index 0000000..9cd091c
|
||
--- /dev/null
|
||
+++ b/efitools/lib/pecoff.c
|
||
@@ -0,0 +1,391 @@
|
||
+/*
|
||
+ * Code Copyright 2012 Red Hat, Inc <mjg@redhat.com>
|
||
+ *
|
||
+ * Functions cut and pasted from
|
||
+ *
|
||
+ * git://github.com/mjg59/shim.git
|
||
+ *
|
||
+ * 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.
|
||
+ *
|
||
+ * ---
|
||
+ *
|
||
+ * This file is a functional simplification of Original code from TianoCore
|
||
+ * (http://tianocore.sf.net)
|
||
+ *
|
||
+ * MdePkg/Library/BasePeCoffLib/BasePeCoff.c
|
||
+ *
|
||
+ * Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||
+ * Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||
+ * 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.
|
||
+ */
|
||
+
|
||
+#include <efi.h>
|
||
+#include <efilib.h>
|
||
+
|
||
+#include <pecoff.h>
|
||
+#include <guid.h>
|
||
+#include <simple_file.h>
|
||
+#include <variables.h>
|
||
+#include <sha256.h>
|
||
+#include <errors.h>
|
||
+
|
||
+#ifndef BUILD_EFI
|
||
+#define Print(...) do { } while(0)
|
||
+#define AllocatePool(x) malloc(x)
|
||
+#define CopyMem(d, s, l) memcpy(d, s, l)
|
||
+#define ZeroMem(s, l) memset(s, 0, l)
|
||
+#endif
|
||
+
|
||
+EFI_STATUS
|
||
+pecoff_read_header(PE_COFF_LOADER_IMAGE_CONTEXT *context, void *data)
|
||
+{
|
||
+ EFI_IMAGE_DOS_HEADER *DosHdr = data;
|
||
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data;
|
||
+
|
||
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE)
|
||
+ PEHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((char *)data + DosHdr->e_lfanew);
|
||
+
|
||
+ 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->SecDir->VirtualAddress >= context->ImageSize) {
|
||
+ Print(L"Malformed security header\n");
|
||
+ return EFI_INVALID_PARAMETER;
|
||
+ }
|
||
+
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+pecoff_image_layout(PE_COFF_LOADER_IMAGE_CONTEXT *context, void **data)
|
||
+{
|
||
+ void *buffer = AllocatePool(context->ImageSize);
|
||
+ EFI_IMAGE_SECTION_HEADER *s;
|
||
+ int i, size;
|
||
+ char *base, *end;
|
||
+
|
||
+ CopyMem(buffer, *data, context->SizeOfHeaders);
|
||
+
|
||
+ for (i = 0; i < context->NumberOfSections; i++) {
|
||
+ s = &context->FirstSection[i];
|
||
+ size = s->Misc.VirtualSize;
|
||
+
|
||
+ if (size > s->SizeOfRawData)
|
||
+ size = s->SizeOfRawData;
|
||
+ base = pecoff_image_address(buffer, context->ImageSize, s->VirtualAddress);
|
||
+ end = pecoff_image_address(buffer, context->ImageSize, s->VirtualAddress + size - 1);
|
||
+
|
||
+ if (!base || !end) {
|
||
+ Print(L"Invalid section size\n");
|
||
+ return EFI_UNSUPPORTED;
|
||
+ }
|
||
+
|
||
+ if (s->SizeOfRawData > 0)
|
||
+ CopyMem(base, *data + s->PointerToRawData, size);
|
||
+
|
||
+ if (size < s->Misc.VirtualSize)
|
||
+ ZeroMem (base + size, s->Misc.VirtualSize - size);
|
||
+
|
||
+ }
|
||
+ //FreePool(*data);
|
||
+ *data = buffer;
|
||
+
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+pecoff_relocate(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;
|
||
+ EFI_STATUS efi_status;
|
||
+
|
||
+ efi_status = pecoff_image_layout(context, data);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"pecoff_image_layout: failed to layout image\n");
|
||
+ return efi_status;
|
||
+ }
|
||
+
|
||
+ context->PEHdr->Pe32Plus.OptionalHeader.ImageBase = (UINT64)*data;
|
||
+
|
||
+ if (context->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
||
+ Print(L"Image has no relocation entry\n");
|
||
+ return EFI_UNSUPPORTED;
|
||
+ }
|
||
+
|
||
+ RelocBase = pecoff_image_address(*data, size, context->RelocDir->VirtualAddress);
|
||
+ RelocBaseEnd = pecoff_image_address(*data, size, context->RelocDir->VirtualAddress + context->RelocDir->Size - 1);
|
||
+
|
||
+ if (!RelocBase || !RelocBaseEnd) {
|
||
+ Print(L"Reloc table overflows binary %d %d\n",
|
||
+ context->RelocDir->VirtualAddress,
|
||
+ context->RelocDir->VirtualAddress + context->RelocDir->Size - 1);
|
||
+ 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 = pecoff_image_address(*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;
|
||
+}
|
||
+
|
||
+#ifdef BUILD_EFI
|
||
+EFI_STATUS
|
||
+pecoff_check_mok(EFI_HANDLE image, CHAR16 *name)
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+ UINT8 hash[SHA256_DIGEST_SIZE];
|
||
+ UINT8 *data;
|
||
+ UINTN len;
|
||
+ UINT32 attr;
|
||
+
|
||
+ /* first check is MokSBState. If we're in insecure mode, boot
|
||
+ * anyway regardless of dbx contents */
|
||
+ status = get_variable_attr(L"MokSBState", &data, &len,
|
||
+ MOK_OWNER, &attr);
|
||
+ if (status == EFI_SUCCESS) {
|
||
+ UINT8 MokSBState = data[0];
|
||
+
|
||
+ FreePool(data);
|
||
+ if ((attr & EFI_VARIABLE_RUNTIME_ACCESS) == 0
|
||
+ && MokSBState)
|
||
+ return EFI_SUCCESS;
|
||
+ }
|
||
+
|
||
+ status = sha256_get_pecoff_digest(image, name, hash);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+
|
||
+ if (find_in_variable_esl(L"dbx", SIG_DB, hash, SHA256_DIGEST_SIZE)
|
||
+ == EFI_SUCCESS)
|
||
+ /* MOK list cannot override dbx */
|
||
+ goto check_tmplist;
|
||
+
|
||
+ status = get_variable_attr(L"MokList", &data, &len, MOK_OWNER, &attr);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ goto check_tmplist;
|
||
+ FreePool(data);
|
||
+
|
||
+ if (attr & EFI_VARIABLE_RUNTIME_ACCESS)
|
||
+ goto check_tmplist;
|
||
+
|
||
+ if (find_in_variable_esl(L"MokList", MOK_OWNER, hash, SHA256_DIGEST_SIZE) == EFI_SUCCESS)
|
||
+ return EFI_SUCCESS;
|
||
+
|
||
+ check_tmplist:
|
||
+ status = get_variable_attr(L"tmpHashList", &data, &len, MOK_OWNER,
|
||
+ &attr);
|
||
+ if (status == EFI_SUCCESS && attr == EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||
+ && find_in_variable_esl(L"tmpHashList", MOK_OWNER, hash,
|
||
+ SHA256_DIGEST_SIZE) == EFI_SUCCESS)
|
||
+ return EFI_SUCCESS;
|
||
+
|
||
+ return EFI_SECURITY_VIOLATION;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+pecoff_execute_checked(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab, CHAR16 *name)
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+ EFI_LOADED_IMAGE *li;
|
||
+ EFI_DEVICE_PATH *loadpath = NULL;
|
||
+ CHAR16 *PathName = NULL;
|
||
+ EFI_HANDLE h;
|
||
+ EFI_FILE *file;
|
||
+
|
||
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
|
||
+ &IMAGE_PROTOCOL, &li);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+ status = generate_path(name, li, &loadpath, &PathName);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+ status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, image,
|
||
+ loadpath, NULL, 0, &h);
|
||
+ if (status == EFI_SECURITY_VIOLATION || status == EFI_ACCESS_DENIED)
|
||
+ status = pecoff_check_mok(image, name);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ /* this will fail if signature validation fails */
|
||
+ return status;
|
||
+ uefi_call_wrapper(BS->UnloadImage, 1, h);
|
||
+
|
||
+ status = simple_file_open(image, name, &file, EFI_FILE_MODE_READ);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+
|
||
+ pecoff_execute_image(file, name, image, systab);
|
||
+ simple_file_close(file);
|
||
+
|
||
+ return status;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+pecoff_execute_image(EFI_FILE *file, CHAR16 *name, EFI_HANDLE image,
|
||
+ EFI_SYSTEM_TABLE *systab)
|
||
+{
|
||
+ UINTN DataSize;
|
||
+ void *buffer;
|
||
+ EFI_STATUS efi_status;
|
||
+ PE_COFF_LOADER_IMAGE_CONTEXT context;
|
||
+ EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
|
||
+
|
||
+ efi_status = simple_file_read_all(file, &DataSize, &buffer);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to read %s\n", name);
|
||
+ return efi_status;
|
||
+ }
|
||
+
|
||
+ Print(L"Read %d bytes from %s\n", DataSize, name);
|
||
+ efi_status = pecoff_read_header(&context, buffer);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to read header\n");
|
||
+ goto out;
|
||
+ }
|
||
+
|
||
+ efi_status = pecoff_relocate(&context, &buffer);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to relocate image\n");
|
||
+ goto out;
|
||
+ }
|
||
+
|
||
+ entry_point = pecoff_image_address(buffer, context.ImageSize, context.EntryPoint);
|
||
+ if (!entry_point) {
|
||
+ Print(L"Invalid entry point\n");
|
||
+ efi_status = EFI_UNSUPPORTED;
|
||
+ goto out;
|
||
+ }
|
||
+
|
||
+ efi_status = uefi_call_wrapper(entry_point, 2, image, systab);
|
||
+
|
||
+ out:
|
||
+ FreePool(buffer);
|
||
+
|
||
+ return efi_status;
|
||
+}
|
||
+#endif
|
||
diff --git a/efitools/lib/security_policy.c b/efitools/lib/security_policy.c
|
||
new file mode 100644
|
||
index 0000000..b688763
|
||
--- /dev/null
|
||
+++ b/efitools/lib/security_policy.c
|
||
@@ -0,0 +1,399 @@
|
||
+/*
|
||
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ *
|
||
+ * Install and remove a platform security2 override policy
|
||
+ */
|
||
+
|
||
+#include <efi.h>
|
||
+#include <efilib.h>
|
||
+
|
||
+#include <guid.h>
|
||
+#include <sha256.h>
|
||
+#include <variables.h>
|
||
+#include <simple_file.h>
|
||
+#include <errors.h>
|
||
+
|
||
+#include <security_policy.h>
|
||
+
|
||
+/*
|
||
+ * See the UEFI Platform Initialization manual (Vol2: DXE) for this
|
||
+ */
|
||
+struct _EFI_SECURITY2_PROTOCOL;
|
||
+struct _EFI_SECURITY_PROTOCOL;
|
||
+typedef struct _EFI_SECURITY2_PROTOCOL EFI_SECURITY2_PROTOCOL;
|
||
+typedef struct _EFI_SECURITY_PROTOCOL EFI_SECURITY_PROTOCOL;
|
||
+typedef EFI_DEVICE_PATH EFI_DEVICE_PATH_PROTOCOL;
|
||
+
|
||
+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_STATUS
|
||
+security_policy_check_mok(void *data, UINTN len)
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+ UINT8 hash[SHA256_DIGEST_SIZE];
|
||
+ UINT32 attr;
|
||
+ UINT8 *VarData;
|
||
+ UINTN VarLen;
|
||
+
|
||
+ /* first check is MokSBState. If we're in insecure mode, boot
|
||
+ * anyway regardless of dbx contents */
|
||
+ status = get_variable_attr(L"MokSBState", &VarData, &VarLen,
|
||
+ MOK_OWNER, &attr);
|
||
+ if (status == EFI_SUCCESS) {
|
||
+ UINT8 MokSBState = VarData[0];
|
||
+
|
||
+ FreePool(VarData);
|
||
+ if ((attr & EFI_VARIABLE_RUNTIME_ACCESS) == 0
|
||
+ && MokSBState)
|
||
+ return EFI_SUCCESS;
|
||
+ }
|
||
+
|
||
+ status = sha256_get_pecoff_digest_mem(data, len, hash);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+
|
||
+ if (find_in_variable_esl(L"dbx", SIG_DB, hash, SHA256_DIGEST_SIZE)
|
||
+ == EFI_SUCCESS)
|
||
+ /* MOK list cannot override dbx */
|
||
+ return EFI_SECURITY_VIOLATION;
|
||
+
|
||
+ status = get_variable_attr(L"MokList", &VarData, &VarLen, MOK_OWNER,
|
||
+ &attr);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ goto check_tmplist;
|
||
+
|
||
+ FreePool(VarData);
|
||
+
|
||
+ if (attr & EFI_VARIABLE_RUNTIME_ACCESS)
|
||
+ goto check_tmplist;
|
||
+
|
||
+ if (find_in_variable_esl(L"MokList", MOK_OWNER, hash, SHA256_DIGEST_SIZE) == EFI_SUCCESS)
|
||
+ return EFI_SUCCESS;
|
||
+
|
||
+ check_tmplist:
|
||
+ if (security_policy_esl
|
||
+ && find_in_esl(security_policy_esl, security_policy_esl_len, hash,
|
||
+ SHA256_DIGEST_SIZE) == EFI_SUCCESS)
|
||
+ return EFI_SUCCESS;
|
||
+
|
||
+ return EFI_SECURITY_VIOLATION;
|
||
+}
|
||
+
|
||
+static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
|
||
+static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
|
||
+
|
||
+static EFI_STATUS thunk_security_policy_authentication(
|
||
+ const EFI_SECURITY_PROTOCOL *This,
|
||
+ UINT32 AuthenticationStatus,
|
||
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||
+ )
|
||
+__attribute__((unused));
|
||
+
|
||
+static EFI_STATUS thunk_security2_policy_authentication(
|
||
+ const EFI_SECURITY2_PROTOCOL *This,
|
||
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||
+ VOID *FileBuffer,
|
||
+ UINTN FileSize,
|
||
+ BOOLEAN BootPolicy
|
||
+ )
|
||
+__attribute__((unused));
|
||
+
|
||
+static __attribute__((used)) EFI_STATUS
|
||
+security2_policy_authentication (
|
||
+ const EFI_SECURITY2_PROTOCOL *This,
|
||
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||
+ VOID *FileBuffer,
|
||
+ UINTN FileSize,
|
||
+ BOOLEAN BootPolicy
|
||
+ )
|
||
+{
|
||
+ EFI_STATUS status, auth;
|
||
+
|
||
+ /* 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;
|
||
+
|
||
+ auth = security_policy_check_mok(FileBuffer, FileSize);
|
||
+
|
||
+ if (auth == EFI_SECURITY_VIOLATION || auth == EFI_ACCESS_DENIED)
|
||
+ /* return previous status, which is the correct one
|
||
+ * for the platform: may be either EFI_ACCESS_DENIED
|
||
+ * or EFI_SECURITY_VIOLATION */
|
||
+ return status;
|
||
+
|
||
+ return auth;
|
||
+}
|
||
+
|
||
+static __attribute__((used)) EFI_STATUS
|
||
+security_policy_authentication (
|
||
+ const EFI_SECURITY_PROTOCOL *This,
|
||
+ UINT32 AuthenticationStatus,
|
||
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst
|
||
+ )
|
||
+{
|
||
+ EFI_STATUS status, fail_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 = uefi_call_wrapper(esfas, 3, 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;
|
||
+
|
||
+ /* capture failure status: may be either EFI_ACCESS_DENIED or
|
||
+ * EFI_SECURITY_VIOLATION */
|
||
+ fail_status = status;
|
||
+
|
||
+ status = uefi_call_wrapper(BS->LocateDevicePath, 3,
|
||
+ &SIMPLE_FS_PROTOCOL, &DevPath, &h);
|
||
+ 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;
|
||
+
|
||
+ status = security_policy_check_mok(FileBuffer, FileSize);
|
||
+ FreePool(FileBuffer);
|
||
+
|
||
+ if (status == EFI_ACCESS_DENIED || status == EFI_SECURITY_VIOLATION)
|
||
+ /* return what the platform originally said */
|
||
+ status = fail_status;
|
||
+ out:
|
||
+ FreePool(OrigDevPath);
|
||
+ return status;
|
||
+}
|
||
+
|
||
+
|
||
+/* Nasty: ELF and EFI have different calling conventions. Here is the map for
|
||
+ * calling ELF -> EFI
|
||
+ *
|
||
+ * 1) rdi -> rcx (32 saved)
|
||
+ * 2) rsi -> rdx (32 saved)
|
||
+ * 3) rdx -> r8 ( 32 saved)
|
||
+ * 4) rcx -> r9 (32 saved)
|
||
+ * 5) r8 -> 32(%rsp) (48 saved)
|
||
+ * 6) r9 -> 40(%rsp) (48 saved)
|
||
+ * 7) pad+0(%rsp) -> 48(%rsp) (64 saved)
|
||
+ * 8) pad+8(%rsp) -> 56(%rsp) (64 saved)
|
||
+ * 9) pad+16(%rsp) -> 64(%rsp) (80 saved)
|
||
+ * 10) pad+24(%rsp) -> 72(%rsp) (80 saved)
|
||
+ * 11) pad+32(%rsp) -> 80(%rsp) (96 saved)
|
||
+
|
||
+ *
|
||
+ * So for a five argument callback, the map is ignore the first two arguments
|
||
+ * and then map (EFI -> ELF) assuming pad = 0.
|
||
+ *
|
||
+ * ARG4 -> ARG1
|
||
+ * ARG3 -> ARG2
|
||
+ * ARG5 -> ARG3
|
||
+ * ARG6 -> ARG4
|
||
+ * ARG11 -> ARG5
|
||
+ *
|
||
+ * Calling conventions also differ over volatile and preserved registers in
|
||
+ * MS: RBX, RBP, RDI, RSI, R12, R13, R14, and R15 are considered nonvolatile .
|
||
+ * In ELF: Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling
|
||
+ * function and the called function is required to preserve their values.
|
||
+ *
|
||
+ * This means when accepting a function callback from MS -> ELF, we have to do
|
||
+ * separate preservation on %rdi, %rsi before swizzling the arguments and
|
||
+ * handing off to the ELF function.
|
||
+ */
|
||
+
|
||
+asm (
|
||
+".type security2_policy_authentication,@function\n"
|
||
+"thunk_security2_policy_authentication:\n\t"
|
||
+ "mov 0x28(%rsp), %r10 # ARG5\n\t"
|
||
+ "push %rdi\n\t"
|
||
+ "push %rsi\n\t"
|
||
+ "mov %r10, %rdi\n\t"
|
||
+ "subq $8, %rsp # space for storing stack pad\n\t"
|
||
+ "mov $0x08, %rax\n\t"
|
||
+ "mov $0x10, %r10\n\t"
|
||
+ "and %rsp, %rax\n\t"
|
||
+ "cmovnz %rax, %r11\n\t"
|
||
+ "cmovz %r10, %r11\n\t"
|
||
+ "subq %r11, %rsp\n\t"
|
||
+ "addq $8, %r11\n\t"
|
||
+ "mov %r11, (%rsp)\n\t"
|
||
+"# five argument swizzle\n\t"
|
||
+ "mov %rdi, %r10\n\t"
|
||
+ "mov %rcx, %rdi\n\t"
|
||
+ "mov %rdx, %rsi\n\t"
|
||
+ "mov %r8, %rdx\n\t"
|
||
+ "mov %r9, %rcx\n\t"
|
||
+ "mov %r10, %r8\n\t"
|
||
+ "callq security2_policy_authentication@PLT\n\t"
|
||
+ "mov (%rsp), %r11\n\t"
|
||
+ "addq %r11, %rsp\n\t"
|
||
+ "pop %rsi\n\t"
|
||
+ "pop %rdi\n\t"
|
||
+ "ret\n"
|
||
+);
|
||
+
|
||
+asm (
|
||
+".type security_policy_authentication,@function\n"
|
||
+"thunk_security_policy_authentication:\n\t"
|
||
+ "push %rdi\n\t"
|
||
+ "push %rsi\n\t"
|
||
+ "subq $8, %rsp # space for storing stack pad\n\t"
|
||
+ "mov $0x08, %rax\n\t"
|
||
+ "mov $0x10, %r10\n\t"
|
||
+ "and %rsp, %rax\n\t"
|
||
+ "cmovnz %rax, %r11\n\t"
|
||
+ "cmovz %r10, %r11\n\t"
|
||
+ "subq %r11, %rsp\n\t"
|
||
+ "addq $8, %r11\n\t"
|
||
+ "mov %r11, (%rsp)\n\t"
|
||
+"# three argument swizzle\n\t"
|
||
+ "mov %rcx, %rdi\n\t"
|
||
+ "mov %rdx, %rsi\n\t"
|
||
+ "mov %r8, %rdx\n\t"
|
||
+ "callq security_policy_authentication@PLT\n\t"
|
||
+ "mov (%rsp), %r11\n\t"
|
||
+ "addq %r11, %rsp\n\t"
|
||
+ "pop %rsi\n\t"
|
||
+ "pop %rdi\n\t"
|
||
+ "ret\n"
|
||
+);
|
||
+
|
||
+EFI_STATUS
|
||
+security_policy_install(void)
|
||
+{
|
||
+ 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,
|
||
+ &security2_protocol);
|
||
+
|
||
+ status = uefi_call_wrapper(BS->LocateProtocol, 3,
|
||
+ &SECURITY_PROTOCOL_GUID, NULL,
|
||
+ &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;
|
||
+ security2_protocol->FileAuthentication =
|
||
+ thunk_security2_policy_authentication;
|
||
+ /* check for security policy in write protected memory */
|
||
+ if (security2_protocol->FileAuthentication
|
||
+ != thunk_security2_policy_authentication)
|
||
+ return EFI_ACCESS_DENIED;
|
||
+ }
|
||
+
|
||
+ esfas = security_protocol->FileAuthenticationState;
|
||
+ security_protocol->FileAuthenticationState =
|
||
+ thunk_security_policy_authentication;
|
||
+ /* check for security policy in write protected memory */
|
||
+ if (security_protocol->FileAuthenticationState
|
||
+ != thunk_security_policy_authentication)
|
||
+ return EFI_ACCESS_DENIED;
|
||
+
|
||
+ 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,
|
||
+ &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,
|
||
+ &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;
|
||
+}
|
||
diff --git a/efitools/lib/sha256.c b/efitools/lib/sha256.c
|
||
new file mode 100644
|
||
index 0000000..a34cab0
|
||
--- /dev/null
|
||
+++ b/efitools/lib/sha256.c
|
||
@@ -0,0 +1,394 @@
|
||
+/*
|
||
+ * FIPS-180-2 compliant SHA-256 implementation
|
||
+ *
|
||
+ * Copyright (C) 2001-2003 Christophe Devine
|
||
+ *
|
||
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
+ */
|
||
+
|
||
+#include <efi/efi.h>
|
||
+#include <efi/efilib.h>
|
||
+
|
||
+#include <sha256.h>
|
||
+#include <pecoff.h>
|
||
+#include <simple_file.h>
|
||
+
|
||
+#ifndef BUILD_EFI
|
||
+#define Print(...) do { } while(0)
|
||
+#define AllocatePool(x) malloc(x)
|
||
+#define CopyMem(d, s, l) memcpy(d, s, l)
|
||
+#define ZeroMem(s, l) memset(s, 0, l)
|
||
+#define FreePool(s) free(s)
|
||
+#endif
|
||
+
|
||
+#define GET_UINT32(n,b,i) \
|
||
+{ \
|
||
+ (n) = ( (uint32) (b)[(i) ] << 24 ) \
|
||
+ | ( (uint32) (b)[(i) + 1] << 16 ) \
|
||
+ | ( (uint32) (b)[(i) + 2] << 8 ) \
|
||
+ | ( (uint32) (b)[(i) + 3] ); \
|
||
+}
|
||
+
|
||
+#define PUT_UINT32(n,b,i) \
|
||
+{ \
|
||
+ (b)[(i) ] = (uint8) ( (n) >> 24 ); \
|
||
+ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
|
||
+ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
|
||
+ (b)[(i) + 3] = (uint8) ( (n) ); \
|
||
+}
|
||
+
|
||
+void sha256_starts( sha256_context *ctx )
|
||
+{
|
||
+ ctx->total[0] = 0;
|
||
+ ctx->total[1] = 0;
|
||
+
|
||
+ ctx->state[0] = 0x6A09E667;
|
||
+ ctx->state[1] = 0xBB67AE85;
|
||
+ ctx->state[2] = 0x3C6EF372;
|
||
+ ctx->state[3] = 0xA54FF53A;
|
||
+ ctx->state[4] = 0x510E527F;
|
||
+ ctx->state[5] = 0x9B05688C;
|
||
+ ctx->state[6] = 0x1F83D9AB;
|
||
+ ctx->state[7] = 0x5BE0CD19;
|
||
+}
|
||
+
|
||
+void sha256_process( sha256_context *ctx, uint8 data[64] )
|
||
+{
|
||
+ uint32 temp1, temp2, W[64];
|
||
+ uint32 A, B, C, D, E, F, G, H;
|
||
+
|
||
+ GET_UINT32( W[0], data, 0 );
|
||
+ GET_UINT32( W[1], data, 4 );
|
||
+ GET_UINT32( W[2], data, 8 );
|
||
+ GET_UINT32( W[3], data, 12 );
|
||
+ GET_UINT32( W[4], data, 16 );
|
||
+ GET_UINT32( W[5], data, 20 );
|
||
+ GET_UINT32( W[6], data, 24 );
|
||
+ GET_UINT32( W[7], data, 28 );
|
||
+ GET_UINT32( W[8], data, 32 );
|
||
+ GET_UINT32( W[9], data, 36 );
|
||
+ GET_UINT32( W[10], data, 40 );
|
||
+ GET_UINT32( W[11], data, 44 );
|
||
+ GET_UINT32( W[12], data, 48 );
|
||
+ GET_UINT32( W[13], data, 52 );
|
||
+ GET_UINT32( W[14], data, 56 );
|
||
+ GET_UINT32( W[15], data, 60 );
|
||
+
|
||
+#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
|
||
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
|
||
+
|
||
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
|
||
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
|
||
+
|
||
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
|
||
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
|
||
+
|
||
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||
+
|
||
+#define R(t) \
|
||
+( \
|
||
+ W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||
+ S0(W[t - 15]) + W[t - 16] \
|
||
+)
|
||
+
|
||
+#define P(a,b,c,d,e,f,g,h,x,K) \
|
||
+{ \
|
||
+ temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||
+ temp2 = S2(a) + F0(a,b,c); \
|
||
+ d += temp1; h = temp1 + temp2; \
|
||
+}
|
||
+
|
||
+ A = ctx->state[0];
|
||
+ B = ctx->state[1];
|
||
+ C = ctx->state[2];
|
||
+ D = ctx->state[3];
|
||
+ E = ctx->state[4];
|
||
+ F = ctx->state[5];
|
||
+ G = ctx->state[6];
|
||
+ H = ctx->state[7];
|
||
+
|
||
+ P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
|
||
+ P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
|
||
+ P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
|
||
+ P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
|
||
+ P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
|
||
+ P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
|
||
+ P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
|
||
+ P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
|
||
+ P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
|
||
+ P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
|
||
+ P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
|
||
+ P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
|
||
+ P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
|
||
+ P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
|
||
+ P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
|
||
+ P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
|
||
+ P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
|
||
+ P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
|
||
+ P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
|
||
+ P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
|
||
+ P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
|
||
+ P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
|
||
+ P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
|
||
+ P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
|
||
+ P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
|
||
+ P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
|
||
+ P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
|
||
+ P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
|
||
+ P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
|
||
+ P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
|
||
+ P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
|
||
+ P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
|
||
+ P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
|
||
+ P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
|
||
+ P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
|
||
+ P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
|
||
+ P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
|
||
+ P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
|
||
+ P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
|
||
+ P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
|
||
+ P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
|
||
+ P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
|
||
+ P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
|
||
+ P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
|
||
+ P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
|
||
+ P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
|
||
+ P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
|
||
+ P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
|
||
+ P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
|
||
+ P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
|
||
+ P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
|
||
+ P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
|
||
+ P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
|
||
+ P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
|
||
+ P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
|
||
+ P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
|
||
+ P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
|
||
+ P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
|
||
+ P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
|
||
+ P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
|
||
+ P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
|
||
+ P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
|
||
+ P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
|
||
+ P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
|
||
+
|
||
+ ctx->state[0] += A;
|
||
+ ctx->state[1] += B;
|
||
+ ctx->state[2] += C;
|
||
+ ctx->state[3] += D;
|
||
+ ctx->state[4] += E;
|
||
+ ctx->state[5] += F;
|
||
+ ctx->state[6] += G;
|
||
+ ctx->state[7] += H;
|
||
+}
|
||
+
|
||
+void sha256_update( sha256_context *ctx, uint8 *input, uint32 length )
|
||
+{
|
||
+ uint32 left, fill;
|
||
+
|
||
+ if( ! length ) return;
|
||
+
|
||
+ left = ctx->total[0] & 0x3F;
|
||
+ fill = 64 - left;
|
||
+
|
||
+ ctx->total[0] += length;
|
||
+ ctx->total[0] &= 0xFFFFFFFF;
|
||
+
|
||
+ if( ctx->total[0] < length )
|
||
+ ctx->total[1]++;
|
||
+
|
||
+ if( left && length >= fill )
|
||
+ {
|
||
+ CopyMem( (void *) (ctx->buffer + left),
|
||
+ (void *) input, fill );
|
||
+ sha256_process( ctx, ctx->buffer );
|
||
+ length -= fill;
|
||
+ input += fill;
|
||
+ left = 0;
|
||
+ }
|
||
+
|
||
+ while( length >= 64 )
|
||
+ {
|
||
+ sha256_process( ctx, input );
|
||
+ length -= 64;
|
||
+ input += 64;
|
||
+ }
|
||
+
|
||
+ if( length )
|
||
+ {
|
||
+ CopyMem( (void *) (ctx->buffer + left),
|
||
+ (void *) input, length );
|
||
+ }
|
||
+}
|
||
+
|
||
+static uint8 sha256_padding[64] =
|
||
+{
|
||
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||
+};
|
||
+
|
||
+void sha256_finish( sha256_context *ctx, uint8 digest[SHA256_DIGEST_SIZE] )
|
||
+{
|
||
+ uint32 last, padn;
|
||
+ uint32 high, low;
|
||
+ uint8 msglen[8];
|
||
+
|
||
+ high = ( ctx->total[0] >> 29 )
|
||
+ | ( ctx->total[1] << 3 );
|
||
+ low = ( ctx->total[0] << 3 );
|
||
+
|
||
+ PUT_UINT32( high, msglen, 0 );
|
||
+ PUT_UINT32( low, msglen, 4 );
|
||
+
|
||
+ last = ctx->total[0] & 0x3F;
|
||
+ padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||
+
|
||
+ sha256_update( ctx, sha256_padding, padn );
|
||
+ sha256_update( ctx, msglen, 8 );
|
||
+
|
||
+ PUT_UINT32( ctx->state[0], digest, 0 );
|
||
+ PUT_UINT32( ctx->state[1], digest, 4 );
|
||
+ PUT_UINT32( ctx->state[2], digest, 8 );
|
||
+ PUT_UINT32( ctx->state[3], digest, 12 );
|
||
+ PUT_UINT32( ctx->state[4], digest, 16 );
|
||
+ PUT_UINT32( ctx->state[5], digest, 20 );
|
||
+ PUT_UINT32( ctx->state[6], digest, 24 );
|
||
+ PUT_UINT32( ctx->state[7], digest, 28 );
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+sha256_get_pecoff_digest_mem(void *buffer, UINTN DataSize,
|
||
+ UINT8 hash[SHA256_DIGEST_SIZE])
|
||
+{
|
||
+ PE_COFF_LOADER_IMAGE_CONTEXT context;
|
||
+ sha256_context ctx;
|
||
+ void *hashbase;
|
||
+ unsigned int hashsize;
|
||
+ EFI_IMAGE_SECTION_HEADER *section;
|
||
+ EFI_IMAGE_SECTION_HEADER **sections;
|
||
+ int i, sum_of_bytes;
|
||
+ EFI_STATUS efi_status;
|
||
+
|
||
+ efi_status = pecoff_read_header(&context, buffer);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to read header\n");
|
||
+ return efi_status;
|
||
+ }
|
||
+
|
||
+ sections = AllocatePool(context.PEHdr->Pe32.FileHeader.NumberOfSections * sizeof(*sections));
|
||
+ if (!sections)
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+
|
||
+ sha256_starts(&ctx);
|
||
+
|
||
+ /* hash start to checksum */
|
||
+ hashbase = buffer;
|
||
+ hashsize = (void *)&context.PEHdr->Pe32.OptionalHeader.CheckSum - buffer;
|
||
+
|
||
+ sha256_update(&ctx, hashbase, hashsize);
|
||
+
|
||
+ /* hash post-checksum to start of certificate table */
|
||
+ hashbase = (void *)&context.PEHdr->Pe32.OptionalHeader.CheckSum + sizeof (int);
|
||
+ hashsize = (void *)context.SecDir - hashbase;
|
||
+
|
||
+ sha256_update(&ctx, hashbase, hashsize);
|
||
+
|
||
+ /* Hash end of certificate table to end of image header */
|
||
+ hashbase = &context.PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
|
||
+ hashsize = context.PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders -
|
||
+ (int) ((void *) (&context.PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - buffer);
|
||
+
|
||
+ sha256_update(&ctx, hashbase, hashsize);
|
||
+ sum_of_bytes = context.PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
|
||
+ section = (EFI_IMAGE_SECTION_HEADER *) ((char *)context.PEHdr + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + context.PEHdr->Pe32.FileHeader.SizeOfOptionalHeader);
|
||
+
|
||
+ /* Sort the section headers by their data pointers */
|
||
+ for (i = 0; i < context.PEHdr->Pe32.FileHeader.NumberOfSections; i++) {
|
||
+ int p = i;
|
||
+ while (p > 0 && section->PointerToRawData < sections[p - 1]->PointerToRawData) {
|
||
+ sections[p] = sections[p-1];
|
||
+ p--;
|
||
+ }
|
||
+ sections[p] = section++;
|
||
+ }
|
||
+ /* hash the sorted sections */
|
||
+ for (i = 0; i < context.PEHdr->Pe32.FileHeader.NumberOfSections; i++) {
|
||
+ section = sections[i];
|
||
+ hashbase = pecoff_image_address(buffer, DataSize, section->PointerToRawData);
|
||
+ hashsize = (unsigned int) section->SizeOfRawData;
|
||
+ if (hashsize == 0)
|
||
+ continue;
|
||
+ sha256_update(&ctx, hashbase, hashsize);
|
||
+ sum_of_bytes += hashsize;
|
||
+ }
|
||
+
|
||
+ if (DataSize > sum_of_bytes) {
|
||
+ /* stuff at end to hash */
|
||
+ hashbase = buffer + sum_of_bytes;
|
||
+ hashsize = (unsigned int)(DataSize - context.PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size - sum_of_bytes);
|
||
+ sha256_update(&ctx, hashbase, hashsize);
|
||
+ }
|
||
+ sha256_finish(&ctx, hash);
|
||
+
|
||
+ FreePool(sections);
|
||
+
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
+#ifdef BUILD_EFI
|
||
+void
|
||
+sha256_StrCat_hash(CHAR16 *str, UINT8 hash[SHA256_DIGEST_SIZE])
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < SHA256_DIGEST_SIZE; i++) {
|
||
+ CHAR16 buf[10];
|
||
+
|
||
+ SPrint(buf, sizeof(buf), L"%02x", hash[i]);
|
||
+ StrCat(str, buf);
|
||
+ }
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+sha256_get_pecoff_digest(EFI_HANDLE device, CHAR16 *name, uint8 hash[SHA256_DIGEST_SIZE])
|
||
+{
|
||
+ EFI_STATUS efi_status;
|
||
+ EFI_FILE *file;
|
||
+ UINTN DataSize;
|
||
+ void *buffer;
|
||
+
|
||
+ efi_status = simple_file_open(device, name, &file, EFI_FILE_MODE_READ);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to open %s\n", name);
|
||
+ return efi_status;
|
||
+ }
|
||
+
|
||
+ efi_status = simple_file_read_all(file, &DataSize, &buffer);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to read %s\n", name);
|
||
+ goto out_close_file;
|
||
+ }
|
||
+
|
||
+ efi_status = sha256_get_pecoff_digest_mem(buffer, DataSize, hash);
|
||
+
|
||
+ FreePool(buffer);
|
||
+ out_close_file:
|
||
+ simple_file_close(file);
|
||
+ return efi_status;
|
||
+}
|
||
+#endif
|
||
diff --git a/efitools/lib/shell.c b/efitools/lib/shell.c
|
||
new file mode 100644
|
||
index 0000000..51de4e0
|
||
--- /dev/null
|
||
+++ b/efitools/lib/shell.c
|
||
@@ -0,0 +1,57 @@
|
||
+/*
|
||
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ *
|
||
+ * misc shell helper functions
|
||
+ */
|
||
+#include <efi.h>
|
||
+#include <efilib.h>
|
||
+
|
||
+#include <shell.h>
|
||
+
|
||
+EFI_STATUS
|
||
+argsplit(EFI_HANDLE image, int *argc, CHAR16*** ARGV)
|
||
+{
|
||
+ int i, count = 1;
|
||
+ EFI_STATUS status;
|
||
+ EFI_LOADED_IMAGE *info;
|
||
+ CHAR16 *start;
|
||
+
|
||
+ *argc = 0;
|
||
+
|
||
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (VOID **) &info);
|
||
+ if (EFI_ERROR(status)) {
|
||
+ Print(L"Failed to get arguments\n");
|
||
+ return status;
|
||
+ }
|
||
+
|
||
+ for (i = 0; i < info->LoadOptionsSize; i += 2) {
|
||
+ CHAR16 *c = (CHAR16 *)(info->LoadOptions + i);
|
||
+ if (*c == L' ' && *(c+1) != '\0') {
|
||
+ (*argc)++;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ (*argc)++; /* we counted spaces, so add one for initial */
|
||
+
|
||
+ *ARGV = AllocatePool(*argc * sizeof(*ARGV));
|
||
+ if (!*ARGV) {
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+ }
|
||
+ (*ARGV)[0] = (CHAR16 *)info->LoadOptions;
|
||
+ for (i = 0; i < info->LoadOptionsSize; i += 2) {
|
||
+ CHAR16 *c = (CHAR16 *)(info->LoadOptions + i);
|
||
+ if (*c == L' ') {
|
||
+ *c = L'\0';
|
||
+ if (*(c + 1) == '\0')
|
||
+ /* strip trailing space */
|
||
+ break;
|
||
+ start = c + 1;
|
||
+ (*ARGV)[count++] = start;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
diff --git a/efitools/lib/simple_file.c b/efitools/lib/simple_file.c
|
||
new file mode 100644
|
||
index 0000000..0e5ecd2
|
||
--- /dev/null
|
||
+++ b/efitools/lib/simple_file.c
|
||
@@ -0,0 +1,501 @@
|
||
+/*
|
||
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ */
|
||
+
|
||
+#include <efi.h>
|
||
+#include <efilib.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;
|
||
+static EFI_GUID FS_INFO = EFI_FILE_SYSTEM_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, &drive);
|
||
+
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Unable to find simple file protocol (%d)\n", efi_status);
|
||
+ goto error;
|
||
+ }
|
||
+
|
||
+ efi_status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
|
||
+
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to open drive volume (%d)\n", efi_status);
|
||
+ goto error;
|
||
+ }
|
||
+
|
||
+ efi_status = uefi_call_wrapper(root->Open, 5, root, file, name,
|
||
+ mode, 0);
|
||
+
|
||
+ 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, &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_dir_read_all_by_handle(EFI_HANDLE image, EFI_FILE *file, CHAR16* name, EFI_FILE_INFO **entries,
|
||
+ int *count)
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+ char buf[4096];
|
||
+ UINTN size = sizeof(buf);
|
||
+ EFI_FILE_INFO *fi = (void *)buf;
|
||
+
|
||
+ status = uefi_call_wrapper(file->GetInfo, 4, file, &FILE_INFO,
|
||
+ &size, fi);
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to get file info\n");
|
||
+ goto out;
|
||
+ }
|
||
+ if ((fi->Attribute & EFI_FILE_DIRECTORY) == 0) {
|
||
+ Print(L"Not a directory %s\n", name);
|
||
+ status = EFI_INVALID_PARAMETER;
|
||
+ goto out;
|
||
+ }
|
||
+ size = 0;
|
||
+ *count = 0;
|
||
+ for (;;) {
|
||
+ UINTN len = sizeof(buf);
|
||
+ status = uefi_call_wrapper(file->Read, 3, file, &len, buf);
|
||
+ if (status != EFI_SUCCESS || len == 0)
|
||
+ break;
|
||
+ (*count)++;
|
||
+ size += len;
|
||
+ }
|
||
+ uefi_call_wrapper(file->SetPosition, 2, file, 0);
|
||
+
|
||
+ char *ptr = AllocatePool(size);
|
||
+ *entries = (EFI_FILE_INFO *)ptr;
|
||
+ if (!*entries)
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+ int i;
|
||
+ for (i = 0; i < *count; i++) {
|
||
+ int len = size;
|
||
+ uefi_call_wrapper(file->Read, 3, file, &len, ptr);
|
||
+ ptr += len;
|
||
+ size -= len;
|
||
+ }
|
||
+ status = EFI_SUCCESS;
|
||
+ out:
|
||
+ simple_file_close(file);
|
||
+ if (status != EFI_SUCCESS && *entries) {
|
||
+ FreePool(*entries);
|
||
+ *entries = NULL;
|
||
+ }
|
||
+ return status;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+simple_dir_read_all(EFI_HANDLE image, CHAR16 *name, EFI_FILE_INFO **entries,
|
||
+ int *count)
|
||
+{
|
||
+ EFI_FILE *file;
|
||
+ EFI_STATUS status;
|
||
+
|
||
+ status = simple_file_open(image, name, &file, EFI_FILE_MODE_READ);
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ Print(L"failed to open file %s: %d\n", name, status);
|
||
+ return status;
|
||
+ }
|
||
+
|
||
+ return simple_dir_read_all_by_handle(image, file, name, entries, count);
|
||
+}
|
||
+
|
||
+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;
|
||
+}
|
||
+
|
||
+
|
||
+EFI_STATUS
|
||
+simple_file_write_all(EFI_FILE *file, UINTN size, void *buffer)
|
||
+{
|
||
+ EFI_STATUS efi_status;
|
||
+
|
||
+ efi_status = uefi_call_wrapper(file->Write, 3, file, &size, buffer);
|
||
+
|
||
+ return efi_status;
|
||
+}
|
||
+
|
||
+void
|
||
+simple_file_close(EFI_FILE *file)
|
||
+{
|
||
+ uefi_call_wrapper(file->Close, 1, file);
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+simple_volume_selector(CHAR16 **title, CHAR16 **selected, EFI_HANDLE *h)
|
||
+{
|
||
+ UINTN count, i;
|
||
+ EFI_HANDLE *vol_handles = NULL;
|
||
+ EFI_STATUS status;
|
||
+ CHAR16 **entries;
|
||
+ int val;
|
||
+
|
||
+ uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol,
|
||
+ &SIMPLE_FS_PROTOCOL, NULL, &count, &vol_handles);
|
||
+
|
||
+ if (!count || !vol_handles)
|
||
+ return EFI_NOT_FOUND;
|
||
+
|
||
+ entries = AllocatePool(sizeof(CHAR16 *) * (count+1));
|
||
+ if (!entries)
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+
|
||
+ for (i = 0; i < count; i++) {
|
||
+ char buf[4096];
|
||
+ UINTN size = sizeof(buf);
|
||
+ EFI_FILE_SYSTEM_INFO *fi = (void *)buf;
|
||
+ EFI_FILE *root;
|
||
+ CHAR16 *name;
|
||
+ EFI_FILE_IO_INTERFACE *drive;
|
||
+
|
||
+ status = uefi_call_wrapper(BS->HandleProtocol, 3,
|
||
+ vol_handles[i],
|
||
+ &SIMPLE_FS_PROTOCOL, &drive);
|
||
+ if (status != EFI_SUCCESS || !drive)
|
||
+ continue;
|
||
+
|
||
+ status = uefi_call_wrapper(drive->OpenVolume, 2, drive, &root);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ continue;
|
||
+
|
||
+ status = uefi_call_wrapper(root->GetInfo, 4, root, &FS_INFO,
|
||
+ &size, fi);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ continue;
|
||
+
|
||
+ name = fi->VolumeLabel;
|
||
+
|
||
+ if (!name || StrLen(name) == 0 || StrCmp(name, L" ") == 0)
|
||
+ name = DevicePathToStr(DevicePathFromHandle(vol_handles[i]));
|
||
+
|
||
+ entries[i] = AllocatePool((StrLen(name) + 2) * sizeof(CHAR16));
|
||
+ if (!entries[i])
|
||
+ break;
|
||
+ StrCpy(entries[i], name);
|
||
+ }
|
||
+ entries[i] = NULL;
|
||
+
|
||
+ val = console_select(title, entries, 0);
|
||
+
|
||
+ if (val >= 0) {
|
||
+ *selected = AllocatePool((StrLen(entries[val]) + 1) * sizeof(CHAR16));
|
||
+ if (*selected) {
|
||
+ StrCpy(*selected , entries[val]);
|
||
+ }
|
||
+ *h = vol_handles[val];
|
||
+ } else {
|
||
+ *selected = NULL;
|
||
+ *h = 0;
|
||
+ }
|
||
+
|
||
+ for (i = 0; i < count; i++) {
|
||
+ if (entries[i])
|
||
+ FreePool(entries[i]);
|
||
+ }
|
||
+ FreePool(entries);
|
||
+ FreePool(vol_handles);
|
||
+
|
||
+
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
|
||
+ CHAR16 ***result, int *count, EFI_FILE_INFO **entries)
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+ int tot, offs = StrLen(filter), i, c, filtercount = 1;
|
||
+ EFI_FILE_INFO *next;
|
||
+ void *ptr;
|
||
+ CHAR16 *newfilter = AllocatePool((StrLen(filter) + 1) * sizeof(CHAR16)),
|
||
+ **filterarr;
|
||
+
|
||
+ if (!newfilter)
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+
|
||
+ /* just in case efi ever stops writeable strings */
|
||
+ StrCpy(newfilter, filter);
|
||
+
|
||
+ for (i = 0; i < offs; i++) {
|
||
+ if (filter[i] == '|')
|
||
+ filtercount++;
|
||
+ }
|
||
+ filterarr = AllocatePool(filtercount * sizeof(void *));
|
||
+ if (!filterarr)
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+ c = 0;
|
||
+ filterarr[c++] = newfilter;
|
||
+ for (i = 0; i < offs; i++) {
|
||
+ if (filter[i] == '|') {
|
||
+ newfilter[i] = '\0';
|
||
+ filterarr[c++] = &newfilter[i+1];
|
||
+ }
|
||
+ }
|
||
+
|
||
+ *count = 0;
|
||
+
|
||
+ status = simple_dir_read_all(image, name, entries, &tot);
|
||
+
|
||
+ if (status != EFI_SUCCESS)
|
||
+ goto out;
|
||
+ ptr = next = *entries;
|
||
+
|
||
+ for (i = 0; i < tot; i++) {
|
||
+ int len = StrLen(next->FileName);
|
||
+
|
||
+ for (c = 0; c < filtercount; c++) {
|
||
+ offs = StrLen(filterarr[c]);
|
||
+
|
||
+ if (StrCmp(&next->FileName[len - offs], filterarr[c]) == 0
|
||
+ || (next->Attribute & EFI_FILE_DIRECTORY)) {
|
||
+ (*count)++;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ ptr += OFFSET_OF(EFI_FILE_INFO, FileName) + (len + 1)*sizeof(CHAR16);
|
||
+ next = ptr;
|
||
+ }
|
||
+ if (*count)
|
||
+ *result = AllocatePool(((*count) + 1) * sizeof(void *));
|
||
+ else
|
||
+ *result = AllocatePool(2 * sizeof(void *));
|
||
+
|
||
+ *count = 0;
|
||
+ ptr = next = *entries;
|
||
+
|
||
+ for (i = 0; i < tot; i++) {
|
||
+ int len = StrLen(next->FileName);
|
||
+
|
||
+ if (StrCmp(next->FileName, L".") == 0)
|
||
+ /* ignore . directory */
|
||
+ goto next;
|
||
+
|
||
+ if (next->Attribute & EFI_FILE_DIRECTORY) {
|
||
+ (*result)[(*count)] = next->FileName;
|
||
+ (*result)[(*count)][len] = '/';
|
||
+ (*result)[(*count)++][len + 1] = '\0';
|
||
+ goto next;
|
||
+ }
|
||
+
|
||
+ for (c = 0; c < filtercount; c++) {
|
||
+ offs = StrLen(filterarr[c]);
|
||
+
|
||
+ if (StrCmp(&next->FileName[len - offs], filterarr[c]) == 0) {
|
||
+ (*result)[(*count)++] = next->FileName;
|
||
+ } else {
|
||
+ continue;
|
||
+ }
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ next:
|
||
+ if (StrCmp(next->FileName, L"../") == 0) {
|
||
+ /* place .. directory first */
|
||
+ CHAR16 *tmp = (*result)[(*count) - 1];
|
||
+
|
||
+ (*result)[(*count) - 1] = (*result)[0];
|
||
+ (*result)[0] = tmp;
|
||
+ }
|
||
+
|
||
+ ptr += OFFSET_OF(EFI_FILE_INFO, FileName) + (len + 1)*sizeof(CHAR16);
|
||
+ next = ptr;
|
||
+ }
|
||
+ if (*count == 0) {
|
||
+ /* no entries at all ... can happen because top level dir has no . or .. */
|
||
+ (*result)[(*count)++] = L"./";
|
||
+ }
|
||
+ (*result)[*count] = NULL;
|
||
+ status = EFI_SUCCESS;
|
||
+
|
||
+ out:
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ if (*entries)
|
||
+ FreePool(*entries);
|
||
+ *entries = NULL;
|
||
+ if (*result)
|
||
+ FreePool(*result);
|
||
+ *result = NULL;
|
||
+ }
|
||
+ return status;
|
||
+}
|
||
+
|
||
+void
|
||
+simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
+ CHAR16 *filter, CHAR16 **result)
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+ CHAR16 **entries;
|
||
+ EFI_FILE_INFO *dmp;
|
||
+ int count, select, len;
|
||
+ CHAR16 *newname, *selected;
|
||
+
|
||
+ *result = NULL;
|
||
+ if (!name)
|
||
+ name = L"\\";
|
||
+ if (!filter)
|
||
+ filter = L"";
|
||
+ if (!*im) {
|
||
+ EFI_HANDLE h;
|
||
+ CHAR16 *volname;
|
||
+
|
||
+ simple_volume_selector(title, &volname, &h);
|
||
+ if (!volname)
|
||
+ return;
|
||
+ FreePool(volname);
|
||
+ *im = h;
|
||
+ }
|
||
+
|
||
+ newname = AllocatePool((StrLen(name) + 1)*sizeof(CHAR16));
|
||
+ if (!newname)
|
||
+ return;
|
||
+
|
||
+ StrCpy(newname, name);
|
||
+ name = newname;
|
||
+
|
||
+ redo:
|
||
+ status = simple_dir_filter(*im, name, filter, &entries, &count, &dmp);
|
||
+
|
||
+ if (status != EFI_SUCCESS)
|
||
+ goto out_free_name;
|
||
+
|
||
+ select = console_select(title, entries, 0);
|
||
+ if (select < 0)
|
||
+ /* ESC key */
|
||
+ goto out_free;
|
||
+ selected = entries[select];
|
||
+ FreePool(entries);
|
||
+ entries = NULL;
|
||
+ /* note that memory used by selected is valid until dmp is freed */
|
||
+ len = StrLen(selected);
|
||
+ if (selected[len - 1] == '/') {
|
||
+ CHAR16 *newname;
|
||
+
|
||
+ /* stay where we are */
|
||
+ if (StrCmp(selected, L"./") == 0) {
|
||
+ FreePool(dmp);
|
||
+ goto redo;
|
||
+ } else if (StrCmp(selected, L"../") == 0) {
|
||
+ int i;
|
||
+
|
||
+ i = StrLen(name) - 1;
|
||
+
|
||
+
|
||
+ for (i = StrLen(name); i > 0; --i) {
|
||
+ if (name[i] == '\\')
|
||
+ break;
|
||
+ }
|
||
+ if (i == 0)
|
||
+ i = 1;
|
||
+
|
||
+ if (StrCmp(name, L"\\") != 0
|
||
+ && StrCmp(&name[i], L"..") != 0) {
|
||
+ name[i] = '\0';
|
||
+ FreePool(dmp);
|
||
+ goto redo;
|
||
+ }
|
||
+ }
|
||
+ newname = AllocatePool((StrLen(name) + len + 2)*sizeof(CHAR16));
|
||
+ if (!newname)
|
||
+ goto out_free;
|
||
+ StrCpy(newname, name);
|
||
+
|
||
+ if (name[StrLen(name) - 1] != '\\')
|
||
+ StrCat(newname, L"\\");
|
||
+ StrCat(newname, selected);
|
||
+ /* remove trailing / */
|
||
+ newname[StrLen(newname) - 1] = '\0';
|
||
+
|
||
+ FreePool(dmp);
|
||
+ FreePool(name);
|
||
+ name = newname;
|
||
+
|
||
+ goto redo;
|
||
+ }
|
||
+ *result = AllocatePool((StrLen(name) + len + 2)*sizeof(CHAR16));
|
||
+ if (*result) {
|
||
+ StrCpy(*result, name);
|
||
+ if (name[StrLen(name) - 1] != '\\')
|
||
+ StrCat(*result, L"\\");
|
||
+ StrCat(*result, selected);
|
||
+ }
|
||
+
|
||
+ out_free:
|
||
+ FreePool(dmp);
|
||
+ if (entries)
|
||
+ FreePool(entries);
|
||
+ out_free_name:
|
||
+ FreePool(name);
|
||
+}
|
||
diff --git a/efitools/lib/variables.c b/efitools/lib/variables.c
|
||
new file mode 100644
|
||
index 0000000..37bb1c1
|
||
--- /dev/null
|
||
+++ b/efitools/lib/variables.c
|
||
@@ -0,0 +1,340 @@
|
||
+/*
|
||
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
|
||
+ *
|
||
+ * see COPYING file
|
||
+ *
|
||
+ * Portions of this file are a direct cut and paste from Tianocore
|
||
+ * (http://tianocore.sf.net)
|
||
+ *
|
||
+ * SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
|
||
+ *
|
||
+ * Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
|
||
+ * This program and the accompanying materials
|
||
+ * are licensed and made available under the terms and conditions of the BSD License
|
||
+ * 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.
|
||
+ *
|
||
+ */
|
||
+#include <efi.h>
|
||
+#include <efilib.h>
|
||
+
|
||
+#include <efiauthenticated.h>
|
||
+
|
||
+#include <variables.h>
|
||
+#include <guid.h>
|
||
+#include <console.h>
|
||
+#include <sha256.h>
|
||
+#include <errors.h>
|
||
+
|
||
+EFI_STATUS
|
||
+variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
|
||
+ void **out, int *outlen)
|
||
+{
|
||
+ *outlen = cert_len + sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
|
||
+
|
||
+ *out = AllocateZeroPool(*outlen);
|
||
+ if (!*out)
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+
|
||
+ EFI_SIGNATURE_LIST *sl = *out;
|
||
+
|
||
+ sl->SignatureHeaderSize = 0;
|
||
+ sl->SignatureType = *type;
|
||
+ sl->SignatureSize = cert_len + sizeof(EFI_GUID);
|
||
+ sl->SignatureListSize = *outlen;
|
||
+
|
||
+ EFI_SIGNATURE_DATA *sd = *out + sizeof(EFI_SIGNATURE_LIST);
|
||
+
|
||
+ if (owner)
|
||
+ sd->SignatureOwner = *owner;
|
||
+
|
||
+ CopyMem(sd->SignatureData, cert, cert_len);
|
||
+
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
+
|
||
+EFI_STATUS
|
||
+CreateTimeBasedPayload (
|
||
+ IN OUT UINTN *DataSize,
|
||
+ IN OUT UINT8 **Data
|
||
+ )
|
||
+{
|
||
+ EFI_STATUS Status;
|
||
+ UINT8 *NewData;
|
||
+ UINT8 *Payload;
|
||
+ UINTN PayloadSize;
|
||
+ EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData;
|
||
+ UINTN DescriptorSize;
|
||
+ EFI_TIME Time;
|
||
+ EFI_GUID efi_cert_type = EFI_CERT_TYPE_PKCS7_GUID;
|
||
+
|
||
+ if (Data == NULL || DataSize == NULL) {
|
||
+ return EFI_INVALID_PARAMETER;
|
||
+ }
|
||
+
|
||
+ //
|
||
+ // In Setup mode or Custom mode, the variable does not need to be signed but the
|
||
+ // parameters to the SetVariable() call still need to be prepared as authenticated
|
||
+ // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
|
||
+ // data in it.
|
||
+ //
|
||
+ Payload = *Data;
|
||
+ PayloadSize = *DataSize;
|
||
+
|
||
+ DescriptorSize = OFFSET_OF(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData);
|
||
+ NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize);
|
||
+ if (NewData == NULL) {
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+ }
|
||
+
|
||
+ if ((Payload != NULL) && (PayloadSize != 0)) {
|
||
+ CopyMem (NewData + DescriptorSize, Payload, PayloadSize);
|
||
+ }
|
||
+
|
||
+ DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData);
|
||
+
|
||
+ ZeroMem (&Time, sizeof (EFI_TIME));
|
||
+ Status = uefi_call_wrapper(RT->GetTime,2, &Time, NULL);
|
||
+ if (EFI_ERROR (Status)) {
|
||
+ FreePool(NewData);
|
||
+ return Status;
|
||
+ }
|
||
+ Time.Pad1 = 0;
|
||
+ Time.Nanosecond = 0;
|
||
+ Time.TimeZone = 0;
|
||
+ Time.Daylight = 0;
|
||
+ Time.Pad2 = 0;
|
||
+ CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME));
|
||
+
|
||
+ DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
|
||
+ DescriptorData->AuthInfo.Hdr.wRevision = 0x0200;
|
||
+ DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
|
||
+ DescriptorData->AuthInfo.CertType = efi_cert_type;
|
||
+
|
||
+ /* we're expecting an EFI signature list, so don't free the input since
|
||
+ * it might not be in a pool */
|
||
+#if 0
|
||
+ if (Payload != NULL) {
|
||
+ FreePool(Payload);
|
||
+ }
|
||
+#endif
|
||
+
|
||
+ *DataSize = DescriptorSize + PayloadSize;
|
||
+ *Data = NewData;
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner,
|
||
+ UINT32 options, int createtimebased)
|
||
+{
|
||
+ EFI_SIGNATURE_LIST *Cert;
|
||
+ UINTN DataSize;
|
||
+ EFI_STATUS efi_status;
|
||
+
|
||
+ /* Microsoft request: Bugs in some UEFI platforms mean that PK or any
|
||
+ * other secure variable can be updated or deleted programmatically,
|
||
+ * so prevent */
|
||
+ if (!variable_is_setupmode())
|
||
+ return EFI_SECURITY_VIOLATION;
|
||
+
|
||
+ if (createtimebased) {
|
||
+ int ds;
|
||
+ efi_status = variable_create_esl(Data, len, &X509_GUID, NULL,
|
||
+ (void **)&Cert, &ds);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to create %s certificate %d\n", var, efi_status);
|
||
+ return efi_status;
|
||
+ }
|
||
+
|
||
+ DataSize = ds;
|
||
+ } else {
|
||
+ /* we expect an efi signature list rather than creating it */
|
||
+ Cert = (EFI_SIGNATURE_LIST *)Data;
|
||
+ DataSize = len;
|
||
+ }
|
||
+ efi_status = CreateTimeBasedPayload(&DataSize, (UINT8 **)&Cert);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ Print(L"Failed to create time based payload %d\n", efi_status);
|
||
+ return efi_status;
|
||
+ }
|
||
+
|
||
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner,
|
||
+ EFI_VARIABLE_NON_VOLATILE
|
||
+ | EFI_VARIABLE_RUNTIME_ACCESS
|
||
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||
+ | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
|
||
+ | options,
|
||
+ DataSize, Cert);
|
||
+
|
||
+ return efi_status;
|
||
+}
|
||
+
|
||
+UINT64
|
||
+GetOSIndications(void)
|
||
+{
|
||
+ UINT64 indications;
|
||
+ UINTN DataSize = sizeof(indications);
|
||
+ EFI_STATUS efi_status;
|
||
+
|
||
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"OsIndicationsSupported", &GV_GUID, NULL, &DataSize, &indications);
|
||
+ if (efi_status != EFI_SUCCESS)
|
||
+ return 0;
|
||
+
|
||
+ return indications;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+SETOSIndicationsAndReboot(UINT64 indications)
|
||
+{
|
||
+ UINTN DataSize = sizeof(indications);
|
||
+ EFI_STATUS efi_status;
|
||
+
|
||
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"OsIndications",
|
||
+ &GV_GUID,
|
||
+ EFI_VARIABLE_NON_VOLATILE
|
||
+ | EFI_VARIABLE_RUNTIME_ACCESS
|
||
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||
+ DataSize, &indications);
|
||
+
|
||
+ if (efi_status != EFI_SUCCESS)
|
||
+ return efi_status;
|
||
+
|
||
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
||
+ /* does not return */
|
||
+
|
||
+ return EFI_SUCCESS;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+get_variable_attr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
|
||
+ UINT32 *attributes)
|
||
+{
|
||
+ EFI_STATUS efi_status;
|
||
+
|
||
+ *len = 0;
|
||
+
|
||
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
|
||
+ NULL, len, NULL);
|
||
+ if (efi_status != EFI_BUFFER_TOO_SMALL)
|
||
+ return efi_status;
|
||
+
|
||
+ *data = AllocateZeroPool(*len);
|
||
+ if (!data)
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+
|
||
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
|
||
+ attributes, len, *data);
|
||
+
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ FreePool(*data);
|
||
+ *data = NULL;
|
||
+ }
|
||
+ return efi_status;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+get_variable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner)
|
||
+{
|
||
+ return get_variable_attr(var, data, len, owner, NULL);
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+find_in_esl(UINT8 *Data, UINTN DataSize, UINT8 *key, UINTN keylen)
|
||
+{
|
||
+ EFI_SIGNATURE_LIST *CertList;
|
||
+
|
||
+ certlist_for_each_certentry(CertList, Data, DataSize, DataSize) {
|
||
+ if (CertList->SignatureSize != keylen + sizeof(EFI_GUID))
|
||
+ continue;
|
||
+ EFI_SIGNATURE_DATA *Cert;
|
||
+
|
||
+ certentry_for_each_cert(Cert, CertList)
|
||
+ if (CompareMem (Cert->SignatureData, key, keylen) == 0)
|
||
+ return EFI_SUCCESS;
|
||
+ }
|
||
+ return EFI_NOT_FOUND;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+find_in_variable_esl(CHAR16* var, EFI_GUID owner, UINT8 *key, UINTN keylen)
|
||
+{
|
||
+ UINTN DataSize;
|
||
+ UINT8 *Data;
|
||
+ EFI_STATUS status;
|
||
+
|
||
+ status = get_variable(var, &Data, &DataSize, owner);
|
||
+ if (status != EFI_SUCCESS)
|
||
+ return status;
|
||
+
|
||
+ status = find_in_esl(Data, DataSize, key, keylen);
|
||
+
|
||
+ FreePool(Data);
|
||
+
|
||
+ return status;
|
||
+}
|
||
+
|
||
+int
|
||
+variable_is_setupmode(void)
|
||
+{
|
||
+ /* set to 1 because we return true if SetupMode doesn't exist */
|
||
+ UINT8 SetupMode = 1;
|
||
+ UINTN DataSize = sizeof(SetupMode);
|
||
+
|
||
+ uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", &GV_GUID, NULL,
|
||
+ &DataSize, &SetupMode);
|
||
+
|
||
+ return SetupMode;
|
||
+}
|
||
+
|
||
+int
|
||
+variable_is_secureboot(void)
|
||
+{
|
||
+ /* return false if variable doesn't exist */
|
||
+ UINT8 SecureBoot = 0;
|
||
+ UINTN DataSize;
|
||
+
|
||
+ DataSize = sizeof(SecureBoot);
|
||
+ uefi_call_wrapper(RT->GetVariable, 5, L"SecureBoot", &GV_GUID, NULL,
|
||
+ &DataSize, &SecureBoot);
|
||
+
|
||
+ return SecureBoot;
|
||
+}
|
||
+
|
||
+EFI_STATUS
|
||
+variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
|
||
+ UINT8 hash[SHA256_DIGEST_SIZE])
|
||
+{
|
||
+ EFI_STATUS status;
|
||
+
|
||
+ if (find_in_variable_esl(var, owner, hash, SHA256_DIGEST_SIZE)
|
||
+ == EFI_SUCCESS)
|
||
+ /* hash already present */
|
||
+ return EFI_ALREADY_STARTED;
|
||
+
|
||
+ UINT8 sig[sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + SHA256_DIGEST_SIZE];
|
||
+ EFI_SIGNATURE_LIST *l = (void *)sig;
|
||
+ EFI_SIGNATURE_DATA *d = (void *)(sig + sizeof(EFI_SIGNATURE_LIST));
|
||
+ SetMem(sig, sizeof(sig), 0);
|
||
+ l->SignatureType = EFI_CERT_SHA256_GUID;
|
||
+ l->SignatureListSize = sizeof(sig);
|
||
+ l->SignatureSize = 16 +32; /* UEFI defined */
|
||
+ CopyMem(&d->SignatureData, hash, SHA256_DIGEST_SIZE);
|
||
+ d->SignatureOwner = MOK_OWNER;
|
||
+
|
||
+ if (CompareGuid(&owner, &SIG_DB) == 0)
|
||
+ status = SetSecureVariable(var, sig, sizeof(sig), owner,
|
||
+ EFI_VARIABLE_APPEND_WRITE, 0);
|
||
+ else
|
||
+ status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner,
|
||
+ EFI_VARIABLE_NON_VOLATILE
|
||
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||
+ | EFI_VARIABLE_APPEND_WRITE,
|
||
+ sizeof(sig), sig);
|
||
+ return status;
|
||
+}
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From 35556acbc747eac5e22d45324503ffcd002ca9dd Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Wed, 17 Apr 2013 11:20:12 +0800
|
||
Subject: [PATCH 02/12] Adopt the file selector from efitools
|
||
|
||
---
|
||
MokManager.c | 378 +++++++++--------------------------------------------------
|
||
1 file changed, 57 insertions(+), 321 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index e27c2c1..c076b12 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -2,6 +2,8 @@
|
||
#include <efilib.h>
|
||
#include <Library/BaseCryptLib.h>
|
||
#include <openssl/x509.h>
|
||
+#include <console.h>
|
||
+#include <simple_file.h>
|
||
#include "shim.h"
|
||
#include "signature.h"
|
||
#include "PeImage.h"
|
||
@@ -17,8 +19,8 @@
|
||
|
||
#define EFI_VARIABLE_APPEND_WRITE 0x00000040
|
||
|
||
-#define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
|
||
-#define HASH_STRING L"Select a file to trust:\n\n"
|
||
+#define CERT_STRING L"Select an X509 certificate to enroll:"
|
||
+#define HASH_STRING L"Select a file to trust:"
|
||
|
||
struct menu_item {
|
||
CHAR16 *text;
|
||
@@ -1318,8 +1320,6 @@ static UINTN verify_certificate(void *cert, UINTN size)
|
||
|
||
if (!(X509ConstructCertificate(cert, size, (UINT8 **) &X509Cert)) ||
|
||
X509Cert == NULL) {
|
||
- Print(L"Invalid X509 certificate\n");
|
||
- Pause();
|
||
return FALSE;
|
||
}
|
||
|
||
@@ -1327,25 +1327,35 @@ static UINTN verify_certificate(void *cert, UINTN size)
|
||
return TRUE;
|
||
}
|
||
|
||
-static INTN file_callback (void *data, void *data2, void *data3) {
|
||
- EFI_FILE_INFO *buffer = NULL;
|
||
- UINTN buffersize = 0, mokbuffersize;
|
||
- EFI_STATUS status;
|
||
+static INTN find_file (void *data, void *data2, void *data3)
|
||
+{
|
||
+ EFI_HANDLE handle = NULL;
|
||
EFI_FILE *file;
|
||
- CHAR16 *filename = data;
|
||
- EFI_FILE *parent = data2;
|
||
+ EFI_STATUS status;
|
||
+ CHAR16 *title[2];
|
||
+ CHAR16 *filename;
|
||
BOOLEAN hash = !!data3;
|
||
+ EFI_FILE_INFO *buffer = NULL;
|
||
EFI_GUID file_info_guid = EFI_FILE_INFO_ID;
|
||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||
EFI_SIGNATURE_LIST *CertList;
|
||
EFI_SIGNATURE_DATA *CertData;
|
||
+ UINTN buffersize = 0, mokbuffersize;
|
||
void *mokbuffer = NULL;
|
||
|
||
- status = uefi_call_wrapper(parent->Open, 5, parent, &file, filename,
|
||
- EFI_FILE_MODE_READ, 0);
|
||
+ title[0] = hash ? HASH_STRING : CERT_STRING;
|
||
+ title[1] = NULL;
|
||
|
||
- if (status != EFI_SUCCESS)
|
||
- return 1;
|
||
+ simple_file_selector(&handle, title, NULL, NULL, &filename);
|
||
+ if (filename == NULL) {
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ status = simple_file_open(handle, filename, &file, EFI_FILE_MODE_READ);
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_error (L"Failed to open file", status);
|
||
+ return 0;
|
||
+ }
|
||
|
||
status = uefi_call_wrapper(file->GetInfo, 4, file, &file_info_guid,
|
||
&buffersize, buffer);
|
||
@@ -1357,8 +1367,10 @@ static INTN file_callback (void *data, void *data2, void *data3) {
|
||
buffer);
|
||
}
|
||
|
||
- if (!buffer)
|
||
+ if (!buffer) {
|
||
+ console_error (L"Failed to allocate buffer", EFI_OUT_OF_RESOURCES);
|
||
return 0;
|
||
+ }
|
||
|
||
buffersize = buffer->FileSize;
|
||
|
||
@@ -1372,35 +1384,46 @@ static INTN file_callback (void *data, void *data2, void *data3) {
|
||
|
||
status = LibLocateProtocol(&shim_guid, (VOID **)&shim_lock);
|
||
|
||
- if (status != EFI_SUCCESS)
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_error (L"Failed to locate shim protocol", status);
|
||
goto out;
|
||
+ }
|
||
|
||
mokbuffersize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID) +
|
||
SHA256_DIGEST_SIZE;
|
||
|
||
mokbuffer = AllocatePool(mokbuffersize);
|
||
|
||
- if (!mokbuffer)
|
||
+ if (!mokbuffer) {
|
||
+ console_error (L"Failed to allocate mokbuffer",
|
||
+ EFI_OUT_OF_RESOURCES);
|
||
goto out;
|
||
+ }
|
||
|
||
binary = AllocatePool(buffersize);
|
||
|
||
status = uefi_call_wrapper(file->Read, 3, file, &buffersize,
|
||
binary);
|
||
|
||
- if (status != EFI_SUCCESS)
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_error (L"Failed to read file", status);
|
||
goto out;
|
||
+ }
|
||
|
||
status = shim_lock->Context(binary, buffersize, &context);
|
||
|
||
- if (status != EFI_SUCCESS)
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_error (L"Failed to get EFI context", status);
|
||
goto out;
|
||
+ }
|
||
|
||
status = shim_lock->Hash(binary, buffersize, &context, sha256,
|
||
sha1);
|
||
|
||
- if (status != EFI_SUCCESS)
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_error (L"Failed to compute hash", status);
|
||
goto out;
|
||
+ }
|
||
|
||
CertList = mokbuffer;
|
||
CertList->SignatureType = EfiHashSha256Guid;
|
||
@@ -1413,8 +1436,11 @@ static INTN file_callback (void *data, void *data2, void *data3) {
|
||
sizeof(EFI_GUID);
|
||
mokbuffer = AllocatePool(mokbuffersize);
|
||
|
||
- if (!mokbuffer)
|
||
+ if (!mokbuffer) {
|
||
+ console_error (L"Failed to allocate mokbuffer",
|
||
+ EFI_OUT_OF_RESOURCES);
|
||
goto out;
|
||
+ }
|
||
|
||
CertList = mokbuffer;
|
||
CertList->SignatureType = EfiCertX509Guid;
|
||
@@ -1422,8 +1448,10 @@ static INTN file_callback (void *data, void *data2, void *data3) {
|
||
status = uefi_call_wrapper(file->Read, 3, file, &buffersize,
|
||
mokbuffer + sizeof(EFI_SIGNATURE_LIST) + 16);
|
||
|
||
- if (status != EFI_SUCCESS)
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_error (L"Failed to read file", status);
|
||
goto out;
|
||
+ }
|
||
CertData = (EFI_SIGNATURE_DATA *)(((UINT8 *)mokbuffer) +
|
||
sizeof(EFI_SIGNATURE_LIST));
|
||
}
|
||
@@ -1433,8 +1461,11 @@ static INTN file_callback (void *data, void *data2, void *data3) {
|
||
CertData->SignatureOwner = shim_lock_guid;
|
||
|
||
if (!hash) {
|
||
- if (!verify_certificate(CertData->SignatureData, buffersize))
|
||
+ if (!verify_certificate(CertData->SignatureData, buffersize)) {
|
||
+ console_error (L"Not a valid certificate",
|
||
+ EFI_INVALID_PARAMETER);
|
||
goto out;
|
||
+ }
|
||
}
|
||
|
||
mok_enrollment_prompt(mokbuffer, mokbuffersize, FALSE);
|
||
@@ -1445,302 +1476,7 @@ out:
|
||
if (mokbuffer)
|
||
FreePool(mokbuffer);
|
||
|
||
- return 0;
|
||
-}
|
||
-
|
||
-static INTN directory_callback (void *data, void *data2, void *data3) {
|
||
- EFI_FILE_INFO *buffer = NULL;
|
||
- UINTN buffersize = 0;
|
||
- EFI_STATUS status;
|
||
- UINTN dircount = 0, i = 0;
|
||
- struct menu_item *dircontent;
|
||
- EFI_FILE *dir;
|
||
- CHAR16 *filename = data;
|
||
- EFI_FILE *root = data2;
|
||
- BOOLEAN hash = !!data3;
|
||
-
|
||
- status = uefi_call_wrapper(root->Open, 5, root, &dir, filename,
|
||
- EFI_FILE_MODE_READ, 0);
|
||
-
|
||
- if (status != EFI_SUCCESS)
|
||
- return 1;
|
||
-
|
||
- while (1) {
|
||
- status = uefi_call_wrapper(dir->Read, 3, dir, &buffersize,
|
||
- buffer);
|
||
-
|
||
- if (status == EFI_BUFFER_TOO_SMALL) {
|
||
- buffer = AllocatePool(buffersize);
|
||
- status = uefi_call_wrapper(dir->Read, 3, dir,
|
||
- &buffersize, buffer);
|
||
- }
|
||
-
|
||
- if (status != EFI_SUCCESS)
|
||
- return 1;
|
||
-
|
||
- if (!buffersize)
|
||
- break;
|
||
-
|
||
- if ((StrCmp(buffer->FileName, L".") == 0) ||
|
||
- (StrCmp(buffer->FileName, L"..") == 0))
|
||
- continue;
|
||
-
|
||
- dircount++;
|
||
-
|
||
- FreePool(buffer);
|
||
- buffersize = 0;
|
||
- }
|
||
-
|
||
- dircount++;
|
||
-
|
||
- dircontent = AllocatePool(sizeof(struct menu_item) * dircount);
|
||
-
|
||
- dircontent[0].text = StrDuplicate(L"..");
|
||
- dircontent[0].callback = NULL;
|
||
- dircontent[0].colour = EFI_YELLOW;
|
||
- i++;
|
||
-
|
||
- uefi_call_wrapper(dir->SetPosition, 2, dir, 0);
|
||
-
|
||
- while (1) {
|
||
- status = uefi_call_wrapper(dir->Read, 3, dir, &buffersize,
|
||
- buffer);
|
||
-
|
||
- if (status == EFI_BUFFER_TOO_SMALL) {
|
||
- buffer = AllocatePool(buffersize);
|
||
- status = uefi_call_wrapper(dir->Read, 3, dir,
|
||
- &buffersize, buffer);
|
||
- }
|
||
-
|
||
- if (status != EFI_SUCCESS)
|
||
- return 1;
|
||
-
|
||
- if (!buffersize)
|
||
- break;
|
||
-
|
||
- if ((StrCmp(buffer->FileName, L".") == 0) ||
|
||
- (StrCmp(buffer->FileName, L"..") == 0))
|
||
- continue;
|
||
-
|
||
- if (buffer->Attribute & EFI_FILE_DIRECTORY) {
|
||
- dircontent[i].text = StrDuplicate(buffer->FileName);
|
||
- dircontent[i].callback = directory_callback;
|
||
- dircontent[i].data = dircontent[i].text;
|
||
- dircontent[i].data2 = dir;
|
||
- dircontent[i].data3 = data3;
|
||
- dircontent[i].colour = EFI_YELLOW;
|
||
- } else {
|
||
- dircontent[i].text = StrDuplicate(buffer->FileName);
|
||
- dircontent[i].callback = file_callback;
|
||
- dircontent[i].data = dircontent[i].text;
|
||
- dircontent[i].data2 = dir;
|
||
- dircontent[i].data3 = data3;
|
||
- dircontent[i].colour = EFI_WHITE;
|
||
- }
|
||
-
|
||
- i++;
|
||
- FreePool(buffer);
|
||
- buffersize = 0;
|
||
- buffer = NULL;
|
||
- }
|
||
-
|
||
- if (hash)
|
||
- run_menu(HASH_STRING, 2, dircontent, dircount, 0);
|
||
- else
|
||
- run_menu(CERT_STRING, 2, dircontent, dircount, 0);
|
||
-
|
||
- return 0;
|
||
-}
|
||
-
|
||
-static INTN filesystem_callback (void *data, void *data2, void *data3) {
|
||
- EFI_FILE_INFO *buffer = NULL;
|
||
- UINTN buffersize = 0;
|
||
- EFI_STATUS status;
|
||
- UINTN dircount = 0, i = 0;
|
||
- struct menu_item *dircontent;
|
||
- EFI_FILE *root = data;
|
||
- BOOLEAN hash = !!data3;
|
||
-
|
||
- uefi_call_wrapper(root->SetPosition, 2, root, 0);
|
||
-
|
||
- while (1) {
|
||
- status = uefi_call_wrapper(root->Read, 3, root, &buffersize,
|
||
- buffer);
|
||
-
|
||
- if (status == EFI_BUFFER_TOO_SMALL) {
|
||
- buffer = AllocatePool(buffersize);
|
||
- status = uefi_call_wrapper(root->Read, 3, root,
|
||
- &buffersize, buffer);
|
||
- }
|
||
-
|
||
- if (status != EFI_SUCCESS)
|
||
- return 1;
|
||
-
|
||
- if (!buffersize)
|
||
- break;
|
||
-
|
||
- if ((StrCmp(buffer->FileName, L".") == 0) ||
|
||
- (StrCmp(buffer->FileName, L"..") == 0))
|
||
- continue;
|
||
-
|
||
- dircount++;
|
||
-
|
||
- FreePool(buffer);
|
||
- buffersize = 0;
|
||
- }
|
||
-
|
||
- dircount++;
|
||
-
|
||
- dircontent = AllocatePool(sizeof(struct menu_item) * dircount);
|
||
-
|
||
- dircontent[0].text = StrDuplicate(L"Return to filesystem list");
|
||
- dircontent[0].callback = NULL;
|
||
- dircontent[0].colour = EFI_YELLOW;
|
||
- i++;
|
||
-
|
||
- uefi_call_wrapper(root->SetPosition, 2, root, 0);
|
||
-
|
||
- while (1) {
|
||
- status = uefi_call_wrapper(root->Read, 3, root, &buffersize,
|
||
- buffer);
|
||
-
|
||
- if (status == EFI_BUFFER_TOO_SMALL) {
|
||
- buffer = AllocatePool(buffersize);
|
||
- status = uefi_call_wrapper(root->Read, 3, root,
|
||
- &buffersize, buffer);
|
||
- }
|
||
-
|
||
- if (status != EFI_SUCCESS)
|
||
- return 1;
|
||
-
|
||
- if (!buffersize)
|
||
- break;
|
||
-
|
||
- if ((StrCmp(buffer->FileName, L".") == 0) ||
|
||
- (StrCmp(buffer->FileName, L"..") == 0))
|
||
- continue;
|
||
-
|
||
- if (buffer->Attribute & EFI_FILE_DIRECTORY) {
|
||
- dircontent[i].text = StrDuplicate(buffer->FileName);
|
||
- dircontent[i].callback = directory_callback;
|
||
- dircontent[i].data = dircontent[i].text;
|
||
- dircontent[i].data2 = root;
|
||
- dircontent[i].data3 = data3;
|
||
- dircontent[i].colour = EFI_YELLOW;
|
||
- } else {
|
||
- dircontent[i].text = StrDuplicate(buffer->FileName);
|
||
- dircontent[i].callback = file_callback;
|
||
- dircontent[i].data = dircontent[i].text;
|
||
- dircontent[i].data2 = root;
|
||
- dircontent[i].data3 = data3;
|
||
- dircontent[i].colour = EFI_WHITE;
|
||
- }
|
||
-
|
||
- i++;
|
||
- FreePool(buffer);
|
||
- buffer = NULL;
|
||
- buffersize = 0;
|
||
- }
|
||
-
|
||
- if (hash)
|
||
- run_menu(HASH_STRING, 2, dircontent, dircount, 0);
|
||
- else
|
||
- run_menu(CERT_STRING, 2, dircontent, dircount, 0);
|
||
-
|
||
- return 0;
|
||
-}
|
||
-
|
||
-static INTN find_fs (void *data, void *data2, void *data3) {
|
||
- EFI_GUID fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL;
|
||
- UINTN count, i;
|
||
- UINTN OldSize, NewSize;
|
||
- EFI_HANDLE *filesystem_handles = NULL;
|
||
- struct menu_item *filesystems;
|
||
- BOOLEAN hash = !!data3;
|
||
-
|
||
- uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol, &fs_guid,
|
||
- NULL, &count, &filesystem_handles);
|
||
-
|
||
- if (!count || !filesystem_handles) {
|
||
- Print(L"No filesystems?\n");
|
||
- return 1;
|
||
- }
|
||
-
|
||
- count++;
|
||
-
|
||
- filesystems = AllocatePool(sizeof(struct menu_item) * count);
|
||
-
|
||
- filesystems[0].text = StrDuplicate(L"Exit");
|
||
- filesystems[0].callback = NULL;
|
||
- filesystems[0].colour = EFI_YELLOW;
|
||
-
|
||
- for (i=1; i<count; i++) {
|
||
- EFI_HANDLE fs = filesystem_handles[i-1];
|
||
- EFI_FILE_IO_INTERFACE *fs_interface;
|
||
- EFI_DEVICE_PATH *path;
|
||
- EFI_FILE *root;
|
||
- EFI_STATUS status;
|
||
- CHAR16 *VolumeLabel = NULL;
|
||
- EFI_FILE_SYSTEM_INFO *buffer = NULL;
|
||
- UINTN buffersize = 0;
|
||
- EFI_GUID file_info_guid = EFI_FILE_INFO_ID;
|
||
-
|
||
- status = uefi_call_wrapper(BS->HandleProtocol, 3, fs, &fs_guid,
|
||
- (void **)&fs_interface);
|
||
-
|
||
- if (status != EFI_SUCCESS || !fs_interface)
|
||
- continue;
|
||
-
|
||
- path = DevicePathFromHandle(fs);
|
||
-
|
||
- status = uefi_call_wrapper(fs_interface->OpenVolume, 2,
|
||
- fs_interface, &root);
|
||
-
|
||
- if (status != EFI_SUCCESS || !root)
|
||
- continue;
|
||
-
|
||
- status = uefi_call_wrapper(root->GetInfo, 4, root,
|
||
- &file_info_guid, &buffersize,
|
||
- buffer);
|
||
-
|
||
- if (status == EFI_BUFFER_TOO_SMALL) {
|
||
- buffer = AllocatePool(buffersize);
|
||
- status = uefi_call_wrapper(root->GetInfo, 4, root,
|
||
- &file_info_guid,
|
||
- &buffersize, buffer);
|
||
- }
|
||
-
|
||
- if (status == EFI_SUCCESS)
|
||
- VolumeLabel = buffer->VolumeLabel;
|
||
-
|
||
- if (path)
|
||
- filesystems[i].text = DevicePathToStr(path);
|
||
- else
|
||
- filesystems[i].text = StrDuplicate(L"Unknown device\n");
|
||
- if (VolumeLabel) {
|
||
- OldSize = (StrLen(filesystems[i].text) + 1) * sizeof(CHAR16);
|
||
- NewSize = OldSize + StrLen(VolumeLabel) * sizeof(CHAR16);
|
||
- filesystems[i].text = ReallocatePool(filesystems[i].text,
|
||
- OldSize, NewSize);
|
||
- StrCat(filesystems[i].text, VolumeLabel);
|
||
- }
|
||
-
|
||
- if (buffersize)
|
||
- FreePool(buffer);
|
||
-
|
||
- filesystems[i].data = root;
|
||
- filesystems[i].data2 = NULL;
|
||
- filesystems[i].data3 = data3;
|
||
- filesystems[i].callback = filesystem_callback;
|
||
- filesystems[i].colour = EFI_YELLOW;
|
||
- }
|
||
-
|
||
- uefi_call_wrapper(BS->FreePool, 1, filesystem_handles);
|
||
-
|
||
- if (hash)
|
||
- run_menu(HASH_STRING, 2, filesystems, count, 0);
|
||
- else
|
||
- run_menu(CERT_STRING, 2, filesystems, count, 0);
|
||
+ simple_file_close(file);
|
||
|
||
return 0;
|
||
}
|
||
@@ -1888,14 +1624,14 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
|
||
menu_item[i].text = StrDuplicate(L"Enroll key from disk");
|
||
menu_item[i].colour = EFI_WHITE;
|
||
- menu_item[i].callback = find_fs;
|
||
+ menu_item[i].callback = find_file;
|
||
menu_item[i].data3 = (void *)FALSE;
|
||
|
||
i++;
|
||
|
||
menu_item[i].text = StrDuplicate(L"Enroll hash from disk");
|
||
menu_item[i].colour = EFI_WHITE;
|
||
- menu_item[i].callback = find_fs;
|
||
+ menu_item[i].callback = find_file;
|
||
menu_item[i].data3 = (void *)TRUE;
|
||
|
||
i++;
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From 87a2148636e2616bb586ee95ad942f5a3eac8905 Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Wed, 17 Apr 2013 18:00:13 +0800
|
||
Subject: [PATCH 03/12] Drop kernel_efivars.h
|
||
|
||
It's not for EFI programs
|
||
---
|
||
efitools/include/kernel_efivars.h | 26 --------------------------
|
||
1 file changed, 26 deletions(-)
|
||
delete mode 100644 efitools/include/kernel_efivars.h
|
||
|
||
diff --git a/efitools/include/kernel_efivars.h b/efitools/include/kernel_efivars.h
|
||
deleted file mode 100644
|
||
index 1f5dfa0..0000000
|
||
--- a/efitools/include/kernel_efivars.h
|
||
+++ /dev/null
|
||
@@ -1,26 +0,0 @@
|
||
-#include <variables_iterators.h>
|
||
-#include <sha256.h>
|
||
-void
|
||
-kernel_variable_init(void);
|
||
-int
|
||
-get_variable(const char *var, EFI_GUID *guid, uint32_t *attributes,
|
||
- uint32_t *size, void *buf);
|
||
-int
|
||
-get_variable_alloc(const char *var, EFI_GUID *guid, uint32_t *attributes,
|
||
- uint32_t *size, uint8_t **buf);
|
||
-int
|
||
-variable_is_setupmode(void);
|
||
-int
|
||
-variable_is_secureboot(void);
|
||
-int
|
||
-set_variable(const char *var, EFI_GUID *guid, uint32_t attributes,
|
||
- uint32_t size, void *buf);
|
||
-int
|
||
-set_variable_esl(const char *var, EFI_GUID *guid, uint32_t attributes,
|
||
- uint32_t size, void *buf);
|
||
-int
|
||
-set_variable_hash(const char *var, EFI_GUID *owner, uint32_t attributes,
|
||
- uint8_t hash[SHA256_DIGEST_SIZE]);
|
||
-uint8_t *
|
||
-hash_to_esl(EFI_GUID *owner, int *len,
|
||
- uint8_t hash[SHA256_DIGEST_SIZE]);
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From cb9bf99ef9ffef2b7921dd7d743ec1eb357095fc Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Wed, 8 May 2013 11:07:55 +0800
|
||
Subject: [PATCH 04/12] Update efitools COPYING
|
||
|
||
---
|
||
efitools/COPYING | 513 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||
1 file changed, 512 insertions(+), 1 deletion(-)
|
||
|
||
diff --git a/efitools/COPYING b/efitools/COPYING
|
||
index 7737e63..454bd72 100644
|
||
--- a/efitools/COPYING
|
||
+++ b/efitools/COPYING
|
||
@@ -6,7 +6,13 @@ All of these programs are made available under version 2 of the GNU General
|
||
Public Licence. The library routines in lib/ are made available under the GNU
|
||
Lesser General Public Licence version 2.1. Additionally for linking the
|
||
programme files with openSSL, there is an additional permission that
|
||
-compiling, linking, and/or using OpenSSL is allowed.
|
||
+compiling, linking, and/or using OpenSSL is allowed. Contributing Authors
|
||
+agree that their code is submitted under the licence appropriate for its
|
||
+location within the source tree (GPL except for LGPL in lib/) and agree that
|
||
+any future patches, provided they are accepted into the project, may change
|
||
+the licence of their code from GPL to LGPL by moving pieces of it into lib/ or
|
||
+LGPL to GPL by moving pieces of it out of lib/
|
||
+
|
||
|
||
GNU GENERAL PUBLIC LICENSE
|
||
Version 2, June 1991
|
||
@@ -348,3 +354,508 @@ 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.
|
||
+
|
||
+---------------------------------------
|
||
+
|
||
+ GNU LESSER GENERAL PUBLIC LICENSE
|
||
+ Version 2.1, February 1999
|
||
+
|
||
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||
+ 51 Franklin Street, 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.
|
||
+
|
||
+[This is the first released version of the Lesser GPL. It also counts
|
||
+ as the successor of the GNU Library Public License, version 2, hence
|
||
+ the version number 2.1.]
|
||
+
|
||
+ Preamble
|
||
+
|
||
+ The licenses for most software are designed to take away your
|
||
+freedom to share and change it. By contrast, the GNU General Public
|
||
+Licenses are intended to guarantee your freedom to share and change
|
||
+free software--to make sure the software is free for all its users.
|
||
+
|
||
+ This license, the Lesser General Public License, applies to some
|
||
+specially designated software packages--typically libraries--of the
|
||
+Free Software Foundation and other authors who decide to use it. You
|
||
+can use it too, but we suggest you first think carefully about whether
|
||
+this license or the ordinary General Public License is the better
|
||
+strategy to use in any particular case, based on the explanations below.
|
||
+
|
||
+ When we speak of free software, we are referring to freedom of use,
|
||
+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 and use pieces of
|
||
+it in new free programs; and that you are informed that you can do
|
||
+these things.
|
||
+
|
||
+ To protect your rights, we need to make restrictions that forbid
|
||
+distributors to deny you these rights or to ask you to surrender these
|
||
+rights. These restrictions translate to certain responsibilities for
|
||
+you if you distribute copies of the library or if you modify it.
|
||
+
|
||
+ For example, if you distribute copies of the library, whether gratis
|
||
+or for a fee, you must give the recipients all the rights that we gave
|
||
+you. You must make sure that they, too, receive or can get the source
|
||
+code. If you link other code with the library, you must provide
|
||
+complete object files to the recipients, so that they can relink them
|
||
+with the library after making changes to the library and recompiling
|
||
+it. And you must show them these terms so they know their rights.
|
||
+
|
||
+ We protect your rights with a two-step method: (1) we copyright the
|
||
+library, and (2) we offer you this license, which gives you legal
|
||
+permission to copy, distribute and/or modify the library.
|
||
+
|
||
+ To protect each distributor, we want to make it very clear that
|
||
+there is no warranty for the free library. Also, if the library is
|
||
+modified by someone else and passed on, the recipients should know
|
||
+that what they have is not the original version, so that the original
|
||
+author's reputation will not be affected by problems that might be
|
||
+introduced by others.
|
||
+
|
||
+ Finally, software patents pose a constant threat to the existence of
|
||
+any free program. We wish to make sure that a company cannot
|
||
+effectively restrict the users of a free program by obtaining a
|
||
+restrictive license from a patent holder. Therefore, we insist that
|
||
+any patent license obtained for a version of the library must be
|
||
+consistent with the full freedom of use specified in this license.
|
||
+
|
||
+ Most GNU software, including some libraries, is covered by the
|
||
+ordinary GNU General Public License. This license, the GNU Lesser
|
||
+General Public License, applies to certain designated libraries, and
|
||
+is quite different from the ordinary General Public License. We use
|
||
+this license for certain libraries in order to permit linking those
|
||
+libraries into non-free programs.
|
||
+
|
||
+ When a program is linked with a library, whether statically or using
|
||
+a shared library, the combination of the two is legally speaking a
|
||
+combined work, a derivative of the original library. The ordinary
|
||
+General Public License therefore permits such linking only if the
|
||
+entire combination fits its criteria of freedom. The Lesser General
|
||
+Public License permits more lax criteria for linking other code with
|
||
+the library.
|
||
+
|
||
+ We call this license the "Lesser" General Public License because it
|
||
+does Less to protect the user's freedom than the ordinary General
|
||
+Public License. It also provides other free software developers Less
|
||
+of an advantage over competing non-free programs. These disadvantages
|
||
+are the reason we use the ordinary General Public License for many
|
||
+libraries. However, the Lesser license provides advantages in certain
|
||
+special circumstances.
|
||
+
|
||
+ For example, on rare occasions, there may be a special need to
|
||
+encourage the widest possible use of a certain library, so that it becomes
|
||
+a de-facto standard. To achieve this, non-free programs must be
|
||
+allowed to use the library. A more frequent case is that a free
|
||
+library does the same job as widely used non-free libraries. In this
|
||
+case, there is little to gain by limiting the free library to free
|
||
+software only, so we use the Lesser General Public License.
|
||
+
|
||
+ In other cases, permission to use a particular library in non-free
|
||
+programs enables a greater number of people to use a large body of
|
||
+free software. For example, permission to use the GNU C Library in
|
||
+non-free programs enables many more people to use the whole GNU
|
||
+operating system, as well as its variant, the GNU/Linux operating
|
||
+system.
|
||
+
|
||
+ Although the Lesser General Public License is Less protective of the
|
||
+users' freedom, it does ensure that the user of a program that is
|
||
+linked with the Library has the freedom and the wherewithal to run
|
||
+that program using a modified version of the Library.
|
||
+
|
||
+ The precise terms and conditions for copying, distribution and
|
||
+modification follow. Pay close attention to the difference between a
|
||
+"work based on the library" and a "work that uses the library". The
|
||
+former contains code derived from the library, whereas the latter must
|
||
+be combined with the library in order to run.
|
||
+
|
||
+ GNU LESSER GENERAL PUBLIC LICENSE
|
||
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||
+
|
||
+ 0. This License Agreement applies to any software library or other
|
||
+program which contains a notice placed by the copyright holder or
|
||
+other authorized party saying it may be distributed under the terms of
|
||
+this Lesser General Public License (also called "this License").
|
||
+Each licensee is addressed as "you".
|
||
+
|
||
+ A "library" means a collection of software functions and/or data
|
||
+prepared so as to be conveniently linked with application programs
|
||
+(which use some of those functions and data) to form executables.
|
||
+
|
||
+ The "Library", below, refers to any such software library or work
|
||
+which has been distributed under these terms. A "work based on the
|
||
+Library" means either the Library or any derivative work under
|
||
+copyright law: that is to say, a work containing the Library or a
|
||
+portion of it, either verbatim or with modifications and/or translated
|
||
+straightforwardly into another language. (Hereinafter, translation is
|
||
+included without limitation in the term "modification".)
|
||
+
|
||
+ "Source code" for a work means the preferred form of the work for
|
||
+making modifications to it. For a library, 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 library.
|
||
+
|
||
+ Activities other than copying, distribution and modification are not
|
||
+covered by this License; they are outside its scope. The act of
|
||
+running a program using the Library is not restricted, and output from
|
||
+such a program is covered only if its contents constitute a work based
|
||
+on the Library (independent of the use of the Library in a tool for
|
||
+writing it). Whether that is true depends on what the Library does
|
||
+and what the program that uses the Library does.
|
||
+
|
||
+ 1. You may copy and distribute verbatim copies of the Library's
|
||
+complete 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 distribute a copy of this License along with the
|
||
+Library.
|
||
+
|
||
+ 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 Library or any portion
|
||
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||
+
|
||
+ b) You must cause the files modified to carry prominent notices
|
||
+ stating that you changed the files and the date of any change.
|
||
+
|
||
+ c) You must cause the whole of the work to be licensed at no
|
||
+ charge to all third parties under the terms of this License.
|
||
+
|
||
+ d) If a facility in the modified Library refers to a function or a
|
||
+ table of data to be supplied by an application program that uses
|
||
+ the facility, other than as an argument passed when the facility
|
||
+ is invoked, then you must make a good faith effort to ensure that,
|
||
+ in the event an application does not supply such function or
|
||
+ table, the facility still operates, and performs whatever part of
|
||
+ its purpose remains meaningful.
|
||
+
|
||
+ (For example, a function in a library to compute square roots has
|
||
+ a purpose that is entirely well-defined independent of the
|
||
+ application. Therefore, Subsection 2d requires that any
|
||
+ application-supplied function or table used by this function must
|
||
+ be optional: if the application does not supply it, the square
|
||
+ root function must still compute square roots.)
|
||
+
|
||
+These requirements apply to the modified work as a whole. If
|
||
+identifiable sections of that work are not derived from the Library,
|
||
+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 Library, 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 Library.
|
||
+
|
||
+In addition, mere aggregation of another work not based on the Library
|
||
+with the Library (or with a work based on the Library) on a volume of
|
||
+a storage or distribution medium does not bring the other work under
|
||
+the scope of this License.
|
||
+
|
||
+ 3. You may opt to apply the terms of the ordinary GNU General Public
|
||
+License instead of this License to a given copy of the Library. To do
|
||
+this, you must alter all the notices that refer to this License, so
|
||
+that they refer to the ordinary GNU General Public License, version 2,
|
||
+instead of to this License. (If a newer version than version 2 of the
|
||
+ordinary GNU General Public License has appeared, then you can specify
|
||
+that version instead if you wish.) Do not make any other change in
|
||
+these notices.
|
||
+
|
||
+ Once this change is made in a given copy, it is irreversible for
|
||
+that copy, so the ordinary GNU General Public License applies to all
|
||
+subsequent copies and derivative works made from that copy.
|
||
+
|
||
+ This option is useful when you wish to copy part of the code of
|
||
+the Library into a program that is not a library.
|
||
+
|
||
+ 4. You may copy and distribute the Library (or a portion or
|
||
+derivative of it, under Section 2) in object code or executable form
|
||
+under the terms of Sections 1 and 2 above provided that you 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.
|
||
+
|
||
+ If distribution of 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 satisfies the requirement to
|
||
+distribute the source code, even though third parties are not
|
||
+compelled to copy the source along with the object code.
|
||
+
|
||
+ 5. A program that contains no derivative of any portion of the
|
||
+Library, but is designed to work with the Library by being compiled or
|
||
+linked with it, is called a "work that uses the Library". Such a
|
||
+work, in isolation, is not a derivative work of the Library, and
|
||
+therefore falls outside the scope of this License.
|
||
+
|
||
+ However, linking a "work that uses the Library" with the Library
|
||
+creates an executable that is a derivative of the Library (because it
|
||
+contains portions of the Library), rather than a "work that uses the
|
||
+library". The executable is therefore covered by this License.
|
||
+Section 6 states terms for distribution of such executables.
|
||
+
|
||
+ When a "work that uses the Library" uses material from a header file
|
||
+that is part of the Library, the object code for the work may be a
|
||
+derivative work of the Library even though the source code is not.
|
||
+Whether this is true is especially significant if the work can be
|
||
+linked without the Library, or if the work is itself a library. The
|
||
+threshold for this to be true is not precisely defined by law.
|
||
+
|
||
+ If such an object file uses only numerical parameters, data
|
||
+structure layouts and accessors, and small macros and small inline
|
||
+functions (ten lines or less in length), then the use of the object
|
||
+file is unrestricted, regardless of whether it is legally a derivative
|
||
+work. (Executables containing this object code plus portions of the
|
||
+Library will still fall under Section 6.)
|
||
+
|
||
+ Otherwise, if the work is a derivative of the Library, you may
|
||
+distribute the object code for the work under the terms of Section 6.
|
||
+Any executables containing that work also fall under Section 6,
|
||
+whether or not they are linked directly with the Library itself.
|
||
+
|
||
+ 6. As an exception to the Sections above, you may also combine or
|
||
+link a "work that uses the Library" with the Library to produce a
|
||
+work containing portions of the Library, and distribute that work
|
||
+under terms of your choice, provided that the terms permit
|
||
+modification of the work for the customer's own use and reverse
|
||
+engineering for debugging such modifications.
|
||
+
|
||
+ You must give prominent notice with each copy of the work that the
|
||
+Library is used in it and that the Library and its use are covered by
|
||
+this License. You must supply a copy of this License. If the work
|
||
+during execution displays copyright notices, you must include the
|
||
+copyright notice for the Library among them, as well as a reference
|
||
+directing the user to the copy of this License. Also, you must do one
|
||
+of these things:
|
||
+
|
||
+ a) Accompany the work with the complete corresponding
|
||
+ machine-readable source code for the Library including whatever
|
||
+ changes were used in the work (which must be distributed under
|
||
+ Sections 1 and 2 above); and, if the work is an executable linked
|
||
+ with the Library, with the complete machine-readable "work that
|
||
+ uses the Library", as object code and/or source code, so that the
|
||
+ user can modify the Library and then relink to produce a modified
|
||
+ executable containing the modified Library. (It is understood
|
||
+ that the user who changes the contents of definitions files in the
|
||
+ Library will not necessarily be able to recompile the application
|
||
+ to use the modified definitions.)
|
||
+
|
||
+ b) Use a suitable shared library mechanism for linking with the
|
||
+ Library. A suitable mechanism is one that (1) uses at run time a
|
||
+ copy of the library already present on the user's computer system,
|
||
+ rather than copying library functions into the executable, and (2)
|
||
+ will operate properly with a modified version of the library, if
|
||
+ the user installs one, as long as the modified version is
|
||
+ interface-compatible with the version that the work was made with.
|
||
+
|
||
+ c) Accompany the work with a written offer, valid for at
|
||
+ least three years, to give the same user the materials
|
||
+ specified in Subsection 6a, above, for a charge no more
|
||
+ than the cost of performing this distribution.
|
||
+
|
||
+ d) If distribution of the work is made by offering access to copy
|
||
+ from a designated place, offer equivalent access to copy the above
|
||
+ specified materials from the same place.
|
||
+
|
||
+ e) Verify that the user has already received a copy of these
|
||
+ materials or that you have already sent this user a copy.
|
||
+
|
||
+ For an executable, the required form of the "work that uses the
|
||
+Library" must include any data and utility programs needed for
|
||
+reproducing the executable from it. However, as a special exception,
|
||
+the materials to be 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.
|
||
+
|
||
+ It may happen that this requirement contradicts the license
|
||
+restrictions of other proprietary libraries that do not normally
|
||
+accompany the operating system. Such a contradiction means you cannot
|
||
+use both them and the Library together in an executable that you
|
||
+distribute.
|
||
+
|
||
+ 7. You may place library facilities that are a work based on the
|
||
+Library side-by-side in a single library together with other library
|
||
+facilities not covered by this License, and distribute such a combined
|
||
+library, provided that the separate distribution of the work based on
|
||
+the Library and of the other library facilities is otherwise
|
||
+permitted, and provided that you do these two things:
|
||
+
|
||
+ a) Accompany the combined library with a copy of the same work
|
||
+ based on the Library, uncombined with any other library
|
||
+ facilities. This must be distributed under the terms of the
|
||
+ Sections above.
|
||
+
|
||
+ b) Give prominent notice with the combined library of the fact
|
||
+ that part of it is a work based on the Library, and explaining
|
||
+ where to find the accompanying uncombined form of the same work.
|
||
+
|
||
+ 8. You may not copy, modify, sublicense, link with, or distribute
|
||
+the Library except as expressly provided under this License. Any
|
||
+attempt otherwise to copy, modify, sublicense, link with, or
|
||
+distribute the Library 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.
|
||
+
|
||
+ 9. 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 Library or its derivative works. These actions are
|
||
+prohibited by law if you do not accept this License. Therefore, by
|
||
+modifying or distributing the Library (or any work based on the
|
||
+Library), you indicate your acceptance of this License to do so, and
|
||
+all its terms and conditions for copying, distributing or modifying
|
||
+the Library or works based on it.
|
||
+
|
||
+ 10. Each time you redistribute the Library (or any work based on the
|
||
+Library), the recipient automatically receives a license from the
|
||
+original licensor to copy, distribute, link with or modify the Library
|
||
+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 with
|
||
+this License.
|
||
+
|
||
+ 11. 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 Library at all. For example, if a patent
|
||
+license would not permit royalty-free redistribution of the Library 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 Library.
|
||
+
|
||
+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.
|
||
+
|
||
+ 12. If the distribution and/or use of the Library is restricted in
|
||
+certain countries either by patents or by copyrighted interfaces, the
|
||
+original copyright holder who places the Library 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.
|
||
+
|
||
+ 13. The Free Software Foundation may publish revised and/or new
|
||
+versions of the Lesser 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 Library
|
||
+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 Library does not specify a
|
||
+license version number, you may choose any version ever published by
|
||
+the Free Software Foundation.
|
||
+
|
||
+ 14. If you wish to incorporate parts of the Library into other free
|
||
+programs whose distribution conditions are incompatible with these,
|
||
+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
|
||
+
|
||
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||
+OTHER PARTIES PROVIDE THE LIBRARY "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
|
||
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||
+
|
||
+ 16. 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 LIBRARY 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
|
||
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||
+DAMAGES.
|
||
+
|
||
+ END OF TERMS AND CONDITIONS
|
||
+
|
||
+ How to Apply These Terms to Your New Libraries
|
||
+
|
||
+ If you develop a new library, and you want it to be of the greatest
|
||
+possible use to the public, we recommend making it free software that
|
||
+everyone can redistribute and change. You can do so by permitting
|
||
+redistribution under these terms (or, alternatively, under the terms of the
|
||
+ordinary General Public License).
|
||
+
|
||
+ To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
|
||
+ Copyright (C) <year> <name of author>
|
||
+
|
||
+ This library is free software; you can redistribute it and/or
|
||
+ modify it under the terms of the GNU Lesser General Public
|
||
+ License as published by the Free Software Foundation; either
|
||
+ version 2.1 of the License, or (at your option) any later version.
|
||
+
|
||
+ This library 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
|
||
+ Lesser General Public License for more details.
|
||
+
|
||
+ You should have received a copy of the GNU Lesser General Public
|
||
+ License along with this library; if not, write to the Free Software
|
||
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||
+
|
||
+Also add information on how to contact you by electronic and paper mail.
|
||
+
|
||
+You should also get your employer (if you work as a programmer) or your
|
||
+school, if any, to sign a "copyright disclaimer" for the library, if
|
||
+necessary. Here is a sample; alter the names:
|
||
+
|
||
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||
+
|
||
+ <signature of Ty Coon>, 1 April 1990
|
||
+ Ty Coon, President of Vice
|
||
+
|
||
+That's all there is to it!
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From f23279283a3540dc3921e808a75603e9818acda5 Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Fri, 3 May 2013 16:15:04 +0800
|
||
Subject: [PATCH 05/12] simple_file: Allocate buffers for file entries
|
||
|
||
The dir filter appends L'/' to the directory entries without
|
||
allocating a new buffer, and this could crash the whole program.
|
||
---
|
||
efitools/lib/simple_file.c | 42 ++++++++++++++++++++++++++++++++++--------
|
||
1 file changed, 34 insertions(+), 8 deletions(-)
|
||
|
||
diff --git a/efitools/lib/simple_file.c b/efitools/lib/simple_file.c
|
||
index 0e5ecd2..e288272 100644
|
||
--- a/efitools/lib/simple_file.c
|
||
+++ b/efitools/lib/simple_file.c
|
||
@@ -344,9 +344,12 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
|
||
goto next;
|
||
|
||
if (next->Attribute & EFI_FILE_DIRECTORY) {
|
||
- (*result)[(*count)] = next->FileName;
|
||
- (*result)[(*count)][len] = '/';
|
||
- (*result)[(*count)++][len + 1] = '\0';
|
||
+ (*result)[(*count)] = PoolPrint(L"%s/", next->FileName);
|
||
+ if (!(*result)[(*count)]) {
|
||
+ Print(L"Failed to allocate buffer");
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+ }
|
||
+ (*count)++;
|
||
goto next;
|
||
}
|
||
|
||
@@ -354,7 +357,12 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
|
||
offs = StrLen(filterarr[c]);
|
||
|
||
if (StrCmp(&next->FileName[len - offs], filterarr[c]) == 0) {
|
||
- (*result)[(*count)++] = next->FileName;
|
||
+ (*result)[(*count)] = StrDuplicate(next->FileName);
|
||
+ if (!(*result)[(*count)]) {
|
||
+ Print(L"Failed to allocate buffer");
|
||
+ return EFI_OUT_OF_RESOURCES;
|
||
+ }
|
||
+ (*count)++;
|
||
} else {
|
||
continue;
|
||
}
|
||
@@ -362,7 +370,7 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
|
||
}
|
||
|
||
next:
|
||
- if (StrCmp(next->FileName, L"../") == 0) {
|
||
+ if (StrCmp(next->FileName, L"..") == 0) {
|
||
/* place .. directory first */
|
||
CHAR16 *tmp = (*result)[(*count) - 1];
|
||
|
||
@@ -392,6 +400,15 @@ simple_dir_filter(EFI_HANDLE image, CHAR16 *name, CHAR16 *filter,
|
||
return status;
|
||
}
|
||
|
||
+static void
|
||
+free_entries(CHAR16 **entries, int count)
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i<count; i++)
|
||
+ FreePool(entries[i]);
|
||
+}
|
||
+
|
||
void
|
||
simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
CHAR16 *filter, CHAR16 **result)
|
||
@@ -436,8 +453,6 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
/* ESC key */
|
||
goto out_free;
|
||
selected = entries[select];
|
||
- FreePool(entries);
|
||
- entries = NULL;
|
||
/* note that memory used by selected is valid until dmp is freed */
|
||
len = StrLen(selected);
|
||
if (selected[len - 1] == '/') {
|
||
@@ -445,6 +460,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
|
||
/* stay where we are */
|
||
if (StrCmp(selected, L"./") == 0) {
|
||
+ free_entries(entries, count);
|
||
+ FreePool(entries);
|
||
+ entries = NULL;
|
||
FreePool(dmp);
|
||
goto redo;
|
||
} else if (StrCmp(selected, L"../") == 0) {
|
||
@@ -463,6 +481,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
if (StrCmp(name, L"\\") != 0
|
||
&& StrCmp(&name[i], L"..") != 0) {
|
||
name[i] = '\0';
|
||
+ free_entries(entries, count);
|
||
+ FreePool(entries);
|
||
+ entries = NULL;
|
||
FreePool(dmp);
|
||
goto redo;
|
||
}
|
||
@@ -478,6 +499,9 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
/* remove trailing / */
|
||
newname[StrLen(newname) - 1] = '\0';
|
||
|
||
+ free_entries(entries, count);
|
||
+ FreePool(entries);
|
||
+ entries = NULL;
|
||
FreePool(dmp);
|
||
FreePool(name);
|
||
name = newname;
|
||
@@ -494,8 +518,10 @@ simple_file_selector(EFI_HANDLE *im, CHAR16 **title, CHAR16 *name,
|
||
|
||
out_free:
|
||
FreePool(dmp);
|
||
- if (entries)
|
||
+ if (entries) {
|
||
+ free_entries(entries, count);
|
||
FreePool(entries);
|
||
+ }
|
||
out_free_name:
|
||
FreePool(name);
|
||
}
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From ff426e1d703de40eb7b6cd6ddfb00600c44613df Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Thu, 18 Apr 2013 17:13:12 +0800
|
||
Subject: [PATCH 06/12] Improve the MokManager menu
|
||
|
||
---
|
||
MokManager.c | 207 ++++++++++++++++++++---------------------------------------
|
||
1 file changed, 71 insertions(+), 136 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index c076b12..c1a726d 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -23,12 +23,10 @@
|
||
#define HASH_STRING L"Select a file to trust:"
|
||
|
||
struct menu_item {
|
||
- CHAR16 *text;
|
||
INTN (* callback)(void *data, void *data2, void *data3);
|
||
void *data;
|
||
void *data2;
|
||
void *data3;
|
||
- UINTN colour;
|
||
};
|
||
|
||
typedef struct {
|
||
@@ -1177,139 +1175,61 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
|
||
return 0;
|
||
}
|
||
|
||
-static UINTN draw_menu (CHAR16 *header, UINTN lines, struct menu_item *items,
|
||
- UINTN count) {
|
||
- UINTN i;
|
||
-
|
||
- uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||
-
|
||
- uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
||
- EFI_WHITE | EFI_BACKGROUND_BLACK);
|
||
-
|
||
- Print(L"%s UEFI key management\n\n", SHIM_VENDOR);
|
||
-
|
||
- if (header)
|
||
- Print(L"%s", header);
|
||
-
|
||
- for (i = 0; i < count; i++) {
|
||
- uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
||
- items[i].colour | EFI_BACKGROUND_BLACK);
|
||
- Print(L" %s\n", items[i].text);
|
||
- }
|
||
-
|
||
- uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, 0);
|
||
- uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, TRUE);
|
||
-
|
||
- return 2 + lines;
|
||
-}
|
||
-
|
||
-static void free_menu (struct menu_item *items, UINTN count) {
|
||
- UINTN i;
|
||
-
|
||
- for (i=0; i<count; i++) {
|
||
- if (items[i].text)
|
||
- FreePool(items[i].text);
|
||
- }
|
||
-
|
||
- FreePool(items);
|
||
-}
|
||
-
|
||
-static void update_time (UINTN position, UINTN timeout)
|
||
+static int draw_countdown()
|
||
{
|
||
- uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0,
|
||
- position);
|
||
-
|
||
- uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
||
- EFI_BLACK | EFI_BACKGROUND_BLACK);
|
||
-
|
||
- Print(L" ", timeout);
|
||
-
|
||
- uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0,
|
||
- position);
|
||
+ 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 enter management menu";
|
||
+ int timeout = 10, wait = 10000000;
|
||
|
||
+ CopyMem(&SavedMode, ST->ConOut->Mode, sizeof(SavedMode));
|
||
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
|
||
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
||
- EFI_WHITE | EFI_BACKGROUND_BLACK);
|
||
-
|
||
- if (timeout > 1)
|
||
- Print(L"Booting in %d seconds\n", timeout);
|
||
- else if (timeout)
|
||
- Print(L"Booting in %d second\n", timeout);
|
||
-}
|
||
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
||
|
||
-static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items,
|
||
- UINTN count, UINTN timeout) {
|
||
- UINTN index, pos = 0, wait = 0, offset;
|
||
- EFI_INPUT_KEY key;
|
||
- EFI_STATUS status;
|
||
- INTN ret;
|
||
+ title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
|
||
+ title[1] = NULL;
|
||
|
||
- if (timeout)
|
||
- wait = 10000000;
|
||
+ console_print_box_at(title, -1, 0, 0, -1, -1, 1, 1);
|
||
|
||
- offset = draw_menu (header, lines, items, count);
|
||
+ 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) {
|
||
- update_time(count + offset + 1, timeout);
|
||
+ 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);
|
||
|
||
- uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut,
|
||
- 0, pos + offset);
|
||
status = WaitForSingleEvent(ST->ConIn->WaitForKey, wait);
|
||
|
||
- if (status == EFI_TIMEOUT) {
|
||
- timeout--;
|
||
- if (!timeout) {
|
||
- free_menu(items, count);
|
||
- return;
|
||
- }
|
||
- continue;
|
||
- }
|
||
-
|
||
- wait = 0;
|
||
- timeout = 0;
|
||
-
|
||
- uefi_call_wrapper(BS->WaitForEvent, 3, 1,
|
||
- &ST->ConIn->WaitForKey, &index);
|
||
- uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn,
|
||
- &key);
|
||
-
|
||
- switch(key.ScanCode) {
|
||
- case SCAN_UP:
|
||
- if (pos == 0)
|
||
- continue;
|
||
- pos--;
|
||
- continue;
|
||
- break;
|
||
- case SCAN_DOWN:
|
||
- if (pos == (count - 1))
|
||
- continue;
|
||
- pos++;
|
||
- continue;
|
||
+ if (status != EFI_TIMEOUT) {
|
||
+ /* Clear the key in the queue */
|
||
+ uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
|
||
+ ST->ConIn, &key);
|
||
break;
|
||
}
|
||
|
||
- switch(key.UnicodeChar) {
|
||
- case CHAR_LINEFEED:
|
||
- case CHAR_CARRIAGE_RETURN:
|
||
- if (items[pos].callback == NULL) {
|
||
- free_menu(items, count);
|
||
- return;
|
||
- }
|
||
-
|
||
- ret = items[pos].callback(items[pos].data,
|
||
- items[pos].data2,
|
||
- items[pos].data3);
|
||
- if (ret < 0) {
|
||
- Print(L"Press a key to continue\n");
|
||
- Pause();
|
||
- /* Clear the key in the queue */
|
||
- uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
|
||
- ST->ConIn, &key);
|
||
- }
|
||
- draw_menu (header, lines, items, count);
|
||
- pos = 0;
|
||
+ timeout--;
|
||
+ if (!timeout)
|
||
break;
|
||
- }
|
||
}
|
||
+
|
||
+ FreePool(title[0]);
|
||
+
|
||
+ /* Restore everything */
|
||
+ 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);
|
||
+
|
||
+ return timeout;
|
||
}
|
||
|
||
static UINTN verify_certificate(void *cert, UINTN size)
|
||
@@ -1529,6 +1449,8 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
void *MokPW, UINTN MokPWSize)
|
||
{
|
||
struct menu_item *menu_item;
|
||
+ CHAR16 *title[2], **item_text;
|
||
+ int opt;
|
||
UINT32 MokAuth = 0;
|
||
UINT32 MokDelAuth = 0;
|
||
UINTN menucount = 3, i = 0;
|
||
@@ -1570,24 +1492,22 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
menucount++;
|
||
|
||
menu_item = AllocateZeroPool(sizeof(struct menu_item) * menucount);
|
||
+ item_text = AllocateZeroPool(sizeof(CHAR16 *) * (menucount + 1));
|
||
|
||
if (!menu_item)
|
||
return EFI_OUT_OF_RESOURCES;
|
||
|
||
- menu_item[i].text = StrDuplicate(L"Continue boot");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Continue boot";
|
||
menu_item[i].callback = NULL;
|
||
|
||
i++;
|
||
|
||
if (MokNew || MokAuth) {
|
||
if (!MokNew) {
|
||
- menu_item[i].text = StrDuplicate(L"Reset MOK");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Reset MOK";
|
||
menu_item[i].callback = mok_reset_prompt;
|
||
} else {
|
||
- menu_item[i].text = StrDuplicate(L"Enroll MOK");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Enroll MOK";
|
||
menu_item[i].data = MokNew;
|
||
menu_item[i].data2 = (void *)MokNewSize;
|
||
menu_item[i].callback = mok_enrollment_prompt_callback;
|
||
@@ -1596,8 +1516,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
}
|
||
|
||
if (MokDel || MokDelAuth) {
|
||
- menu_item[i].text = StrDuplicate(L"Delete MOK");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Delete MOK";
|
||
menu_item[i].data = MokDel;
|
||
menu_item[i].data2 = (void *)MokDelSize;
|
||
menu_item[i].callback = mok_deletion_prompt;
|
||
@@ -1605,8 +1524,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
}
|
||
|
||
if (MokSB) {
|
||
- menu_item[i].text = StrDuplicate(L"Change Secure Boot state");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Change Secure Boot state";
|
||
menu_item[i].callback = mok_sb_prompt;
|
||
menu_item[i].data = MokSB;
|
||
menu_item[i].data2 = (void *)MokSBSize;
|
||
@@ -1614,32 +1532,49 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
}
|
||
|
||
if (MokPW) {
|
||
- menu_item[i].text = StrDuplicate(L"Set MOK password");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Set MOK password";
|
||
menu_item[i].callback = mok_pw_prompt;
|
||
menu_item[i].data = MokPW;
|
||
menu_item[i].data2 = (void *)MokPWSize;
|
||
i++;
|
||
}
|
||
|
||
- menu_item[i].text = StrDuplicate(L"Enroll key from disk");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Enroll key from disk";
|
||
menu_item[i].callback = find_file;
|
||
menu_item[i].data3 = (void *)FALSE;
|
||
|
||
i++;
|
||
|
||
- menu_item[i].text = StrDuplicate(L"Enroll hash from disk");
|
||
- menu_item[i].colour = EFI_WHITE;
|
||
+ item_text[i] = L"Enroll hash from disk";
|
||
menu_item[i].callback = find_file;
|
||
menu_item[i].data3 = (void *)TRUE;
|
||
|
||
i++;
|
||
|
||
- run_menu(NULL, 0, menu_item, menucount, 10);
|
||
+ title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
|
||
+ title[1] = NULL;
|
||
+
|
||
+ if (draw_countdown() == 0)
|
||
+ goto done;
|
||
+
|
||
+ while (1) {
|
||
+ opt = console_select(title, item_text, 0);
|
||
+ if (opt == -1 || opt == 0)
|
||
+ break;
|
||
|
||
+ if (menu_item[opt].callback) {
|
||
+ menu_item[opt].callback(menu_item[opt].data,
|
||
+ menu_item[opt].data2,
|
||
+ menu_item[opt].data3);
|
||
+ }
|
||
+ }
|
||
+
|
||
+done:
|
||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||
|
||
+ FreePool(item_text);
|
||
+ FreePool(title[0]);
|
||
+
|
||
return 0;
|
||
}
|
||
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From 74cbc9f5a4d6f93de93d93dd0a79796ec560f672 Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Thu, 18 Apr 2013 17:52:46 +0800
|
||
Subject: [PATCH 07/12] Remove the duplicate get_keystroke()
|
||
|
||
---
|
||
MokManager.c | 16 ++--------------
|
||
1 file changed, 2 insertions(+), 14 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index c1a726d..8c52121 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -67,18 +67,6 @@ static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
|
||
return efi_status;
|
||
}
|
||
|
||
-static EFI_INPUT_KEY get_keystroke (void)
|
||
-{
|
||
- EFI_INPUT_KEY key;
|
||
- UINTN EventIndex;
|
||
-
|
||
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey,
|
||
- &EventIndex);
|
||
- uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
|
||
-
|
||
- return key;
|
||
-}
|
||
-
|
||
static EFI_STATUS get_sha1sum (void *Data, int DataSize, UINT8 *hash)
|
||
{
|
||
EFI_STATUS status;
|
||
@@ -426,7 +414,7 @@ static INTN get_number ()
|
||
int count = 0;
|
||
|
||
do {
|
||
- input_key = get_keystroke();
|
||
+ input_key = console_get_keystroke();
|
||
|
||
if ((input_key.UnicodeChar < '0' ||
|
||
input_key.UnicodeChar > '9' ||
|
||
@@ -517,7 +505,7 @@ static UINT8 get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show
|
||
int count = 0;
|
||
|
||
do {
|
||
- key = get_keystroke();
|
||
+ key = console_get_keystroke();
|
||
|
||
if ((count >= line_max &&
|
||
key.UnicodeChar != CHAR_BACKSPACE) ||
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From d9073c96d9bb51cca75cd10b32ad79fef9ce3217 Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Fri, 3 May 2013 17:06:56 +0800
|
||
Subject: [PATCH 08/12] Revamp the key enrollment UI
|
||
|
||
---
|
||
MokManager.c | 439 ++++++++++++++++++++++++++++++++++-------------------------
|
||
1 file changed, 254 insertions(+), 185 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index 8c52121..27887c4 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -189,17 +189,6 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
|
||
return list;
|
||
}
|
||
|
||
-static void print_x509_name (X509_NAME *X509Name, CHAR16 *name)
|
||
-{
|
||
- char *str;
|
||
-
|
||
- str = X509_NAME_oneline(X509Name, NULL, 0);
|
||
- if (str) {
|
||
- Print(L" %s:\n %a\n", name, str);
|
||
- OPENSSL_free(str);
|
||
- }
|
||
-}
|
||
-
|
||
static const char *mon[12]= {
|
||
"Jan","Feb","Mar","Apr","May","Jun",
|
||
"Jul","Aug","Sep","Oct","Nov","Dec"
|
||
@@ -304,157 +293,165 @@ error:
|
||
return;
|
||
}
|
||
|
||
-static void print_x509_time (ASN1_TIME *time, CHAR16 *name)
|
||
+static void put_x509_time (ASN1_TIME *time, CHAR16 *output)
|
||
{
|
||
- CHAR16 time_string[30];
|
||
-
|
||
if (time->type == V_ASN1_UTCTIME) {
|
||
- print_x509_UTCTIME_time(time, time_string);
|
||
+ print_x509_UTCTIME_time(time, output);
|
||
} else if (time->type == V_ASN1_GENERALIZEDTIME) {
|
||
- print_x509_GENERALIZEDTIME_time(time, time_string);
|
||
+ print_x509_GENERALIZEDTIME_time(time, output);
|
||
} else {
|
||
- time_string[0] = '\0';
|
||
+ output[0] = '\0';
|
||
}
|
||
-
|
||
- Print(L" %s:\n %s\n", name, time_string);
|
||
}
|
||
|
||
-static void show_x509_info (X509 *X509Cert)
|
||
+static int get_common_name (X509_NAME *X509Name, CHAR16 *output, int max)
|
||
{
|
||
- ASN1_INTEGER *serial;
|
||
- BIGNUM *bnser;
|
||
- unsigned char hexbuf[30];
|
||
- X509_NAME *X509Name;
|
||
- ASN1_TIME *time;
|
||
+ CHAR8 *full, *ptr, *cn = NULL;
|
||
+ int i, full_len;
|
||
|
||
- serial = X509_get_serialNumber(X509Cert);
|
||
- if (serial) {
|
||
- int i, n;
|
||
- bnser = ASN1_INTEGER_to_BN(serial, NULL);
|
||
- n = BN_bn2bin(bnser, hexbuf);
|
||
- Print(L" Serial Number:\n ");
|
||
- for (i = 0; i < n-1; i++) {
|
||
- Print(L"%02x:", hexbuf[i]);
|
||
- }
|
||
- Print(L"%02x\n", hexbuf[n-1]);
|
||
- }
|
||
+ if (!output)
|
||
+ return -1;
|
||
|
||
- X509Name = X509_get_issuer_name(X509Cert);
|
||
- if (X509Name) {
|
||
- print_x509_name(X509Name, L"Issuer");
|
||
+ if (!X509Name) {
|
||
+ output[0] = '\0';
|
||
+ return 0;
|
||
}
|
||
|
||
- X509Name = X509_get_subject_name(X509Cert);
|
||
- if (X509Name) {
|
||
- print_x509_name(X509Name, L"Subject");
|
||
+ full = (CHAR8 *)X509_NAME_oneline(X509Name, NULL, 0);
|
||
+ full_len = strlena(full);
|
||
+
|
||
+ for (ptr = full, i = 0; i < (full_len -4) ; ptr++, i++) {
|
||
+ if (strncmpa(ptr, (CHAR8 *)"/CN=", 4) == 0) {
|
||
+ cn = ptr+4;
|
||
+ break;
|
||
+ }
|
||
}
|
||
|
||
- time = X509_get_notBefore(X509Cert);
|
||
- if (time) {
|
||
- print_x509_time(time, L"Validity from");
|
||
+ if (!cn) {
|
||
+ output[0] = '\0';
|
||
+ return 0;
|
||
}
|
||
|
||
- time = X509_get_notAfter(X509Cert);
|
||
- if (time) {
|
||
- print_x509_time(time, L"Validity till");
|
||
+ for (ptr = cn, i = 0; i < max; ptr++, i++) {
|
||
+ if (*ptr == '\0' || *ptr == '/')
|
||
+ break;
|
||
+ output[i] = (CHAR16)*ptr;
|
||
}
|
||
+ output[i] = '\0';
|
||
+
|
||
+ return 0;
|
||
}
|
||
|
||
static void show_mok_info (void *Mok, UINTN MokSize)
|
||
{
|
||
EFI_STATUS efi_status;
|
||
UINT8 hash[SHA1_DIGEST_SIZE];
|
||
- unsigned int i;
|
||
+ CHAR16 *title[19];
|
||
+ INTN start;
|
||
X509 *X509Cert;
|
||
+ X509_NAME *X509Name;
|
||
+ CHAR16 issuer[80], subject[80];
|
||
+ ASN1_TIME *time;
|
||
+ CHAR16 str_from[30], str_till[30];
|
||
+ CHAR16 hash_line[2][40];
|
||
|
||
if (!Mok || MokSize == 0)
|
||
return;
|
||
|
||
if (MokSize != SHA256_DIGEST_SIZE) {
|
||
- if (X509ConstructCertificate(Mok, MokSize,
|
||
- (UINT8 **) &X509Cert) && X509Cert != NULL) {
|
||
- show_x509_info(X509Cert);
|
||
- X509_free(X509Cert);
|
||
- } else {
|
||
- Print(L" Not a valid X509 certificate: %x\n\n",
|
||
- ((UINT32 *)Mok)[0]);
|
||
- return;
|
||
- }
|
||
-
|
||
- efi_status = get_sha1sum(Mok, MokSize, hash);
|
||
+ title[0] = L"X509 certificate";
|
||
+ title[1] = L"";
|
||
|
||
- if (efi_status != EFI_SUCCESS) {
|
||
- Print(L"Failed to compute MOK fingerprint\n");
|
||
- return;
|
||
- }
|
||
-
|
||
- Print(L" Fingerprint (SHA1):\n ");
|
||
- for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
|
||
- Print(L" %02x", hash[i]);
|
||
- if (i % 10 == 9)
|
||
- Print(L"\n ");
|
||
+ if (!X509ConstructCertificate(Mok, MokSize, (UINT8 **) &X509Cert) ||
|
||
+ X509Cert == NULL) {
|
||
+ title[2] = L"Not a valid X509 certificate";
|
||
+ title[3] = NULL;
|
||
+ goto done;
|
||
}
|
||
- } else {
|
||
- Print(L"SHA256 hash:\n ");
|
||
- for (i = 0; i < SHA256_DIGEST_SIZE; i++) {
|
||
- Print(L" %02x", ((UINT8 *)Mok)[i]);
|
||
- if (i % 10 == 9)
|
||
- Print(L"\n ");
|
||
+ start = 2;
|
||
+
|
||
+ title[start] = L"[Issuer]";
|
||
+ X509Name = X509_get_issuer_name(X509Cert);
|
||
+ get_common_name(X509Name, issuer, 80);
|
||
+ title[start + 1] = issuer;
|
||
+ title[start + 2] = L"";
|
||
+
|
||
+ title[start + 3] = L"[Subject]";
|
||
+ X509Name = X509_get_subject_name(X509Cert);
|
||
+ get_common_name(X509Name, subject, 80);
|
||
+ title[start + 4] = subject;
|
||
+ title[start + 5] = L"";
|
||
+
|
||
+ title[start + 6] = L"[Valid Not Before]";
|
||
+ time = X509_get_notBefore(X509Cert);
|
||
+ if (time) {
|
||
+ put_x509_time(time, str_from);
|
||
+ title[start + 7] = str_from;
|
||
+ } else {
|
||
+ title[start + 7] = L"";
|
||
}
|
||
- Print(L"\n");
|
||
- }
|
||
+ title[start + 8] = L"";
|
||
|
||
- Print(L"\n");
|
||
-}
|
||
-
|
||
-static INTN get_number ()
|
||
-{
|
||
- EFI_INPUT_KEY input_key;
|
||
- CHAR16 input[10];
|
||
- int count = 0;
|
||
-
|
||
- do {
|
||
- input_key = console_get_keystroke();
|
||
-
|
||
- if ((input_key.UnicodeChar < '0' ||
|
||
- input_key.UnicodeChar > '9' ||
|
||
- count >= 10) &&
|
||
- input_key.UnicodeChar != CHAR_BACKSPACE) {
|
||
- continue;
|
||
+ title[start + 9] = L"[Valid Not After]";
|
||
+ time = X509_get_notAfter(X509Cert);
|
||
+ if (time) {
|
||
+ put_x509_time(time, str_till);
|
||
+ title[start + 10] = str_till;
|
||
+ } else {
|
||
+ title[start + 10] = L"";
|
||
}
|
||
+ title[start + 11] = L"";
|
||
|
||
- if (count == 0 && input_key.UnicodeChar == CHAR_BACKSPACE)
|
||
- continue;
|
||
+ X509_free(X509Cert);
|
||
|
||
- Print(L"%c", input_key.UnicodeChar);
|
||
-
|
||
- if (input_key.UnicodeChar == CHAR_BACKSPACE) {
|
||
- input[--count] = '\0';
|
||
- continue;
|
||
+ title[start + 12] = L"[Fingerprint (SHA1)]";
|
||
+ efi_status = get_sha1sum(Mok, MokSize, hash);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ title[start + 13] = L"Failed to compute MOK fingerprint";
|
||
+ title[start + 14] = L"";
|
||
+ } else {
|
||
+ SPrint(hash_line[0], 0, L"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||
+ hash[0], hash[1], hash[2], hash[3], hash[4],
|
||
+ hash[5], hash[6], hash[7], hash[8], hash[9]);
|
||
+ SPrint(hash_line[1], 0, L"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||
+ hash[10], hash[11], hash[12], hash[13], hash[14],
|
||
+ hash[15], hash[16], hash[17], hash[18], hash[19]);
|
||
+ title[start + 13] = hash_line[0];
|
||
+ title[start + 14] = hash_line[1];
|
||
}
|
||
|
||
- input[count++] = input_key.UnicodeChar;
|
||
- } while (input_key.UnicodeChar != CHAR_CARRIAGE_RETURN);
|
||
+ title[start + 15] = NULL;
|
||
+ } else {
|
||
+ title[0] = L"SHA256 hash";
|
||
+ title[1] = title[2] = L"";
|
||
|
||
- if (count == 0)
|
||
- return -1;
|
||
|
||
- input[count] = '\0';
|
||
+ SPrint(hash_line[0], 0, L"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||
+ hash[0], hash[1], hash[2], hash[3], hash[4],
|
||
+ hash[5], hash[6], hash[7], hash[8], hash[9]);
|
||
+ SPrint(hash_line[1], 0, L"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||
+ hash[10], hash[11], hash[12], hash[13], hash[14],
|
||
+ hash[15], hash[16], hash[17], hash[18], hash[19]);
|
||
+ title[3] = hash_line[0];
|
||
+ title[4] = hash_line[1];
|
||
+ title[5] = NULL;
|
||
+ }
|
||
|
||
- return (INTN)Atoi(input);
|
||
+done:
|
||
+ console_print_box(title, -1);
|
||
}
|
||
|
||
static UINT8 list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
|
||
{
|
||
UINT32 MokNum = 0;
|
||
MokListNode *keys = NULL;
|
||
- INTN key_num = 0;
|
||
- UINT8 initial = 1;
|
||
+ CHAR16 *selector_title[2];
|
||
+ CHAR16 **opt_text;
|
||
+ INTN i, opt = 0;
|
||
|
||
if (KeyListSize < (sizeof(EFI_SIGNATURE_LIST) +
|
||
sizeof(EFI_SIGNATURE_DATA))) {
|
||
- Print(L"No keys\n");
|
||
- Pause();
|
||
+ console_errorbox(L"No Key in the list.");
|
||
return 0;
|
||
}
|
||
|
||
@@ -462,38 +459,46 @@ static UINT8 list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
|
||
keys = build_mok_list(MokNum, KeyList, KeyListSize);
|
||
|
||
if (!keys) {
|
||
- Print(L"Failed to construct key list\n");
|
||
+ console_errorbox(L"Failed to construct key list");
|
||
return 0;
|
||
}
|
||
|
||
- do {
|
||
- uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||
- if (title)
|
||
- Print(L"%s\n", title);
|
||
- Print(L"Input the key number to show the details of the key or\n"
|
||
- L"type \'0\' to continue\n\n");
|
||
- Print(L"%d key(s) in the key list\n\n", MokNum);
|
||
-
|
||
- if (key_num > MokNum) {
|
||
- Print(L"[Key %d]\n", key_num);
|
||
- Print(L"No such key\n\n");
|
||
- } else if (initial != 1 && key_num > 0){
|
||
- Print(L"[Key %d]\n", key_num);
|
||
- show_mok_info(keys[key_num-1].Mok, keys[key_num-1].MokSize);
|
||
- }
|
||
+ if (MokNum == 1) {
|
||
+ show_mok_info(keys[0].Mok, keys[0].MokSize);
|
||
+ FreePool(keys);
|
||
+ return 1;
|
||
+ }
|
||
|
||
- Print(L"Key Number: ");
|
||
+ selector_title[0] = title;
|
||
+ selector_title[1] = NULL;
|
||
|
||
- key_num = get_number();
|
||
+ opt_text = AllocateZeroPool(sizeof(CHAR16 *) * (MokNum + 2));
|
||
+ if (!opt_text) {
|
||
+ console_errorbox(L"Failed to allocate buffer");
|
||
+ return 0;
|
||
+ }
|
||
|
||
- Print(L"\n\n");
|
||
+ opt_text[0] = L"Back";
|
||
+ for (i = 0; i < MokNum; i++) {
|
||
+ opt_text[i+1] = PoolPrint(L"Mok-%02d", i+1);
|
||
+ if (!opt_text[i+1]) {
|
||
+ console_errorbox(L"Failed to allocate buffer");
|
||
+ return 0;
|
||
+ }
|
||
+ }
|
||
|
||
- if (key_num == -1)
|
||
- continue;
|
||
+ while(1) {
|
||
+ opt = console_select(selector_title, opt_text, opt);
|
||
|
||
- initial = 0;
|
||
- } while (key_num != 0);
|
||
+ if (opt == 0 || opt == -1)
|
||
+ break;
|
||
+ else
|
||
+ show_mok_info(keys[opt-1].Mok, keys[opt-1].MokSize);
|
||
+ }
|
||
|
||
+ for (i = 0; i < MokNum; i++)
|
||
+ FreePool(opt_text[i+1]);
|
||
+ FreePool(opt_text);
|
||
FreePool(keys);
|
||
|
||
return 1;
|
||
@@ -550,32 +555,32 @@ static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password,
|
||
ctx = AllocatePool(ctxsize);
|
||
|
||
if (!ctx) {
|
||
- Print(L"Unable to allocate memory for hash context\n");
|
||
+ console_errorbox(L"Unable to allocate memory for hash context");
|
||
return EFI_OUT_OF_RESOURCES;
|
||
}
|
||
|
||
if (!Sha256Init(ctx)) {
|
||
- Print(L"Unable to initialise hash\n");
|
||
+ console_errorbox(L"Unable to initialise hash");
|
||
status = EFI_OUT_OF_RESOURCES;
|
||
goto done;
|
||
}
|
||
|
||
if (Data && DataSize) {
|
||
if (!(Sha256Update(ctx, Data, DataSize))) {
|
||
- Print(L"Unable to generate hash\n");
|
||
+ console_errorbox(L"Unable to generate hash");
|
||
status = EFI_OUT_OF_RESOURCES;
|
||
goto done;
|
||
}
|
||
}
|
||
|
||
if (!(Sha256Update(ctx, password, pw_length))) {
|
||
- Print(L"Unable to generate hash\n");
|
||
+ console_errorbox(L"Unable to generate hash");
|
||
status = EFI_OUT_OF_RESOURCES;
|
||
goto done;
|
||
}
|
||
|
||
if (!(Sha256Final(ctx, hash))) {
|
||
- Print(L"Unable to finalise hash\n");
|
||
+ console_errorbox(L"Unable to finalise hash");
|
||
status = EFI_OUT_OF_RESOURCES;
|
||
goto done;
|
||
}
|
||
@@ -585,6 +590,61 @@ 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)
|
||
@@ -611,15 +671,10 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
|
||
}
|
||
|
||
while (fail_count < 3) {
|
||
- if (prompt) {
|
||
- Print(L"%s", prompt);
|
||
- } else {
|
||
- Print(L"Password: ");
|
||
- }
|
||
- get_line(&pw_length, password, PASSWORD_MAX, 0);
|
||
+ pw_length = get_password(prompt, password, PASSWORD_MAX);
|
||
|
||
if (pw_length < PASSWORD_MIN || pw_length > PASSWORD_MAX) {
|
||
- Print(L"Invalid password length\n");
|
||
+ console_errorbox(L"Invalid password length");
|
||
fail_count++;
|
||
continue;
|
||
}
|
||
@@ -642,13 +697,13 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
|
||
pw_length * sizeof(CHAR16), hash);
|
||
}
|
||
if (status != EFI_SUCCESS) {
|
||
- Print(L"Unable to generate password hash\n");
|
||
+ console_errorbox(L"Unable to generate password hash");
|
||
fail_count++;
|
||
continue;
|
||
}
|
||
|
||
if (CompareMem(auth_hash, hash, auth_size) != 0) {
|
||
- Print(L"Password doesn't match\n");
|
||
+ console_errorbox(L"Password doesn't match");
|
||
fail_count++;
|
||
continue;
|
||
}
|
||
@@ -678,7 +733,7 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
|
||
if (efi_status != EFI_SUCCESS ||
|
||
(auth_size != SHA256_DIGEST_SIZE &&
|
||
auth_size != PASSWORD_CRYPT_SIZE)) {
|
||
- Print(L"Failed to get MokAuth %d\n", efi_status);
|
||
+ console_error(L"Failed to get MokAuth", efi_status);
|
||
return efi_status;
|
||
}
|
||
|
||
@@ -711,33 +766,58 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate)
|
||
}
|
||
|
||
if (efi_status != EFI_SUCCESS) {
|
||
- Print(L"Failed to set variable %d\n", efi_status);
|
||
+ 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) {
|
||
+static void restart_system()
|
||
+{
|
||
+ console_print_box((CHAR16 *[]){L"Press a key to reboot system", NULL}, -1);
|
||
+
|
||
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS,
|
||
+ 0, NULL);
|
||
+
|
||
+ console_errorbox(L"Failed to reboot");
|
||
+}
|
||
+
|
||
+static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth)
|
||
+{
|
||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||
- CHAR16 line[1];
|
||
- UINT32 length;
|
||
- EFI_STATUS efi_status;
|
||
+ EFI_STATUS status;
|
||
+ CHAR16 *title[2];
|
||
+ CHAR16 *opt_text[4];
|
||
+ CHAR16 *enroll_text[4];
|
||
+ INTN opt = 0;
|
||
|
||
- do {
|
||
- if (!list_keys(MokNew, MokNewSize, L"[Enroll MOK]")) {
|
||
- return 0;
|
||
- }
|
||
+ title[0] = L"Enroll MOK";
|
||
+ title[1] = NULL;
|
||
|
||
- Print(L"Enroll the key(s)? (y/n): ");
|
||
+ opt_text[0] = L"Enroll";
|
||
+ opt_text[1] = L"Show details";
|
||
+ opt_text[2] = L"Cancel";
|
||
+ opt_text[3] = NULL;
|
||
|
||
- get_line (&length, line, 1, 1);
|
||
+ enroll_text[0] = L"Enroll MOK";
|
||
+ enroll_text[1] = L"";
|
||
+ enroll_text[2] = L"Do you want to enroll the key(s)?";
|
||
+ enroll_text[3] = NULL;
|
||
|
||
- if (line[0] == 'Y' || line[0] == 'y') {
|
||
- efi_status = store_keys(MokNew, MokNewSize, auth);
|
||
+ while (1) {
|
||
+ opt = console_select(title, opt_text, opt);
|
||
|
||
- if (efi_status != EFI_SUCCESS) {
|
||
- Print(L"Failed to enroll keys\n");
|
||
+ if (opt == -1 || opt == 2)
|
||
+ break;
|
||
+
|
||
+ if (opt == 0) {
|
||
+ if (console_yes_no(enroll_text) == 0)
|
||
+ break;
|
||
+
|
||
+ status = store_keys(MokNew, MokNewSize, auth);
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_errorbox(L"Failed to enroll keys");
|
||
return -1;
|
||
}
|
||
|
||
@@ -745,18 +825,16 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) {
|
||
LibDeleteVariable(L"MokNew", &shim_lock_guid);
|
||
LibDeleteVariable(L"MokAuth", &shim_lock_guid);
|
||
|
||
- Print(L"\nPress a key to reboot system\n");
|
||
- Pause();
|
||
- uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
|
||
- EFI_SUCCESS, 0, NULL);
|
||
- Print(L"Failed to reboot\n");
|
||
+ restart_system();
|
||
return -1;
|
||
}
|
||
-
|
||
- return 0;
|
||
+ break;
|
||
+ } else if (opt == 1) {
|
||
+ list_keys(MokNew, MokNewSize, L"Keys to be enrolled");
|
||
}
|
||
- } while (line[0] != 'N' && line[0] != 'n');
|
||
- return -1;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
}
|
||
|
||
static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2,
|
||
@@ -1173,10 +1251,7 @@ static int draw_countdown()
|
||
CHAR16 *message = L"Press any key to enter management menu";
|
||
int timeout = 10, wait = 10000000;
|
||
|
||
- CopyMem(&SavedMode, ST->ConOut->Mode, sizeof(SavedMode));
|
||
- uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
|
||
- uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
||
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
||
+ console_save_and_set_mode(&SavedMode);
|
||
|
||
title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
|
||
title[1] = NULL;
|
||
@@ -1209,13 +1284,7 @@ static int draw_countdown()
|
||
|
||
FreePool(title[0]);
|
||
|
||
- /* Restore everything */
|
||
- 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);
|
||
+ console_restore_mode(&SavedMode);
|
||
|
||
return timeout;
|
||
}
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From 5364b826a40dfb76e58c20d7ff8e2fd4e98f40d6 Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Fri, 3 May 2013 17:58:38 +0800
|
||
Subject: [PATCH 09/12] Revamp the key deletion UI
|
||
|
||
---
|
||
MokManager.c | 60 ++++++++++++++++++++++++++++++++++++++----------------------
|
||
1 file changed, 38 insertions(+), 22 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index 27887c4..6883cb1 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -959,7 +959,7 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
|
||
|
||
if (efi_status != EFI_SUCCESS ||
|
||
(auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_CRYPT_SIZE)) {
|
||
- Print(L"Failed to get MokDelAuth %d\n", efi_status);
|
||
+ console_error(L"Failed to get MokDelAuth", efi_status);
|
||
return efi_status;
|
||
}
|
||
|
||
@@ -976,9 +976,13 @@ static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize)
|
||
&MokListDataSize, &MokListData);
|
||
|
||
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
|
||
- Print(L"MokList is compromised!\nErase all keys in MokList!\n");
|
||
+ console_alertbox((CHAR16 *[]){L"ERROR",
|
||
+ L"",
|
||
+ L"MokList is compromised!",
|
||
+ L"Erase all keys in MokList!",
|
||
+ NULL});
|
||
if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) {
|
||
- Print(L"Failed to erase MokList\n");
|
||
+ console_errorbox(L"Failed to erase MokList");
|
||
}
|
||
return EFI_ACCESS_DENIED;
|
||
}
|
||
@@ -1023,38 +1027,50 @@ static INTN mok_deletion_prompt (void *MokDel, void *data2, void *data3)
|
||
{
|
||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||
UINTN MokDelSize = (UINTN)data2;
|
||
- CHAR16 line[1];
|
||
- UINT32 length;
|
||
- EFI_STATUS efi_status;
|
||
+ EFI_STATUS status;
|
||
+ CHAR16 *title[2];
|
||
+ CHAR16 *opt_text[4];
|
||
+ CHAR16 *delete_text[4];
|
||
+ INTN opt = 0;
|
||
|
||
- do {
|
||
- if (!list_keys(MokDel, MokDelSize, L"[Delete MOK]")) {
|
||
- return 0;
|
||
- }
|
||
+ title[0] = L"Delete MOK";
|
||
+ title[1] = NULL;
|
||
|
||
- Print(L"Delete the key(s)? (y/n): ");
|
||
+ opt_text[0] = L"Delete";
|
||
+ opt_text[1] = L"Show details";
|
||
+ opt_text[2] = L"Cancel";
|
||
+ opt_text[3] = NULL;
|
||
|
||
- get_line (&length, line, 1, 1);
|
||
+ delete_text[0] = L"Delete MOK";
|
||
+ delete_text[1] = L"";
|
||
+ delete_text[2] = L"Do you want to delete the key(s)?";
|
||
+ delete_text[3] = NULL;
|
||
|
||
- if (line[0] == 'Y' || line[0] == 'y') {
|
||
- efi_status = delete_keys(MokDel, MokDelSize);
|
||
+ while (1) {
|
||
+ opt = console_select(title, opt_text, opt);
|
||
|
||
- if (efi_status != EFI_SUCCESS) {
|
||
- Print(L"Failed to delete keys\n");
|
||
+ if (opt == -1 || opt == 2)
|
||
+ break;
|
||
+
|
||
+ if (opt == 0) {
|
||
+ if (console_yes_no(delete_text) == 0)
|
||
+ break;
|
||
+
|
||
+ status = delete_keys(MokDel, MokDelSize);
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_errorbox(L"Failed to delete keys");
|
||
return -1;
|
||
}
|
||
|
||
LibDeleteVariable(L"MokDel", &shim_lock_guid);
|
||
LibDeleteVariable(L"MokDelAuth", &shim_lock_guid);
|
||
|
||
- Print(L"\nPress a key to reboot system\n");
|
||
- Pause();
|
||
- uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
|
||
- EFI_SUCCESS, 0, NULL);
|
||
- Print(L"Failed to reboot\n");
|
||
+ restart_system();
|
||
return -1;
|
||
+ } else if (opt == 1) {
|
||
+ list_keys(MokDel, MokDelSize, L"Keys to be deleted");
|
||
}
|
||
- } while (line[0] != 'N' && line[0] != 'n');
|
||
+ }
|
||
return -1;
|
||
}
|
||
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From bcd5b4fb1489888af4310c63f6429120700b78ad Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Fri, 3 May 2013 18:05:22 +0800
|
||
Subject: [PATCH 10/12] Revamp the key reset UI
|
||
|
||
---
|
||
MokManager.c | 39 ++++++++++++++++-----------------------
|
||
1 file changed, 16 insertions(+), 23 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index 6883cb1..59e2b2d 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -847,35 +847,28 @@ static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2,
|
||
static INTN mok_reset_prompt (void *MokNew, void *data2, void *data3)
|
||
{
|
||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||
- CHAR16 line[1];
|
||
- UINT32 length;
|
||
- EFI_STATUS efi_status;
|
||
-
|
||
- uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||
- Print(L"Erase all stored keys? (y/N): ");
|
||
-
|
||
- get_line (&length, line, 1, 1);
|
||
+ EFI_STATUS status;
|
||
+ CHAR16 *erase_text[4];
|
||
|
||
- if (line[0] == 'Y' || line[0] == 'y') {
|
||
- efi_status = store_keys(NULL, 0, TRUE);
|
||
+ erase_text[0] = L"Reset MOK";
|
||
+ erase_text[1] = L"";
|
||
+ erase_text[2] = L"Do you want to erase all keys?";
|
||
+ erase_text[3] = NULL;
|
||
|
||
- if (efi_status != EFI_SUCCESS) {
|
||
- Print(L"Failed to erase keys\n");
|
||
- return -1;
|
||
- }
|
||
-
|
||
- LibDeleteVariable(L"MokNew", &shim_lock_guid);
|
||
- LibDeleteVariable(L"MokAuth", &shim_lock_guid);
|
||
+ if (console_yes_no(erase_text) == 0)
|
||
+ return 0;
|
||
|
||
- Print(L"\nPress a key to reboot system\n");
|
||
- Pause();
|
||
- uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
|
||
- EFI_SUCCESS, 0, NULL);
|
||
- Print(L"Failed to reboot\n");
|
||
+ status = store_keys(NULL, 0, TRUE);
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_errorbox(L"Failed to erase keys");
|
||
return -1;
|
||
}
|
||
|
||
- return 0;
|
||
+ LibDeleteVariable(L"MokNew", &shim_lock_guid);
|
||
+ LibDeleteVariable(L"MokAuth", &shim_lock_guid);
|
||
+
|
||
+ restart_system();
|
||
+ return -1;
|
||
}
|
||
|
||
static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num)
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From f4a5f4fb0c3b57f3801d9d7d28a3ea3d3a58ff5e Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Mon, 6 May 2013 15:53:49 +0800
|
||
Subject: [PATCH 11/12] Revamp the lockdown password UI
|
||
|
||
---
|
||
MokManager.c | 90 +++++++++++++++++++++++++++++++-----------------------------
|
||
1 file changed, 46 insertions(+), 44 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index 59e2b2d..9c37a44 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -1171,14 +1171,15 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
|
||
UINTN MokPWSize = (UINTN)data2;
|
||
UINT8 hash[PASSWORD_CRYPT_SIZE];
|
||
UINT8 clear = 0;
|
||
- UINT32 length;
|
||
- CHAR16 line[1];
|
||
+ CHAR16 *pw_text[2];
|
||
|
||
if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_CRYPT_SIZE) {
|
||
Print(L"Invalid MokPW variable contents\n");
|
||
return -1;
|
||
}
|
||
|
||
+ pw_text[1] = NULL;
|
||
+
|
||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||
|
||
SetMem(hash, PASSWORD_CRYPT_SIZE, 0);
|
||
@@ -1192,60 +1193,47 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
|
||
}
|
||
|
||
if (clear) {
|
||
- Print(L"Clear MOK password? (y/n): ");
|
||
-
|
||
- do {
|
||
- get_line (&length, line, 1, 1);
|
||
+ pw_text[0] = L"Clear MOK lockdown password?";
|
||
|
||
- if (line[0] == 'Y' || line[0] == 'y') {
|
||
- LibDeleteVariable(L"MokPWStore", &shim_lock_guid);
|
||
- LibDeleteVariable(L"MokPW", &shim_lock_guid);
|
||
- }
|
||
- } while (line[0] != 'N' && line[0] != 'n');
|
||
+ if (console_yes_no(pw_text) == 1) {
|
||
+ LibDeleteVariable(L"MokPWStore", &shim_lock_guid);
|
||
+ LibDeleteVariable(L"MokPW", &shim_lock_guid);
|
||
+ }
|
||
|
||
return 0;
|
||
}
|
||
|
||
if (MokPWSize == PASSWORD_CRYPT_SIZE) {
|
||
efi_status = match_password((PASSWORD_CRYPT *)MokPW, NULL, 0,
|
||
- NULL, L"Confirm MOK passphrase: ");
|
||
+ NULL, L"Confirm MOK password:");
|
||
} else {
|
||
efi_status = match_password(NULL, NULL, 0, MokPW,
|
||
- L"Confirm MOK passphrase: ");
|
||
+ L"Confirm MOK password:");
|
||
}
|
||
|
||
if (efi_status != EFI_SUCCESS) {
|
||
- Print(L"Password limit reached\n");
|
||
+ console_errorbox(L"Password limit reached");
|
||
return -1;
|
||
}
|
||
|
||
- Print(L"Set MOK password? (y/n): ");
|
||
-
|
||
- do {
|
||
- get_line (&length, line, 1, 1);
|
||
-
|
||
- if (line[0] == 'Y' || line[0] == 'y') {
|
||
- efi_status = uefi_call_wrapper(RT->SetVariable, 5,
|
||
- L"MokPWStore",
|
||
- &shim_lock_guid,
|
||
+ pw_text[0] = L"Set MOK lockdown password?";
|
||
+ if (console_yes_no(pw_text) == 1) {
|
||
+ 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) {
|
||
- Print(L"Failed to set MOK password\n");
|
||
- return -1;
|
||
- }
|
||
-
|
||
- LibDeleteVariable(L"MokPW", &shim_lock_guid);
|
||
-
|
||
- Print(L"Press a key to reboot system\n");
|
||
- Pause();
|
||
- uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
|
||
- EFI_SUCCESS, 0, NULL);
|
||
- Print(L"Failed to reboot\n");
|
||
+ MokPWSize, MokPW);
|
||
+ if (efi_status != EFI_SUCCESS) {
|
||
+ console_errorbox(L"Failed to set MOK lockdown password");
|
||
return -1;
|
||
}
|
||
- } while (line[0] != 'N' && line[0] != 'n');
|
||
+
|
||
+ LibDeleteVariable(L"MokPW", &shim_lock_guid);
|
||
+
|
||
+ restart_system();
|
||
+ return -1;
|
||
+ }
|
||
|
||
return 0;
|
||
}
|
||
@@ -1467,13 +1455,17 @@ out:
|
||
return 0;
|
||
}
|
||
|
||
-static BOOLEAN verify_pw(void)
|
||
+static BOOLEAN verify_pw(UINT8 *protected)
|
||
{
|
||
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||
EFI_STATUS efi_status;
|
||
UINT8 pwhash[PASSWORD_CRYPT_SIZE];
|
||
UINTN size = PASSWORD_CRYPT_SIZE;
|
||
UINT32 attributes;
|
||
+ CHAR16 *message[2];
|
||
+
|
||
+ *protected = 0;
|
||
|
||
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
|
||
&shim_lock_guid, &attributes, &size,
|
||
@@ -1493,18 +1485,27 @@ static BOOLEAN verify_pw(void)
|
||
|
||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||
|
||
+ 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: ");
|
||
+ NULL, L"Enter MOK password:");
|
||
} else {
|
||
efi_status = match_password(NULL, NULL, 0, pwhash,
|
||
- L"Enter MOK password: ");
|
||
+ L"Enter MOK password:");
|
||
}
|
||
if (efi_status != EFI_SUCCESS) {
|
||
- Print(L"Password limit reached\n");
|
||
+ console_errorbox(L"Password limit reached");
|
||
return FALSE;
|
||
}
|
||
|
||
+ *protected = 1;
|
||
+
|
||
return TRUE;
|
||
}
|
||
|
||
@@ -1525,8 +1526,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
UINT8 auth[PASSWORD_CRYPT_SIZE];
|
||
UINTN auth_size = PASSWORD_CRYPT_SIZE;
|
||
UINT32 attributes;
|
||
+ UINT8 protected;
|
||
|
||
- if (verify_pw() == FALSE)
|
||
+ if (verify_pw(&protected) == FALSE)
|
||
return EFI_ACCESS_DENIED;
|
||
|
||
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
|
||
@@ -1598,7 +1600,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
}
|
||
|
||
if (MokPW) {
|
||
- item_text[i] = L"Set MOK password";
|
||
+ item_text[i] = L"Set MOK lockdown password";
|
||
menu_item[i].callback = mok_pw_prompt;
|
||
menu_item[i].data = MokPW;
|
||
menu_item[i].data2 = (void *)MokPWSize;
|
||
@@ -1620,7 +1622,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
||
title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
|
||
title[1] = NULL;
|
||
|
||
- if (draw_countdown() == 0)
|
||
+ if (protected == 0 && draw_countdown() == 0)
|
||
goto done;
|
||
|
||
while (1) {
|
||
--
|
||
1.8.1.4
|
||
|
||
|
||
From 7ab54bd23e9bc412fa581e166c8f214df44604c5 Mon Sep 17 00:00:00 2001
|
||
From: Gary Ching-Pang Lin <glin@suse.com>
|
||
Date: Mon, 6 May 2013 17:19:47 +0800
|
||
Subject: [PATCH 12/12] Revamp the Secure Boot state setting UI
|
||
|
||
---
|
||
MokManager.c | 129 ++++++++++++++++++++++++++++++++++++++---------------------
|
||
1 file changed, 84 insertions(+), 45 deletions(-)
|
||
|
||
diff --git a/MokManager.c b/MokManager.c
|
||
index 9c37a44..5b0c70c 100644
|
||
--- a/MokManager.c
|
||
+++ b/MokManager.c
|
||
@@ -1067,25 +1067,57 @@ static INTN mok_deletion_prompt (void *MokDel, void *data2, void *data3)
|
||
return -1;
|
||
}
|
||
|
||
+static CHAR16 get_password_charater (CHAR16 *prompt)
|
||
+{
|
||
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
||
+ 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);
|
||
+ get_line(&pw_length, &character, 1, 0);
|
||
+
|
||
+ console_restore_mode(&SavedMode);
|
||
+
|
||
+ return character;
|
||
+}
|
||
+
|
||
static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) {
|
||
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
||
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||
- EFI_STATUS efi_status;
|
||
+ EFI_STATUS status;
|
||
UINTN MokSBSize = (UINTN)data2;
|
||
MokSBvar *var = MokSB;
|
||
+ CHAR16 *message[4];
|
||
CHAR16 pass1, pass2, pass3;
|
||
+ CHAR16 *str;
|
||
UINT8 fail_count = 0;
|
||
- UINT32 length;
|
||
- CHAR16 line[1];
|
||
UINT8 sbval = 1;
|
||
UINT8 pos1, pos2, pos3;
|
||
|
||
if (MokSBSize != sizeof(MokSBvar)) {
|
||
- Print(L"Invalid MokSB variable contents\n");
|
||
+ console_errorbox(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);
|
||
@@ -1100,19 +1132,34 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) {
|
||
pos3 = (pos3 % var->PWLen) ;
|
||
} while (pos3 == pos2 || pos3 == pos1);
|
||
|
||
- Print(L"Enter password character %d: ", pos1 + 1);
|
||
- get_line(&length, &pass1, 1, 0);
|
||
+ 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);
|
||
|
||
- Print(L"Enter password character %d: ", pos2 + 1);
|
||
- get_line(&length, &pass2, 1, 0);
|
||
+ 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);
|
||
|
||
- Print(L"Enter password character %d: ", pos3 + 1);
|
||
- get_line(&length, &pass3, 1, 0);
|
||
+ 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");
|
||
+ console_errorbox(L"Invalid character");
|
||
fail_count++;
|
||
} else {
|
||
break;
|
||
@@ -1120,46 +1167,38 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) {
|
||
}
|
||
|
||
if (fail_count >= 3) {
|
||
- Print(L"Password limit reached\n");
|
||
+ console_errorbox(L"Password limit reached");
|
||
return -1;
|
||
}
|
||
|
||
- if (var->MokSBState == 0) {
|
||
- Print(L"Disable Secure Boot? (y/n): ");
|
||
- } else {
|
||
- Print(L"Enable Secure Boot? (y/n): ");
|
||
- }
|
||
-
|
||
- do {
|
||
- get_line (&length, line, 1, 1);
|
||
-
|
||
- if (line[0] == 'Y' || line[0] == 'y') {
|
||
- 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) {
|
||
- Print(L"Failed to set Secure Boot state\n");
|
||
- return -1;
|
||
- }
|
||
- } else {
|
||
- LibDeleteVariable(L"MokSBState",
|
||
- &shim_lock_guid);
|
||
+ message[1] = L"";
|
||
+ if (var->MokSBState == 0)
|
||
+ message[2] = L"Disable Secure Boot?";
|
||
+ else
|
||
+ message[2] = L"Enable Secure Boot?";
|
||
+ message[3] = NULL;
|
||
+
|
||
+ if (console_yes_no(message) == 1) {
|
||
+ if (var->MokSBState == 0) {
|
||
+ status = uefi_call_wrapper(RT->SetVariable,
|
||
+ 5, L"MokSBState",
|
||
+ &shim_lock_guid,
|
||
+ EFI_VARIABLE_NON_VOLATILE |
|
||
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||
+ 1, &sbval);
|
||
+ if (status != EFI_SUCCESS) {
|
||
+ console_errorbox(L"Failed to set Secure Boot state");
|
||
+ return -1;
|
||
}
|
||
+ } else {
|
||
+ LibDeleteVariable(L"MokSBState", &shim_lock_guid);
|
||
+ }
|
||
|
||
- LibDeleteVariable(L"MokSB", &shim_lock_guid);
|
||
+ LibDeleteVariable(L"MokSB", &shim_lock_guid);
|
||
|
||
- Print(L"Press a key to reboot system\n");
|
||
- Pause();
|
||
- uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
|
||
- EFI_SUCCESS, 0, NULL);
|
||
- Print(L"Failed to reboot\n");
|
||
- return -1;
|
||
- }
|
||
- } while (line[0] != 'N' && line[0] != 'n');
|
||
+ restart_system();
|
||
+ return -1;
|
||
+ }
|
||
|
||
return -1;
|
||
}
|
||
--
|
||
1.8.1.4
|
||
|