The package rpms/edk2.git has added or updated architecture specific content in its spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s): https://src.fedoraproject.org/cgit/rpms/edk2.git/commit/?id=05b0353aa12fc3e3....
Change: +ExclusiveArch: x86_64 aarch64
Thanks.
Full change: ============
commit 05b0353aa12fc3e3f4f6ad546820212b564616e5 Author: Cole Robinson crobinso@redhat.com Date: Fri Aug 31 13:31:19 2018 -0400
Update to edk2 git cb5f4f45ce
- Remove upstreamed patches - Update to qemu qemu-ovmf-secureboot-1.1.3 - Enable TPM2 support - Fix RPM build option passthrough
diff --git a/0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch b/0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch index de247bc..5d4d06a 100644 --- a/0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch +++ b/0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch @@ -1,3 +1,4 @@ +From 37942481c89eca732239c23fe606680e6e3faf77 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek lersek@redhat.com Date: Wed, 27 Jan 2016 03:05:18 +0100 Subject: [PATCH] OvmfPkg: silence EFI_D_VERBOSE (0x00400000) in NvmExpressDxe @@ -7,6 +8,7 @@ level.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek lersek@redhat.com +Signed-off-by: Paolo Bonzini pbonzini@redhat.com --- OvmfPkg/OvmfPkgIa32.dsc | 5 ++++- OvmfPkg/OvmfPkgIa32X64.dsc | 5 ++++- @@ -14,10 +16,10 @@ Signed-off-by: Laszlo Ersek lersek@redhat.com 3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc -index 3f4d42d..048a144 100644 +index a28b511d5c..7f725ab198 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc -@@ -635,7 +635,10 @@ +@@ -738,7 +738,10 @@ OvmfPkg/SataControllerDxe/SataControllerDxe.inf MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf @@ -30,10 +32,10 @@ index 3f4d42d..048a144 100644 MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc -index 5688475..fac0cf0 100644 +index 115d0c01ff..d444a84267 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc -@@ -644,7 +644,10 @@ +@@ -747,7 +747,10 @@ OvmfPkg/SataControllerDxe/SataControllerDxe.inf MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf @@ -46,10 +48,10 @@ index 5688475..fac0cf0 100644 MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc -index dcf64b9..bc62a64 100644 +index 362eb789c7..f4e072870c 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc -@@ -642,7 +642,10 @@ +@@ -745,7 +745,10 @@ OvmfPkg/SataControllerDxe/SataControllerDxe.inf MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf diff --git a/0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch b/0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch index 71ec2b1..9264deb 100644 --- a/0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch +++ b/0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch @@ -1,3 +1,4 @@ +From 5e55066b33d894cb7e9b84179de449e8734cb57d Mon Sep 17 00:00:00 2001 From: Laszlo Ersek lersek@redhat.com Date: Wed, 27 Jan 2016 03:05:18 +0100 Subject: [PATCH] OvmfPkg: silence EFI_D_VERBOSE (0x00400000) in the DXE core @@ -8,6 +9,7 @@ not interested in. Suppress said output.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek lersek@redhat.com +Signed-off-by: Paolo Bonzini pbonzini@redhat.com --- OvmfPkg/OvmfPkgIa32.dsc | 2 ++ OvmfPkg/OvmfPkgIa32X64.dsc | 2 ++ @@ -15,10 +17,10 @@ Signed-off-by: Laszlo Ersek lersek@redhat.com 3 files changed, 6 insertions(+)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc -index 767fd7d..40688dd 100644 +index 7f725ab198..83e47281ed 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc -@@ -562,6 +562,8 @@ +@@ -644,6 +644,8 @@ <LibraryClasses> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf @@ -28,10 +30,10 @@ index 767fd7d..40688dd 100644
MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc -index 7460d50..3e75388 100644 +index d444a84267..a2adacfbd3 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc -@@ -571,6 +571,8 @@ +@@ -653,6 +653,8 @@ <LibraryClasses> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf @@ -41,10 +43,10 @@ index 7460d50..3e75388 100644
MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc -index 765506a..e169f13 100644 +index f4e072870c..b57e32f432 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc -@@ -569,6 +569,8 @@ +@@ -651,6 +651,8 @@ <LibraryClasses> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf diff --git a/0003-OvmfPkg-enable-DEBUG_VERBOSE.patch b/0003-OvmfPkg-enable-DEBUG_VERBOSE.patch index 6da6d05..776d50b 100644 --- a/0003-OvmfPkg-enable-DEBUG_VERBOSE.patch +++ b/0003-OvmfPkg-enable-DEBUG_VERBOSE.patch @@ -1,3 +1,4 @@ +From c667557c191923e981b972b5679fc49cec60d7e5 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek lersek@redhat.com Date: Sun, 8 Jul 2012 14:26:07 +0200 Subject: [PATCH] OvmfPkg: enable DEBUG_VERBOSE @@ -5,6 +6,7 @@ Subject: [PATCH] OvmfPkg: enable DEBUG_VERBOSE Enable verbose debug logs.
Signed-off-by: Laszlo Ersek lersek@redhat.com +Signed-off-by: Paolo Bonzini pbonzini@redhat.com --- OvmfPkg/OvmfPkgIa32.dsc | 2 +- OvmfPkg/OvmfPkgIa32X64.dsc | 2 +- @@ -12,10 +14,10 @@ Signed-off-by: Laszlo Ersek lersek@redhat.com 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc -index c0440d9..fa9661c 100644 +index 83e47281ed..cd0e71869b 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc -@@ -408,7 +408,7 @@ +@@ -486,7 +486,7 @@ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may # // significantly impact boot performance # DEBUG_ERROR 0x80000000 // Error @@ -25,10 +27,10 @@ index c0440d9..fa9661c 100644 !ifdef $(SOURCE_DEBUG_ENABLE) gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc -index 6f94bc7..667584a 100644 +index a2adacfbd3..7f7a78f60a 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc -@@ -413,7 +413,7 @@ +@@ -491,7 +491,7 @@ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may # // significantly impact boot performance # DEBUG_ERROR 0x80000000 // Error @@ -38,10 +40,10 @@ index 6f94bc7..667584a 100644 !ifdef $(SOURCE_DEBUG_ENABLE) gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc -index a92bf19..5ae8469 100644 +index b57e32f432..739807efc4 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc -@@ -413,7 +413,7 @@ +@@ -491,7 +491,7 @@ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may # // significantly impact boot performance # DEBUG_ERROR 0x80000000 // Error diff --git a/0004-OvmfPkg-increase-max-debug-message-length-to-512.patch b/0004-OvmfPkg-increase-max-debug-message-length-to-512.patch index 1bb9ee3..bedec89 100644 --- a/0004-OvmfPkg-increase-max-debug-message-length-to-512.patch +++ b/0004-OvmfPkg-increase-max-debug-message-length-to-512.patch @@ -1,14 +1,22 @@ +From 6324a2a8ae4fc96c9e13d39483c5ee0cb1fff619 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek lersek@redhat.com Date: Thu, 20 Feb 2014 22:54:45 +0100 Subject: [PATCH] OvmfPkg: increase max debug message length to 512
-Contributed-under: TianoCore Contribution Agreement 1.0 +Upstream prefers short debug messages (sometimes even limited to 80 +characters), but any line length under 512 characters is just unsuitable +for effective debugging. (For example, config strings in HII routing, +logged by the platform driver "OvmfPkg/PlatformDxe" on DEBUG_VERBOSE +level, can be several hundred characters long.) 512 is an empirically good +value. + +Signed-off-by: Laszlo Ersek lersek@redhat.com --- OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c b/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c -index 44850a9..b6927d0 100644 +index 36cde54976..c0c4eaee0f 100644 --- a/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c +++ b/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c @@ -27,7 +27,7 @@ @@ -16,7 +24,7 @@ index 44850a9..b6927d0 100644 // Define the maximum debug and assert message length that this library supports // -#define MAX_DEBUG_MESSAGE_LENGTH 0x100 -+#define MAX_DEBUG_MESSAGE_LENGTH 0x200 ++#define MAX_DEBUG_MESSAGE_LENGTH 0x200
/** - This constructor function does not have to do anything. + Prints a debug message to the debug output device if the specified error level is enabled. diff --git a/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch b/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch deleted file mode 100644 index f1274ea..0000000 --- a/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch +++ /dev/null @@ -1,520 +0,0 @@ -From: Laszlo Ersek lersek@redhat.com -Date: Tue, 20 May 2014 23:41:56 +0200 -Subject: [PATCH] OvmfPkg: QemuVideoDxe: enable debug messages in VbeShim - -Contributed-under: TianoCore Contribution Agreement 1.0 ---- - OvmfPkg/QemuVideoDxe/VbeShim.asm | 2 +- - OvmfPkg/QemuVideoDxe/VbeShim.h | 481 +++++++++++++++++++++++++-------------- - 2 files changed, 308 insertions(+), 175 deletions(-) - -diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.asm b/OvmfPkg/QemuVideoDxe/VbeShim.asm -index 18fa920..9a185f2 100644 ---- a/OvmfPkg/QemuVideoDxe/VbeShim.asm -+++ b/OvmfPkg/QemuVideoDxe/VbeShim.asm -@@ -18,7 +18,7 @@ - ;------------------------------------------------------------------------------ - - ; enable this macro for debug messages --;%define DEBUG -+%define DEBUG - - %macro DebugLog 1 - %ifdef DEBUG -diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.h b/OvmfPkg/QemuVideoDxe/VbeShim.h -index cc9b6e1..db37f1d 100644 ---- a/OvmfPkg/QemuVideoDxe/VbeShim.h -+++ b/OvmfPkg/QemuVideoDxe/VbeShim.h -@@ -517,185 +517,318 @@ STATIC CONST UINT8 mVbeShim[] = { - /* 000001FE nop */ 0x90, - /* 000001FF nop */ 0x90, - /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F, -- /* 00000203 jz 0x22d */ 0x74, 0x28, -+ /* 00000203 jz 0x235 */ 0x74, 0x30, - /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F, -- /* 00000208 jz 0x245 */ 0x74, 0x3B, -+ /* 00000208 jz 0x255 */ 0x74, 0x4B, - /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F, -- /* 0000020D jz 0x269 */ 0x74, 0x5A, -+ /* 0000020D jz 0x289 */ 0x74, 0x7A, - /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F, -- /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01, -+ /* 00000212 jz word 0x361 */ 0x0F, 0x84, 0x4B, 0x01, - /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F, -- /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01, -+ /* 00000219 jz word 0x36e */ 0x0F, 0x84, 0x51, 0x01, - /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F, -- /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01, -+ /* 00000220 jz word 0x378 */ 0x0F, 0x84, 0x54, 0x01, - /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00, -- /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01, -- /* 0000022B jmp short 0x22b */ 0xEB, 0xFE, -- /* 0000022D push es */ 0x06, -- /* 0000022E push di */ 0x57, -- /* 0000022F push ds */ 0x1E, -- /* 00000230 push si */ 0x56, -- /* 00000231 push cx */ 0x51, -- /* 00000232 push cs */ 0x0E, -- /* 00000233 pop ds */ 0x1F, -- /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00, -- /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01, -- /* 0000023A cld */ 0xFC, -- /* 0000023B rep movsb */ 0xF3, 0xA4, -- /* 0000023D pop cx */ 0x59, -- /* 0000023E pop si */ 0x5E, -- /* 0000023F pop ds */ 0x1F, -- /* 00000240 pop di */ 0x5F, -- /* 00000241 pop es */ 0x07, -- /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01, -- /* 00000245 push es */ 0x06, -- /* 00000246 push di */ 0x57, -- /* 00000247 push ds */ 0x1E, -- /* 00000248 push si */ 0x56, -- /* 00000249 push cx */ 0x51, -- /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, -- /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, -- /* 00000252 jz 0x256 */ 0x74, 0x02, -- /* 00000254 jmp short 0x22b */ 0xEB, 0xD5, -- /* 00000256 push cs */ 0x0E, -- /* 00000257 pop ds */ 0x1F, -- /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01, -- /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01, -- /* 0000025E cld */ 0xFC, -- /* 0000025F rep movsb */ 0xF3, 0xA4, -- /* 00000261 pop cx */ 0x59, -- /* 00000262 pop si */ 0x5E, -- /* 00000263 pop ds */ 0x1F, -- /* 00000264 pop di */ 0x5F, -- /* 00000265 pop es */ 0x07, -- /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00, -- /* 00000269 push dx */ 0x52, -- /* 0000026A push ax */ 0x50, -- /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, -- /* 0000026F jz 0x273 */ 0x74, 0x02, -- /* 00000271 jmp short 0x22b */ 0xEB, 0xB8, -- /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, -- /* 00000276 mov al,0x20 */ 0xB0, 0x20, -- /* 00000278 out dx,al */ 0xEE, -- /* 00000279 push dx */ 0x52, -- /* 0000027A push ax */ 0x50, -- /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00, -- /* 00000281 out dx,ax */ 0xEF, -- /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00, -- /* 00000288 out dx,ax */ 0xEF, -- /* 00000289 pop ax */ 0x58, -- /* 0000028A pop dx */ 0x5A, -- /* 0000028B push dx */ 0x52, -- /* 0000028C push ax */ 0x50, -- /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00, -- /* 00000293 out dx,ax */ 0xEF, -- /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00, -- /* 0000029A out dx,ax */ 0xEF, -- /* 0000029B pop ax */ 0x58, -- /* 0000029C pop dx */ 0x5A, -- /* 0000029D push dx */ 0x52, -- /* 0000029E push ax */ 0x50, -- /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00, -- /* 000002A5 out dx,ax */ 0xEF, -- /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00, -- /* 000002AC out dx,ax */ 0xEF, -- /* 000002AD pop ax */ 0x58, -- /* 000002AE pop dx */ 0x5A, -- /* 000002AF push dx */ 0x52, -- /* 000002B0 push ax */ 0x50, -- /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00, -- /* 000002B7 out dx,ax */ 0xEF, -- /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00, -- /* 000002BE out dx,ax */ 0xEF, -- /* 000002BF pop ax */ 0x58, -- /* 000002C0 pop dx */ 0x5A, -- /* 000002C1 push dx */ 0x52, -- /* 000002C2 push ax */ 0x50, -- /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00, -- /* 000002C9 out dx,ax */ 0xEF, -- /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00, -- /* 000002D0 out dx,ax */ 0xEF, -- /* 000002D1 pop ax */ 0x58, -- /* 000002D2 pop dx */ 0x5A, -- /* 000002D3 push dx */ 0x52, -- /* 000002D4 push ax */ 0x50, -- /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00, -- /* 000002DB out dx,ax */ 0xEF, -- /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04, -- /* 000002E2 out dx,ax */ 0xEF, -- /* 000002E3 pop ax */ 0x58, -- /* 000002E4 pop dx */ 0x5A, -- /* 000002E5 push dx */ 0x52, -- /* 000002E6 push ax */ 0x50, -- /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00, -- /* 000002ED out dx,ax */ 0xEF, -- /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04, -- /* 000002F4 out dx,ax */ 0xEF, -- /* 000002F5 pop ax */ 0x58, -- /* 000002F6 pop dx */ 0x5A, -- /* 000002F7 push dx */ 0x52, -- /* 000002F8 push ax */ 0x50, -- /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00, -- /* 000002FF out dx,ax */ 0xEF, -- /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03, -- /* 00000306 out dx,ax */ 0xEF, -- /* 00000307 pop ax */ 0x58, -- /* 00000308 pop dx */ 0x5A, -- /* 00000309 push dx */ 0x52, -- /* 0000030A push ax */ 0x50, -- /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00, -- /* 00000311 out dx,ax */ 0xEF, -- /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03, -- /* 00000318 out dx,ax */ 0xEF, -- /* 00000319 pop ax */ 0x58, -- /* 0000031A pop dx */ 0x5A, -- /* 0000031B push dx */ 0x52, -- /* 0000031C push ax */ 0x50, -- /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -- /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00, -- /* 00000323 out dx,ax */ 0xEF, -- /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -- /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00, -- /* 0000032A out dx,ax */ 0xEF, -- /* 0000032B pop ax */ 0x58, -- /* 0000032C pop dx */ 0x5A, -- /* 0000032D pop ax */ 0x58, -- /* 0000032E pop dx */ 0x5A, -- /* 0000032F jmp short 0x34c */ 0xEB, 0x1B, -- /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, -- /* 00000334 jmp short 0x34c */ 0xEB, 0x16, -- /* 00000336 jmp short 0x350 */ 0xEB, 0x18, -- /* 00000338 jmp short 0x350 */ 0xEB, 0x16, -- /* 0000033A cmp al,0x3 */ 0x3C, 0x03, -- /* 0000033C jz 0x345 */ 0x74, 0x07, -- /* 0000033E cmp al,0x12 */ 0x3C, 0x12, -- /* 00000340 jz 0x349 */ 0x74, 0x07, -- /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE, -- /* 00000345 mov al,0x30 */ 0xB0, 0x30, -- /* 00000347 jmp short 0x34b */ 0xEB, 0x02, -- /* 00000349 mov al,0x20 */ 0xB0, 0x20, -- /* 0000034B iretw */ 0xCF, -- /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00, -- /* 0000034F iretw */ 0xCF, -- /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01, -- /* 00000353 iretw */ 0xCF, -+ /* 00000227 jz word 0x382 */ 0x0F, 0x84, 0x57, 0x01, -+ /* 0000022B push si */ 0x56, -+ /* 0000022C mov si,0x3e9 */ 0xBE, 0xE9, 0x03, -+ /* 0000022F call word 0x3c4 */ 0xE8, 0x92, 0x01, -+ /* 00000232 pop si */ 0x5E, -+ /* 00000233 jmp short 0x233 */ 0xEB, 0xFE, -+ /* 00000235 push es */ 0x06, -+ /* 00000236 push di */ 0x57, -+ /* 00000237 push ds */ 0x1E, -+ /* 00000238 push si */ 0x56, -+ /* 00000239 push cx */ 0x51, -+ /* 0000023A push si */ 0x56, -+ /* 0000023B mov si,0x3fb */ 0xBE, 0xFB, 0x03, -+ /* 0000023E call word 0x3c4 */ 0xE8, 0x83, 0x01, -+ /* 00000241 pop si */ 0x5E, -+ /* 00000242 push cs */ 0x0E, -+ /* 00000243 pop ds */ 0x1F, -+ /* 00000244 mov si,0x0 */ 0xBE, 0x00, 0x00, -+ /* 00000247 mov cx,0x100 */ 0xB9, 0x00, 0x01, -+ /* 0000024A cld */ 0xFC, -+ /* 0000024B rep movsb */ 0xF3, 0xA4, -+ /* 0000024D pop cx */ 0x59, -+ /* 0000024E pop si */ 0x5E, -+ /* 0000024F pop ds */ 0x1F, -+ /* 00000250 pop di */ 0x5F, -+ /* 00000251 pop es */ 0x07, -+ /* 00000252 jmp word 0x3ac */ 0xE9, 0x57, 0x01, -+ /* 00000255 push es */ 0x06, -+ /* 00000256 push di */ 0x57, -+ /* 00000257 push ds */ 0x1E, -+ /* 00000258 push si */ 0x56, -+ /* 00000259 push cx */ 0x51, -+ /* 0000025A push si */ 0x56, -+ /* 0000025B mov si,0x404 */ 0xBE, 0x04, 0x04, -+ /* 0000025E call word 0x3c4 */ 0xE8, 0x63, 0x01, -+ /* 00000261 pop si */ 0x5E, -+ /* 00000262 and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, -+ /* 00000266 cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, -+ /* 0000026A jz 0x276 */ 0x74, 0x0A, -+ /* 0000026C push si */ 0x56, -+ /* 0000026D mov si,0x432 */ 0xBE, 0x32, 0x04, -+ /* 00000270 call word 0x3c4 */ 0xE8, 0x51, 0x01, -+ /* 00000273 pop si */ 0x5E, -+ /* 00000274 jmp short 0x233 */ 0xEB, 0xBD, -+ /* 00000276 push cs */ 0x0E, -+ /* 00000277 pop ds */ 0x1F, -+ /* 00000278 mov si,0x100 */ 0xBE, 0x00, 0x01, -+ /* 0000027B mov cx,0x100 */ 0xB9, 0x00, 0x01, -+ /* 0000027E cld */ 0xFC, -+ /* 0000027F rep movsb */ 0xF3, 0xA4, -+ /* 00000281 pop cx */ 0x59, -+ /* 00000282 pop si */ 0x5E, -+ /* 00000283 pop ds */ 0x1F, -+ /* 00000284 pop di */ 0x5F, -+ /* 00000285 pop es */ 0x07, -+ /* 00000286 jmp word 0x3ac */ 0xE9, 0x23, 0x01, -+ /* 00000289 push dx */ 0x52, -+ /* 0000028A push ax */ 0x50, -+ /* 0000028B push si */ 0x56, -+ /* 0000028C mov si,0x41a */ 0xBE, 0x1A, 0x04, -+ /* 0000028F call word 0x3c4 */ 0xE8, 0x32, 0x01, -+ /* 00000292 pop si */ 0x5E, -+ /* 00000293 cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, -+ /* 00000297 jz 0x2a3 */ 0x74, 0x0A, -+ /* 00000299 push si */ 0x56, -+ /* 0000029A mov si,0x432 */ 0xBE, 0x32, 0x04, -+ /* 0000029D call word 0x3c4 */ 0xE8, 0x24, 0x01, -+ /* 000002A0 pop si */ 0x5E, -+ /* 000002A1 jmp short 0x233 */ 0xEB, 0x90, -+ /* 000002A3 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, -+ /* 000002A6 mov al,0x20 */ 0xB0, 0x20, -+ /* 000002A8 out dx,al */ 0xEE, -+ /* 000002A9 push dx */ 0x52, -+ /* 000002AA push ax */ 0x50, -+ /* 000002AB mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 000002AE mov ax,0x4 */ 0xB8, 0x04, 0x00, -+ /* 000002B1 out dx,ax */ 0xEF, -+ /* 000002B2 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 000002B5 mov ax,0x0 */ 0xB8, 0x00, 0x00, -+ /* 000002B8 out dx,ax */ 0xEF, -+ /* 000002B9 pop ax */ 0x58, -+ /* 000002BA pop dx */ 0x5A, -+ /* 000002BB push dx */ 0x52, -+ /* 000002BC push ax */ 0x50, -+ /* 000002BD mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 000002C0 mov ax,0x5 */ 0xB8, 0x05, 0x00, -+ /* 000002C3 out dx,ax */ 0xEF, -+ /* 000002C4 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 000002C7 mov ax,0x0 */ 0xB8, 0x00, 0x00, -+ /* 000002CA out dx,ax */ 0xEF, -+ /* 000002CB pop ax */ 0x58, -+ /* 000002CC pop dx */ 0x5A, -+ /* 000002CD push dx */ 0x52, -+ /* 000002CE push ax */ 0x50, -+ /* 000002CF mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 000002D2 mov ax,0x8 */ 0xB8, 0x08, 0x00, -+ /* 000002D5 out dx,ax */ 0xEF, -+ /* 000002D6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 000002D9 mov ax,0x0 */ 0xB8, 0x00, 0x00, -+ /* 000002DC out dx,ax */ 0xEF, -+ /* 000002DD pop ax */ 0x58, -+ /* 000002DE pop dx */ 0x5A, -+ /* 000002DF push dx */ 0x52, -+ /* 000002E0 push ax */ 0x50, -+ /* 000002E1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 000002E4 mov ax,0x9 */ 0xB8, 0x09, 0x00, -+ /* 000002E7 out dx,ax */ 0xEF, -+ /* 000002E8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 000002EB mov ax,0x0 */ 0xB8, 0x00, 0x00, -+ /* 000002EE out dx,ax */ 0xEF, -+ /* 000002EF pop ax */ 0x58, -+ /* 000002F0 pop dx */ 0x5A, -+ /* 000002F1 push dx */ 0x52, -+ /* 000002F2 push ax */ 0x50, -+ /* 000002F3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 000002F6 mov ax,0x3 */ 0xB8, 0x03, 0x00, -+ /* 000002F9 out dx,ax */ 0xEF, -+ /* 000002FA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 000002FD mov ax,0x20 */ 0xB8, 0x20, 0x00, -+ /* 00000300 out dx,ax */ 0xEF, -+ /* 00000301 pop ax */ 0x58, -+ /* 00000302 pop dx */ 0x5A, -+ /* 00000303 push dx */ 0x52, -+ /* 00000304 push ax */ 0x50, -+ /* 00000305 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 00000308 mov ax,0x1 */ 0xB8, 0x01, 0x00, -+ /* 0000030B out dx,ax */ 0xEF, -+ /* 0000030C mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 0000030F mov ax,0x400 */ 0xB8, 0x00, 0x04, -+ /* 00000312 out dx,ax */ 0xEF, -+ /* 00000313 pop ax */ 0x58, -+ /* 00000314 pop dx */ 0x5A, -+ /* 00000315 push dx */ 0x52, -+ /* 00000316 push ax */ 0x50, -+ /* 00000317 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 0000031A mov ax,0x6 */ 0xB8, 0x06, 0x00, -+ /* 0000031D out dx,ax */ 0xEF, -+ /* 0000031E mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 00000321 mov ax,0x400 */ 0xB8, 0x00, 0x04, -+ /* 00000324 out dx,ax */ 0xEF, -+ /* 00000325 pop ax */ 0x58, -+ /* 00000326 pop dx */ 0x5A, -+ /* 00000327 push dx */ 0x52, -+ /* 00000328 push ax */ 0x50, -+ /* 00000329 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 0000032C mov ax,0x2 */ 0xB8, 0x02, 0x00, -+ /* 0000032F out dx,ax */ 0xEF, -+ /* 00000330 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 00000333 mov ax,0x300 */ 0xB8, 0x00, 0x03, -+ /* 00000336 out dx,ax */ 0xEF, -+ /* 00000337 pop ax */ 0x58, -+ /* 00000338 pop dx */ 0x5A, -+ /* 00000339 push dx */ 0x52, -+ /* 0000033A push ax */ 0x50, -+ /* 0000033B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 0000033E mov ax,0x7 */ 0xB8, 0x07, 0x00, -+ /* 00000341 out dx,ax */ 0xEF, -+ /* 00000342 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 00000345 mov ax,0x300 */ 0xB8, 0x00, 0x03, -+ /* 00000348 out dx,ax */ 0xEF, -+ /* 00000349 pop ax */ 0x58, -+ /* 0000034A pop dx */ 0x5A, -+ /* 0000034B push dx */ 0x52, -+ /* 0000034C push ax */ 0x50, -+ /* 0000034D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, -+ /* 00000350 mov ax,0x4 */ 0xB8, 0x04, 0x00, -+ /* 00000353 out dx,ax */ 0xEF, -+ /* 00000354 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, -+ /* 00000357 mov ax,0x41 */ 0xB8, 0x41, 0x00, -+ /* 0000035A out dx,ax */ 0xEF, -+ /* 0000035B pop ax */ 0x58, -+ /* 0000035C pop dx */ 0x5A, -+ /* 0000035D pop ax */ 0x58, -+ /* 0000035E pop dx */ 0x5A, -+ /* 0000035F jmp short 0x3ac */ 0xEB, 0x4B, -+ /* 00000361 push si */ 0x56, -+ /* 00000362 mov si,0x411 */ 0xBE, 0x11, 0x04, -+ /* 00000365 call word 0x3c4 */ 0xE8, 0x5C, 0x00, -+ /* 00000368 pop si */ 0x5E, -+ /* 00000369 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, -+ /* 0000036C jmp short 0x3ac */ 0xEB, 0x3E, -+ /* 0000036E push si */ 0x56, -+ /* 0000036F mov si,0x43f */ 0xBE, 0x3F, 0x04, -+ /* 00000372 call word 0x3c4 */ 0xE8, 0x4F, 0x00, -+ /* 00000375 pop si */ 0x5E, -+ /* 00000376 jmp short 0x3b8 */ 0xEB, 0x40, -+ /* 00000378 push si */ 0x56, -+ /* 00000379 mov si,0x452 */ 0xBE, 0x52, 0x04, -+ /* 0000037C call word 0x3c4 */ 0xE8, 0x45, 0x00, -+ /* 0000037F pop si */ 0x5E, -+ /* 00000380 jmp short 0x3b8 */ 0xEB, 0x36, -+ /* 00000382 push si */ 0x56, -+ /* 00000383 mov si,0x423 */ 0xBE, 0x23, 0x04, -+ /* 00000386 call word 0x3c4 */ 0xE8, 0x3B, 0x00, -+ /* 00000389 pop si */ 0x5E, -+ /* 0000038A cmp al,0x3 */ 0x3C, 0x03, -+ /* 0000038C jz 0x39d */ 0x74, 0x0F, -+ /* 0000038E cmp al,0x12 */ 0x3C, 0x12, -+ /* 00000390 jz 0x3a1 */ 0x74, 0x0F, -+ /* 00000392 push si */ 0x56, -+ /* 00000393 mov si,0x432 */ 0xBE, 0x32, 0x04, -+ /* 00000396 call word 0x3c4 */ 0xE8, 0x2B, 0x00, -+ /* 00000399 pop si */ 0x5E, -+ /* 0000039A jmp word 0x233 */ 0xE9, 0x96, 0xFE, -+ /* 0000039D mov al,0x30 */ 0xB0, 0x30, -+ /* 0000039F jmp short 0x3a3 */ 0xEB, 0x02, -+ /* 000003A1 mov al,0x20 */ 0xB0, 0x20, -+ /* 000003A3 push si */ 0x56, -+ /* 000003A4 mov si,0x3d6 */ 0xBE, 0xD6, 0x03, -+ /* 000003A7 call word 0x3c4 */ 0xE8, 0x1A, 0x00, -+ /* 000003AA pop si */ 0x5E, -+ /* 000003AB iretw */ 0xCF, -+ /* 000003AC push si */ 0x56, -+ /* 000003AD mov si,0x3d6 */ 0xBE, 0xD6, 0x03, -+ /* 000003B0 call word 0x3c4 */ 0xE8, 0x11, 0x00, -+ /* 000003B3 pop si */ 0x5E, -+ /* 000003B4 mov ax,0x4f */ 0xB8, 0x4F, 0x00, -+ /* 000003B7 iretw */ 0xCF, -+ /* 000003B8 push si */ 0x56, -+ /* 000003B9 mov si,0x3dc */ 0xBE, 0xDC, 0x03, -+ /* 000003BC call word 0x3c4 */ 0xE8, 0x05, 0x00, -+ /* 000003BF pop si */ 0x5E, -+ /* 000003C0 mov ax,0x14f */ 0xB8, 0x4F, 0x01, -+ /* 000003C3 iretw */ 0xCF, -+ /* 000003C4 pushaw */ 0x60, -+ /* 000003C5 push ds */ 0x1E, -+ /* 000003C6 push cs */ 0x0E, -+ /* 000003C7 pop ds */ 0x1F, -+ /* 000003C8 mov dx,0x402 */ 0xBA, 0x02, 0x04, -+ /* 000003CB lodsb */ 0xAC, -+ /* 000003CC cmp al,0x0 */ 0x3C, 0x00, -+ /* 000003CE jz 0x3d3 */ 0x74, 0x03, -+ /* 000003D0 out dx,al */ 0xEE, -+ /* 000003D1 jmp short 0x3cb */ 0xEB, 0xF8, -+ /* 000003D3 pop ds */ 0x1F, -+ /* 000003D4 popaw */ 0x61, -+ /* 000003D5 ret */ 0xC3, -+ /* 000003D6 inc bp */ 0x45, -+ /* 000003D7 js 0x442 */ 0x78, 0x69, -+ /* 000003D9 jz 0x3e5 */ 0x74, 0x0A, -+ /* 000003DB add [di+0x6e],dl */ 0x00, 0x55, 0x6E, -+ /* 000003DE jnc 0x455 */ 0x73, 0x75, -+ /* 000003E0 jo 0x452 */ 0x70, 0x70, -+ /* 000003E2 outsw */ 0x6F, -+ /* 000003E3 jc 0x459 */ 0x72, 0x74, -+ /* 000003E5 or al,[fs:bx+si] */ 0x65, 0x64, 0x0A, 0x00, -+ /* 000003E9 push bp */ 0x55, -+ /* 000003EA outsb */ 0x6E, -+ /* 000003EB imul bp,[bp+0x6f],byte +0x77 */ 0x6B, 0x6E, 0x6F, 0x77, -+ /* 000003EF outsb */ 0x6E, -+ /* 000003F0 and [bp+0x75],al */ 0x20, 0x46, 0x75, -+ /* 000003F3 outsb */ 0x6E, -+ /* 000003F4 arpl [si+0x69],si */ 0x63, 0x74, 0x69, -+ /* 000003F7 outsw */ 0x6F, -+ /* 000003F8 outsb */ 0x6E, -+ /* 000003F9 or al,[bx+si] */ 0x0A, 0x00, -+ /* 000003FB inc di */ 0x47, -+ /* 000003FC gs jz 0x448 */ 0x65, 0x74, 0x49, -+ /* 000003FF outsb */ 0x6E, -+ /* 00000400 outsd */ 0x66, 0x6F, -+ /* 00000402 or al,[bx+si] */ 0x0A, 0x00, -+ /* 00000404 inc di */ 0x47, -+ /* 00000405 gs jz 0x455 */ 0x65, 0x74, 0x4D, -+ /* 00000408 outsw */ 0x6F, -+ /* 00000409 gs dec cx */ 0x64, 0x65, 0x49, -+ /* 0000040C outsb */ 0x6E, -+ /* 0000040D outsd */ 0x66, 0x6F, -+ /* 0000040F or al,[bx+si] */ 0x0A, 0x00, -+ /* 00000411 inc di */ 0x47, -+ /* 00000412 gs jz 0x462 */ 0x65, 0x74, 0x4D, -+ /* 00000415 outsw */ 0x6F, -+ /* 00000416 or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, -+ /* 0000041A push bx */ 0x53, -+ /* 0000041B gs jz 0x46b */ 0x65, 0x74, 0x4D, -+ /* 0000041E outsw */ 0x6F, -+ /* 0000041F or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, -+ /* 00000423 push bx */ 0x53, -+ /* 00000424 gs jz 0x474 */ 0x65, 0x74, 0x4D, -+ /* 00000427 outsw */ 0x6F, -+ /* 00000428 gs dec sp */ 0x64, 0x65, 0x4C, -+ /* 0000042B gs a32 popaw */ 0x65, 0x67, 0x61, -+ /* 0000042E arpl [bx+di+0xa],di */ 0x63, 0x79, 0x0A, -+ /* 00000431 add [di+0x6e],dl */ 0x00, 0x55, 0x6E, -+ /* 00000434 imul bp,[bx+0x77],byte +0x6e */ 0x6B, 0x6F, 0x77, 0x6E, -+ /* 00000438 and [di+0x6f],cl */ 0x20, 0x4D, 0x6F, -+ /* 0000043B or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, -+ /* 0000043F inc di */ 0x47, -+ /* 00000440 gs jz 0x493 */ 0x65, 0x74, 0x50, -+ /* 00000443 insw */ 0x6D, -+ /* 00000444 inc bx */ 0x43, -+ /* 00000445 popaw */ 0x61, -+ /* 00000446 jo 0x4a9 */ 0x70, 0x61, -+ /* 00000448 bound bp,[bx+di+0x6c] */ 0x62, 0x69, 0x6C, -+ /* 0000044B imul si,[si+0x69],word 0x7365 */ 0x69, 0x74, 0x69, 0x65, 0x73, -+ /* 00000450 or al,[bx+si] */ 0x0A, 0x00, -+ /* 00000452 push dx */ 0x52, -+ /* 00000453 gs popaw */ 0x65, 0x61, -+ /* 00000455 fs inc bp */ 0x64, 0x45, -+ /* 00000457 fs */ 0x64, -+ /* 00000458 db 0x69 */ 0x69, -+ /* 00000459 or al,[fs:bx+si] */ 0x64, 0x0A, 0x00, - }; - #endif diff --git a/0005-advertise-OpenSSL-on-TianoCore-splash-screen-boot-lo.patch b/0005-advertise-OpenSSL-on-TianoCore-splash-screen-boot-lo.patch new file mode 100644 index 0000000..7b26aef --- /dev/null +++ b/0005-advertise-OpenSSL-on-TianoCore-splash-screen-boot-lo.patch @@ -0,0 +1,3123 @@ +From ade02daad705e1a4fd6468136de8fcb886f202a2 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 11 Jun 2014 23:33:33 +0200 +Subject: [PATCH] advertise OpenSSL on TianoCore splash screen / boot logo + +Because we may include the OpenSSL library in our OVMF and AAVMF builds +now, we should advertise it as required by its license. This patch takes +the original TianoCore logo, shifts it up by 20 pixels, and adds the +horizontally centered message + + This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit (http://www.openssl.org/) + +below. + +Logo-OpenSSL.bmp: PC bitmap, Windows 3.x format, 469 x 111 x 24 +Logo.bmp: PC bitmap, Windows 3.x format, 193 x 58 x 8 + +Downstream only because upstream edk2 does not intend to release a +secure-boot-enabled OVMF build. (However the advertising requirement in +the OpenSSL license, +"CryptoPkg/Library/OpensslLib/openssl-1.0.2*/LICENSE", has been discussed +nonetheless, which is why I'm changing the logo.) + +Notes about the 9ece15a -> c9e5618 rebase: +- Logo.bmp is no longer modified in-place; instead a modified copy is + created. That's because AAVMF includes the logo too, but it doesn't + include OpenSSL / Secure Boot, so we need the original copy too. + +Notes about the c9e5618 -> b9ffeab rebase: +- AAVMF gained Secure Boot support, therefore the logo is again modified + in the common location, and no FDF changes are necessary. + +Notes about the d7c0dfa -> 90bb4c5 rebase: + +- squash in the following downstream-only commits (made originally for + https://bugzilla.redhat.com/show_bug.cgi?id=1308678): + + - eef9eb0 restore TianoCore splash logo without OpenSSL advertisment + (RHEL only) + + - 25842f0 OvmfPkg, ArmVirtPkg: show OpenSSL-less logo without Secure + Boot (RH only) + + The reason is that ideas keep changing when and where to include the + Secure Boot feature, so the logo must be controllable directly on the + build command line, from the RPM spec file. See the following + references: + + - https://post-office.corp.redhat.com/mailman/private/virt-devel/2016-March/ms... + - https://post-office.corp.redhat.com/mailman/private/virt-devel/2016-April/ms... + - https://bugzilla.redhat.com/show_bug.cgi?id=1323363 + +- This squashed variant should remain the final version of this patch. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- For more fun, upstream completely changed the way logo bitmaps are + embedded in the firmware binary (see for example commit ab970515d2c6, + "OvmfPkg: Use the new LogoDxe driver", 2016-09-26). Therefore in this + rebase, we reimplement the previous downstream-only commit e775fb20c999, + as described below. + +- Beyond the new bitmap file (which we preserve intact from the last + downstream branch), we introduce: + + - a new IDF (image description file) referencing the new BMP, + + - a new driver INF file, referencing the new BMP and new IDF (same C + source code though), + + - a new UNI (~description) file for the new driver INF file. + +- In the OVMF DSC and FDF files, we select the new driver INF for + inclusion if either SECURE_BOOT_ENABLE, NETWORK_IP6_ENABLE, or + TLS_ENABLE is set, as they all make use of OpenSSL (although + different subsets of it). + +- In the AAVMF DSC and FDF files, we only look at SECURE_BOOT_ENABLE, + or NETWORK_IP6_ENABLE, because the ArmVirtQemu platform does not + support TLS_ENABLE yet. + +- This patch is best displayed with "git show --find-copies-harder". + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- After picking previous downstream-only commit 32192c62e289, carry new + upstream commit e01e9ae28250 ("MdeModulePkg/LogoDxe: Add missing + dependency gEfiHiiImageExProtocolGuid", 2017-03-16) over to + "LogoOpenSSLDxe.inf". + +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 32192c62e289f261f5ce74acee48e5a94561f10b) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + ArmVirtPkg/ArmVirtQemu.dsc | 4 + + ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 4 + + ArmVirtPkg/ArmVirtQemuKernel.dsc | 4 + + MdeModulePkg/Logo/Logo-OpenSSL.bmp.b64 | 2743 ++++++++++++++++++++++++ + MdeModulePkg/Logo/Logo-OpenSSL.idf | 15 + + MdeModulePkg/Logo/LogoOpenSSLDxe.inf | 61 + + MdeModulePkg/Logo/LogoOpenSSLDxe.uni | 22 + + OvmfPkg/OvmfPkgIa32.dsc | 4 + + OvmfPkg/OvmfPkgIa32.fdf | 4 + + OvmfPkg/OvmfPkgIa32X64.dsc | 4 + + OvmfPkg/OvmfPkgIa32X64.fdf | 4 + + OvmfPkg/OvmfPkgX64.dsc | 4 + + OvmfPkg/OvmfPkgX64.fdf | 4 + + 13 files changed, 2877 insertions(+) + create mode 100644 MdeModulePkg/Logo/Logo-OpenSSL.bmp.b64 + create mode 100644 MdeModulePkg/Logo/Logo-OpenSSL.idf + create mode 100644 MdeModulePkg/Logo/LogoOpenSSLDxe.inf + create mode 100644 MdeModulePkg/Logo/LogoOpenSSLDxe.uni + +diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc +index 885c6b14b8..a7a3899560 100644 +--- a/ArmVirtPkg/ArmVirtQemu.dsc ++++ b/ArmVirtPkg/ArmVirtQemu.dsc +@@ -327,7 +327,11 @@ + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +index a6390bd4b8..20a5bcb27b 100644 +--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc ++++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +@@ -202,7 +202,11 @@ READ_LOCK_STATUS = TRUE + # + # TianoCore logo (splash screen) + # ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) ++ INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Ramdisk support +diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc +index 434d6861a5..6e4e0249ef 100644 +--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc ++++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc +@@ -316,7 +316,11 @@ + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/MdeModulePkg/Logo/Logo-OpenSSL.bmp.b64 b/MdeModulePkg/Logo/Logo-OpenSSL.bmp.b64 +new file mode 100644 +index 0000000000..567ca32f05 +--- /dev/null ++++ b/MdeModulePkg/Logo/Logo-OpenSSL.bmp.b64 +@@ -0,0 +1,2743 @@ ++Qk22YgIAAAAAADYAAAAoAAAA1QEAAG8AAAABABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWlpav7+/CQkJAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQUoKCg6enp7+/vrKys ++PT09AAAAAAAAAAAAAAAAAAAAAAAACQkJwMDAWlpaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAERERN3d3RUVFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALy8vHp6ehAQEAYGBi8vL8HBwWpqagAAAAAAAAAAAAAA ++AAAAAAAAABYWFt/f30NDQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgLU1NRU ++VFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAxMTEEBAQAAAAAAAAAAAAoKCjd3d0AAAAAAAAAAAAAAAAAAAAAAAAAAABXV1fS0tIB ++AQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAA////AAAAAAAAAAAAAAAAaGho3t7e+vr629vbZWVlAAAAAAAAAAAA////AAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAALy8vzs7O9/f309PTPj4+6urqAgICAAAAMzMzxcXF9fX18PDws7OzHx8f ++AAAAAAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAgAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAA ++AAAA////AAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAARkZG5eXl6urqAAAAAAAA ++////AAAAAAAAAAAAAAAA////AAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAgAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAgICaGhozMzM9fX19fX1ycnJYmJiAQEBAAAAAAAAAAAA////PDw8zMzM+Pj4 ++5OTkYGBgAAAAAAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAgAAAAAAAA////AAAAAAAAAAAAAAAA ++////AAAAAAAAAAAARUVFtLS05eXl+vr68fHxxMTEU1NTAAAAAAAAAAAAAAAARUVFtLS05eXl+vr6 ++8fHxxMTEU1NTAAAAAAAAAAAA////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAA////AAAAAAAAAAAAAAAAaGho3t7e+vr629vbZWVlAAAAAAAAAAAAAAAAaGho3t7e +++vr629vbZWVlAAAAAAAAAAAAAAAA////AAAAAAAA////AAAAAAAAAAAAAAAAYWFhw8PDCAgI//// ++AAAAAAAAAAAARkZG5eXl6urqAAAAAAAAAAAAAAAAAAAAT09Pzc3NAAAAAAAAAAAAAAAA////AAAA ++AAAAAAAAAAAA////AAAAAAAARkZG5eXl6urqAAAAAAAARkZG5eXl6urqAAAA////PDw8zMzM+Pj4 ++5OTkYGBgAAAAAAAAAAAAAAAA////AAAAAAAA3NzcFRUVAAAAAAAA3NzcFRUVAAAAAAAAAAAAAAAA ++AAAAKysr////Ly8vAAAALy8v////KysrAAAAAAAAAAAAAAAAKysr////Ly8vAAAALy8v////Kysr ++AAAAAAAAAAAAAAAAAAAAKysr////Ly8vAAAALy8v////KysrAAAAAAAAAAAA////AAAAAAAAAAAA ++aGho3t7e+vr629vbZWVlAAAAAAAAAAAAAAAA////PDw8zMzM+Pj45OTkYGBgAAAAAAAAAAAAAAAA ++V1dX09PT+vr67+/vq6urICAgAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAAMzMzxcXF9fX1 ++8PDws7OzHx8fAAAAAAAAMzMzxcXF9fX18PDws7OzHx8fAAAAAAAAAAAA////AAAAAAAAAAAA//// ++AAAAAAAAAAAAaGho3t7e+vr629vbZWVlAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAZ2dn5eXl ++9PT0urq6KCgo/Pz8AAAAAAAA3NzcFRUVAAAAAAAAAAAAAAAAzs7OS0tLAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAFJS ++Utvb2zY2NgkJCTMzM9fX11NTUwAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDA ++wICAgAoKCi0tLb29vfj4+AAAAAAAAMLCwmxsbA0NDQgICG9vb76+vgAAAAAAAAAAAEhISN3d3T8/ ++PwkJCRoaGoWFhbS0tAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAP///wAAAAAAAAAAAAAA ++AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAOTk5DMzMwoKCgAAAAAAAP///wAAAAAAAAAAAAAAAP// ++/wAAAAAAAEhISN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKSkpMzM ++zERERAsLCwoKCj4+PsPDw5ubmwAAAAAAAAAAAP7+/srKyj09PQoKCjExMdfX10xMTAAAAAAAAEhI ++SN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAFhYWOvr62Zm ++ZhgYGAMDAxQUFE1NTdbW1lVVVQAAAAAAAFhYWOvr62ZmZhgYGAMDAxQUFE1NTdbW1lVVVQAAAAAA ++AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAA ++AAAAAFJSUtvb2zY2NgkJCTMzM9fX11NTUwAAAAAAAFJSUtvb2zY2NgkJCTMzM9fX11NTUwAAAAAA ++AAAAAP///wAAAAAAAP///wAAAAAAAAAAAFFRUdLS0hEREQAAAP///wAAAAAAAAAAAOTk5DMzMwoK ++CgAAAAAAAAAAAAAAAAAAAJubm3d3dwAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAA ++AOTk5DMzMwoKCgAAAAAAAOTk5DMzMwoKCgAAAP7+/srKyj09PQoKCjExMdfX10xMTAAAAAAAAAAA ++AP///wAAAAAAAJqamlVVVQAAAAAAAJqamlVVVQAAAAAAAAAAAAAAAAAAAGpqav7+/mVlZQAAAGVl ++Zf7+/mlpaQAAAAAAAAAAAAAAAGpqav7+/mVlZQAAAGVlZf7+/mlpaQAAAAAAAAAAAAAAAAAAAGpq ++av7+/mVlZQAAAGVlZf7+/mlpaQAAAAAAAAAAAP///wAAAAAAAFJSUtvb2zY2NgkJCTMzM9fX11NT ++UwAAAAAAAAAAAP7+/srKyj09PQoKCjExMdfX10xMTAAAAAAAAEhISN3d3T8/PwkJCRoaGoWFhbS0 ++tAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAMLCwmxsbA0NDQgICG9vb76+vgAAAAAAAMLC ++wmxsbA0NDQgICG9vb76+vgAAAAAAAAAAAP///wAAAAAAAAAAAP///wAAAAAAAFJSUtvb2zY2NgkJ ++CTMzM9fX11NTUwAAAAAAAP///wAAAAAAAAAAAAAAAGhoaM3NzSoqKgwMDFZWVtDQ0P///wAAAAAA ++AJqamlVVVQAAAAAAAAAAAAAAAHp6epaWlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAC9vb1OTk4AAAAAAAAAAABMTEy+ ++vr4AAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADx8fESEhIAAAAAAAA8PDz///8A ++AAAAAAAAAAAAAAAAAAAAAAAICAj09PQAAAAAAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAA ++AAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAC4uLhJSUkAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUVFTd3d0KCgoAAAAAAAAAAAAAAAAHBwfN ++zc1PT08AAAAAAAD///9KSkoAAAAAAAAAAABOTk7AwMAAAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAA ++AAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAADLy8tGRkYAAAAAAAAAAAAAAAAAAAAlJSXi ++4uIAAAAAAADLy8tGRkYAAAAAAAAAAAAAAAAAAAAlJSXi4uIAAAAAAAD///8AAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAC9vb1OTk4AAAAAAAAA ++AABMTEy+vr4AAAAAAAC9vb1OTk4AAAAAAAAAAABMTEy+vr4AAAAAAAAAAAD///8AAAAAAAD///8A ++AAAAAABDQ0Pd3d0eHh4AAAAAAAD///8AAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAADW ++1tYyMjIAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAD///8AAAAAAAAAAAAAAAD/ ++//8AAAAAAAAAAAD///9KSkoAAAAAAAAAAABOTk7AwMAAAAAAAAAAAAAAAAAAAAAAAABWVlaWlpYA ++AAAAAABWVlaWlpYAAAAAAAAAAAAAAAAAAACpqanHx8ebm5sAAACbm5vFxcWoqKgAAAAAAAAAAAAA ++AACpqanHx8ebm5sAAACbm5vFxcWoqKgAAAAAAAAAAAAAAAAAAACpqanHx8ebm5sAAACbm5vFxcWo ++qKgAAAAAAAAAAAAAAAAAAAAAAAC9vb1OTk4AAAAAAAAAAABMTEy+vr4AAAAAAAAAAAD///9KSkoA ++AAAAAAAAAABOTk7AwMAAAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAA ++AAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAICAj09PQAAAAAAAAAAAAAAAAAAAAAAAAICAj09PQA ++AAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAC9vb1OTk4AAAAAAAAAAABMTEy+vr4AAAAAAAD/ ++//8AAAAAAAAAAAAAAADOzs5FRUUAAAAAAAAAAABxcXH///8AAAAAAABWVlaWlpYAAAAAAAAAAAAA ++AAA2NjbS0tIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAA////AAAAAAAAAAAA7u7uEhISAAAAAAAAAAAAEhIS7u7uAAAAAAAA////AAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAACgoK////AAAAAAAAAAAAAAAAAAAAIiIi ++MjIyyMjIAAAAAAAAAAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//// ++AAAAAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAA ++AAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAt7e3Xl5eAAAAAAAAAAAAAAAAAAAAAAAAVFRUtLS0AAAAAAAA////EBAQ ++AAAAAAAAAAAAFBQU5ubmAAAAAAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAA ++AAAAAAAA////AAAAAAAAAwMDAAAAAAAAAAAAAAAAAAAAAAAAFhYW5+fnAAAAAAAAAwMDAAAAAAAA ++AAAAAAAAAAAAAAAAFhYW5+fnAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAA7u7uEhISAAAAAAAAAAAAEhIS7u7uAAAAAAAA7u7u ++EhISAAAAAAAAAAAAEhIS7u7uAAAAAAAAAAAA////AAAAAAAA////cHBwODg45OTkLS0tAAAAAAAA ++AAAA////AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAA7e3tFhYWAAAAAAAAAAAAAAAA ++////AAAAAAAAAAAAAAAA////AAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAAAAAA////EBAQ ++AAAAAAAAAAAAFBQU5ubmAAAAAAAAAAAAAAAAAAAAAAAAExMT1dXVAAAAAAAAExMT1dXVAAAAAAAA ++AAAAAAAAAAAA5+fnaWlp0dHRAAAA0dHRZWVl5ubmAAAAAAAAAAAAAAAA5+fnaWlp0dHRAAAA0dHR ++ZWVl5ubmAAAAAAAAAAAAAAAAAAAA5+fnaWlp0dHRAAAA0dHRZWVl5ubmAAAAAAAAAAAAAAAAAAAA ++AAAA7u7uEhISAAAAAAAAAAAAEhIS7u7uAAAAAAAAAAAA////EBAQAAAAAAAAAAAAFBQU5ubmAAAA ++AAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAAAAAA ++AAAAAAAAIiIiMjIyyMjIAAAAAAAAAAAAAAAAAAAAIiIiMjIyyMjIAAAAAAAAAAAA////AAAAAAAA ++AAAAAAAAAAAAAAAA7u7uEhISAAAAAAAAAAAAEhIS7u7uAAAAAAAA////AAAAAAAAAAAAAAAA8/Pz ++DQ0NAAAAAAAAAAAAGRkZ////AAAAAAAAExMT1dXVAAAAAAAAAAAAAAAAGRkZ6urqAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAA ++AAAAAPz8/AICAgAAAAAAAAAAAAMDA/z8/AAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAoKCn5+ftra2v7+/re3tyMjIwAAAAAAAAAAAPz8 ++/P////////////////////j4+AAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAP///wAAAAAA ++AAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAA ++AAAAAP///wAAAAAAAPz8/P////////////////////j4+AAAAAAAAAAAAAAAAAAAAAAAAAAAAOvr ++6xcXFwAAAAAAAAAAAAAAAAAAAAAAACIiIunp6QAAAAAAAP///wMDAwAAAAAAAAAAAAUFBfn5+QAA ++AAAAAPz8/P////////////////////j4+AAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAA ++AAAAAAAAAAAAAAAAABMTE1hYWNXV1V5eXgAAAAAAAAAAAAAAAAAAAAAAAAAAABMTE1hYWNXV1V5e ++XgAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ++/wAAAAAAAAAAAPz8/AICAgAAAAAAAAAAAAMDA/z8/AAAAAAAAPz8/AICAgAAAAAAAAAAAAMDA/z8 ++/AAAAAAAAAAAAP///wAAAAAAAP///+7u7vX19UFBQQAAAAAAAAAAAAAAAP///wAAAAAAAAAAAP// ++/wAAAAAAAAAAAAAAAAAAAAAAAAAAAPv7+wUFBQAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP// ++/wAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAAAP///wMDAwAAAAAAAAAAAAUFBfn5+QAA ++AAAAAAAAAAAAAAAAAAAAAAAAAM3NzRkZGQAAAAAAAM3NzRkZGQAAAAAAAAAAACYmJu/v7wkJCfX1 ++9RYWFvT09AgICOvr6yUlJQAAAAAAACYmJu/v7wkJCfX19RYWFvT09AgICOvr6yUlJQAAAAAAAAAA ++ACYmJu/v7wkJCfX19RYWFvT09AgICOvr6yUlJQAAAAAAAAAAAAAAAAAAAPz8/AICAgAAAAAAAAAA ++AAMDA/z8/AAAAAAAAAAAAP///wMDAwAAAAAAAAAAAAUFBfn5+QAAAAAAAPz8/P////////////// ++//////j4+AAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAoKCn5+ftra2v7+/re3tyMjIwAA ++AAAAAAoKCn5+ftra2v7+/re3tyMjIwAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAPz8/AIC ++AgAAAAAAAAAAAAMDA/z8/AAAAAAAAP///wAAAAAAAAAAAAAAAPv7+wICAgAAAAAAAAAAAAQEBP// ++/wAAAAAAAAAAAM3NzRkZGQAAAAAAAAAAAAYGBvr6+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAADv7+8QEBAAAAAAAAAA ++AAAQEBDw8PAAAAAAAAD///8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAA ++AAD///8AAAAAAACqqqqamppiYmIdHR0AAAAAAAAAAAAAAAAAAADw8PASEhIAAAAAAAAAAAAYGBjh ++4eEAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAD///8KCgoAAAAAAAABAQH///8AAAAAAAAA ++AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8ICAgAAAAAAAAAAAD///8AAAAAAADw8PAS ++EhIAAAAAAAAAAAAYGBjh4eEAAAAAAAAAAAAAAAAAAAAAAAAAAAD7+/sEBAQAAAAAAAAAAAAAAAAA ++AAAAAAAGBgb6+voAAAAAAAD///8TExMAAAAAAAAAAAASEhLo6OgAAAAAAADw8PASEhIAAAAAAAAA ++AAAYGBjh4eEAAAAAAAD///8KCgoAAAAAAAABAQH///8AAAAAAAAAAAAQEBBoaGiqqqrf39/y8vK0 ++tLROTk4AAAAAAAAAAAAAAAAQEBBoaGiqqqrf39/y8vK0tLROTk4AAAAAAAAAAAD///8AAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAADv7+8QEBAA ++AAAAAAAAAAAQEBDw8PAAAAAAAADv7+8QEBAAAAAAAAAAAAAQEBDw8PAAAAAAAAAAAAD///8AAAAA ++AAD///8uLi7T09MwMDAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAA ++AAAAAADt7e0WFhYAAAAAAAAAAAAAAAD///8ICAgAAAAAAAAAAAD///8AAAAAAAD///8AAAAAAAAA ++AAAAAAD///8AAAAAAAAAAAD///8TExMAAAAAAAAAAAASEhLo6OgAAAAAAAAAAAAAAAAAAAAAAAAA ++AACKiopZWVkAAAAAAACKiopZWVkAAAAAAAAAAABlZWWvr68AAADGxsZ2dnbHx8cAAACqqqpkZGQA ++AAAAAABlZWWvr68AAADGxsZ2dnbHx8cAAACqqqpkZGQAAAAAAAAAAABlZWWvr68AAADGxsZ2dnbH ++x8cAAACqqqpkZGQAAAAAAAAAAAAAAAAAAADv7+8QEBAAAAAAAAAAAAAQEBDw8PAAAAAAAAAAAAD/ ++//8TExMAAAAAAAAAAAASEhLo6OgAAAAAAADw8PASEhIAAAAAAAAAAAAYGBjh4eEAAAAAAAD///8K ++CgoAAAAAAAABAQH///8AAAAAAACqqqqamppiYmIdHR0AAAAAAAAAAAAAAACqqqqamppiYmIdHR0A ++AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAADv7+8QEBAAAAAAAAAAAAAQEBDw8PAA ++AAAAAAD///8PDw8AAAAAAAAAAADo6OgQEBAAAAAAAAAAAAAbGxv///8AAAAAAAAAAACKiopZWVkA ++AAAAAAAAAAAZGRnq6uoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAAAAAA//// ++REREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAA8vLyDQ0N ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAAAAAAAAAAAAAA ++AAAA////AAAAAAAAAAAA////PT09AAAAAAAAExMT8PDwAAAAAAAAAAAAAAAAAAAAAAAAAAAA//// ++AAAAAAAAAAAAAAAA////Ozs7AAAAAAAAExMT8vLyAAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6ur ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA7e3tFBQUAAAAAAAAAAAAAAAAAAAAAAAAFRUV7OzsAAAAAAAA ++////U1NTAAAAAAAAAAAASkpKxMTEAAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAA//// ++PT09AAAAAAAAExMT8PDwAAAAAAAARERE6Ojop6enYmJiLS0tAwMDAAAAAAAAAAAAAAAAAAAARERE ++6Ojop6enYmJiLS0tAwMDAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAA ++AAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAAAAAAAAAA////AAAAAAAA////AAAAJiYm1NTUQ0ND ++AAAAAAAAAAAA////AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAA1tbWMjIyAAAAAAAA ++AAAAAAAA////Ozs7AAAAAAAAExMT8vLyAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAAAAAA ++////U1NTAAAAAAAAAAAASkpKxMTEAAAAAAAAAAAAAAAAAAAAAAAAAAAARkZGmpqaAAAAAAAARkZG ++mpqaAAAAAAAAAAAAo6OjbW1tAAAAjo6OxcXFj4+PAAAAZ2dno6OjAAAAAAAAo6OjbW1tAAAAjo6O ++xcXFj4+PAAAAZ2dno6OjAAAAAAAAAAAAo6OjbW1tAAAAjo6OxcXFj4+PAAAAZ2dno6OjAAAAAAAA ++AAAAAAAAAAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAAAAAAAAAA////U1NTAAAAAAAAAAAASkpK ++xMTEAAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAA////PT09AAAAAAAAExMT8PDwAAAA ++AAAA8vLyDQ0NAAAAAAAAAAAAAAAAAAAAAAAA8vLyDQ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAA//// ++AAAAAAAAAAAAAAAAAAAAAAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAAAAAA////REREAAAAAAAA ++AAAAxMTESEhIAAAAAAAAAAAAbGxs////AAAAAAAAAAAARkZGmpqaAAAAAAAAAAAANjY20tLSAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ++/wAAAAAAAAAAAFdXV9fX1zU1NQoKCi4uLtHR0U9PTwAAAAEBAfHx8aurqyEhIQcHBwAAAAAAAAAA ++AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAMnJyWlpaQoKCg0NDW9vb8fHxwAAAAAA ++AAAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAPb2 ++9sDAwC0tLQsLC4KCgr+/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAPr6+r6+ ++vi0tLQ4ODoSEhL6+vgAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAAAAAAAAAAAAAAAAAA ++AAAAALy8vFBQUAAAAAAAAAAAAAAAAAAAAAAAAFRUVLu7uwAAAAAAAP39/c7Ozjo6OgsLCzExMdbW ++1lVVVQAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAAAPb29sDAwC0tLQsLC4KCgr+/vwAA ++AAAAANzc3Dk5OQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANzc3Dk5OQAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAP///wAAAAAAAAAAAFdXV9fX1zU1NQoKCi4uLtHR0U9PTwAAAAAAAFdXV9fX1zU1NQoKCi4u ++LtHR0U9PTwAAAAAAAAAAAP///wAAAAAAAP///wAAAAAAAB4eHtTU1FlZWQAAAAAAAP///wAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAJqamnd3dwAAAAAAAAAAAAAAAPr6+r6+vi0tLQ4O ++DoSEhL6+vgAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAAAP39/c7Ozjo6OgsLCzExMdbW ++1lVVVQAAAAAAAAAAAP///wAAAAAAAAAAAAkJCdPT0wAAAAAAAAkJCdPT0wAAAAAAAAAAAOLi4isr ++KwAAAFVVVfz8/FdXVwAAACQkJOHh4QAAAAAAAOLi4isrKwAAAFVVVfz8/FdXVwAAACQkJOHh4QAA ++AAAAAAAAAOLi4isrKwAAAFVVVfz8/FdXVwAAACQkJOHh4QAAAAAAAAAAAAAAAAAAAFdXV9fX1zU1 ++NQoKCi4uLtHR0U9PTwAAAAAAAAAAAP39/c7Ozjo6OgsLCzExMdbW1lVVVQAAAAAAAE1NTeXl5UZG ++RgsLCz8/P+Li4kJCQgAAAAAAAPb29sDAwC0tLQsLC4KCgr+/vwAAAAAAAMnJyWlpaQoKCg0NDW9v ++b8fHxwAAAAAAAMnJyWlpaQoKCg0NDW9vb8fHxwAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAA ++AFdXV9fX1zU1NQoKCi4uLtHR0U9PTwAAAAEBAfHx8aurqyEhIQcHBwAAAFVVVdfX1zMzMw0NDVhY ++WNjY2P39/QAAAAAAAAAAAAkJCdPT0wAAAAAAAAAAAHp6epWVlQAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDD///////////////8AAAAAAABpaWnc ++3Nz6+vrb29tWVlYAAAAAAAAHBwfo6Og7Ozvb29v5+fkAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAA ++AAAAAAAAAAD///8AAAAAAAAnJye5ubnw8PDy8vK/v78uLi4AAAAAAAAAAAAAAABfX1/R0dH29vba ++2tpfX18AAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAGBgbn5+c+Pj7R0dH29vbLy8suLi4A ++AAAAAAAAAAAAAAAAAAAAAAD4+Pj///////+QkJAAAAAAAAD7+/s9PT3S0tL5+fnR0dErKysAAAAA ++AAAAAABfX1/R0dH29vba2tpfX18AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbW1vLy8sGBgYAAAAA ++AAAAAAAAAAAHBwfOzs5ZWVkAAAAFBQXz8/M8PDzPz8/5+fnk5ORmZmYAAAAAAAAAAAAAAABfX1/R ++0dH29vba2tpfX18AAAAAAAAGBgbn5+c+Pj7R0dH29vbLy8suLi4AAAAAAADs7OwaGhoAAAAAAAAA ++AAAAAAAAAAAqKiqUlJQAAAAAAADs7OwaGhoAAAAAAAAAAAAAAAAAAAAqKiqUlJQAAAAAAAD///8A ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAA ++AABpaWnc3Nz6+vrb29tWVlYAAAAAAAAAAAAAAABpaWnc3Nz6+vrb29tWVlYAAAAAAAAAAAAAAAD/ ++//8AAAAAAAD///8AAAAAAAAAAAAYGBjR0dFzc3MAAAD///8AAAAAAAD4+Pj///////+QkJAAAAAA ++AAAAAAAAAAAAAABOTk7Nzc0AAAAAAAAAAAAAAAD7+/s9PT3S0tL5+fnR0dErKysAAAD4+Pj///// ++//+QkJAAAAD4+Pj///////+QkJAFBQXz8/M8PDzPz8/5+fnk5ORmZmYAAAAAAAAAAAAAAAD///8A ++AAAAAAAAAAAAAAC9vb0cHBwAAAAAAAC9vb0cHBwAAAAhISHo6OgAAAAAAAAcHBz///8fHx8AAAAA ++AADh4eEgICAhISHo6OgAAAAAAAAcHBz///8fHx8AAAAAAADh4eEgICAAAAAhISHo6OgAAAAAAAAc ++HBz///8fHx8AAAAAAADh4eEgICAAAAAAAAAAAAAAAAAAAABpaWnc3Nz6+vrb29tWVlYAAAAAAAAA ++AAAFBQXz8/M8PDzPz8/5+fnk5ORmZmYAAAAAAAAAAAAAAABfX1/R0dH29vba2tpfX18AAAAAAAAG ++Bgbn5+c+Pj7R0dH29vbLy8suLi4AAAAAAAAnJye5ubnw8PDy8vK/v78uLi4AAAAAAAAnJye5ubnw ++8PDy8vK/v78uLi4AAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAABpaWnc3Nz6+vrb29tW ++VlYAAAAAAAAHBwfo6Og7Ozvb29v5+fkAAAAAAABTU1Pb29v39/fDw8MvLy/29vYCAgIAAAAAAAAA ++AAC9vb0cHBwAAAAAAADOzs5KSkoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAwMD////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAA3t7eAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBqampw8PDQEBACwsLCgoKQUFBxcXFpqamAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXFxcxMTEQUFBDw8PBAQEGBgYVlZW39/fb29vAAAA ++AAAAXFxcxMTEQUFBDw8PBAQEGBgYVlZW39/fb29vAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAA////AAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3t7eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEB0tLS ++VVVVAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAA3t7eAAAAAAAAAAAAAAAA3t7eAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenp6XV1d ++AAAAAAAAenp6XV1dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenp6XV1dAAAAWFhY0NDQ ++AQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAPLy8j4+PgcHBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALq6ugAAAAAAAAAAAAAA ++AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAICAmlpacvLy/X19fX19cvLy2hoaAICAgAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAE1NTcfHx+rq6vv7+/Hx8cjIyGZmZgAAAAAAAAAAAAAAAE1NTcfHx+rq6vv7 +++/Hx8cjIyGZmZgAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ++/////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAALq6ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJCQt7e3hYWFgAAAAAAAP///wAA ++AAAAAAAAAAAAAAAAAAAAAAAAALq6ugAAAAAAAAAAAAAAALq6ugAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADY2Np6engAAAAAAADY2Np6engAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADY2Np6enhcXF+Dg4EFBQQAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApKSnU1NT39/cAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAD///8AAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABZWVnAwMAJCQkAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAACAgLOzs4AAAAAAAACAgLOzs4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAACAgLX19fCwsJZWVkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+fn55eXlbW1tAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +++Pj4a2trAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBUdHR/Pz81NTUwAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUlJe7u7gAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAB5eXnLy8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQH///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAA ++AAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAA////AAAAAAAAAAAAMzMzxcXF ++9fX18PDws7OzHx8fAAAAAAAAAAAAAAAAAAAAAAAAAAAA////PDw8zMzM+Pj45OTkYGBgAAAAAAAA ++AAAA////AAAAAAAAAAAAAAAAAAAAaGho3t7e+vr629vbZWVlAAAAAAAAAAAAAAAAU1NTx8fH9/f3 ++zs7OPj4+9vb2AgICAAAALy8vzs7O9/f309PTPj4+6urqAgICAAAAAAAAX19f5ubm9PT0vLy8Jycn ++AAAAAAAAAAAARkZG5eXl6urqAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAA ++AAAAAAAA////AAAAAAAAAAAAX19f5ubm9PT0vLy8JycnAAAAAAAA////AAAAAAAALy8vzs7O9/f3 ++09PTPj4+6urqAgICAAAAAAAAAAAAU1NTx8fH9/f3zs7OPj4+9vb2AgICAAAAAAAAV1dX09PT+vr6 ++7+/vq6urICAgAAAAAAAAMzMzxcXF9fX18PDws7OzHx8fAAAAAAAAAAAAAAAAAAAAAAAAMzMzxcXF ++9fX18PDws7OzHx8fAAAAAAAAAAAAaGho3t7e+vr629vbZWVlAAAAAAAAAAAA////AAAAAAAAAAAA ++AAAARkZG5eXl6urqAAAAAAAAKysr////Ly8vAAAALy8v////KysrAAAAAAAAAAAAMTExxsbG9fX1 ++6+vroaGhFBQUenp69fX1AAAAAAAA////AAAAAAAAAAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAg ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAU1NTx8fH9/f3zs7OPj4+9vb2AgICAAAAAAAAV1dX09PT+vr6 ++7+/vq6urICAgAAAAAAAAAAAAfn5+////REREAAAAAAAAAAAAAAAAAAAAV1dX09PT+vr67+/vq6ur ++ICAgAAAAAAAA////AAAAAAAAAAAAaGho3t7e+vr629vbZWVlAAAAAAAAAAAA////PDw8zMzM+Pj4 ++5OTkYGBgAAAAAAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAgAAAAAAAAAAAAU1NTx8fH9/f3zs7O ++Pj4+9vb2AgICAAAAAAAAAAAAAAAABQUF8/PzPDw8zs7O+Pj44+PjZ2dnAAAAAAAAAAAAAAAAAAAA ++Pz8//v7+ExMTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARkZG5eXl6urqAAAA////AAAAAAAAAAAA ++AAAA////AAAAAAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AgICaGhozMzM9fX19fX1ycnJYmJiAQEBAAAAAAAAAAAAAAAA////PDw8zMzM+Pj45OTkYGBgAAAA ++AAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAgAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAA ++AAAARUVFtLS05eXl+vr68fHxxMTEU1NTAAAAAAAAAAAAAAAARUVFtLS05eXl+vr68fHxxMTEU1NT ++AAAAAAAAAAAA////////////////////////////AAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAaGho3t7e+vr629vbZWVlAAAA ++AAAAAAAAAAAA////AAAAAAAAAAAAV1dX09PT+vr67+/vq6urICAgAAAAAAAAAAAAX19f5ubm9PT0 ++vLy8JycnAAAAAAAARkZG5eXl6urqAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAP// ++/wAAAAAAAAAAAAAAAP///wAAAAAAAP///wAAAAAAAAAAAMLCwmxsbA0NDQgICG9vb76+vgAAAAAA ++AAAAAAAAAAAAAAAAAAAAAP7+/srKyj09PQoKCjExMdfX10xMTAAAAAAAAP///wAAAAAAAAAAAAAA ++AFJSUtvb2zY2NgkJCTMzM9fX11NTUwAAAAAAAFtbW8/PzysrKwsLC0NDQ9PT0/7+/gAAAAAAAMDA ++wICAgAoKCi0tLb29vfj4+AAAAAAAAEdHR9HR0R8fHwkJCWRkZMzMzAAAAAAAAAAAAOTk5DMzMwoK ++CgAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAEdH ++R9HR0R8fHwkJCWRkZMzMzAAAAAAAAP///wAAAAAAAMDAwICAgAoKCi0tLb29vfj4+AAAAAAAAAAA ++AFtbW8/PzysrKwsLC0NDQ9PT0/7+/gAAAAAAAEhISN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAMLC ++wmxsbA0NDQgICG9vb76+vgAAAAAAAAAAAAAAAAAAAAAAAMLCwmxsbA0NDQgICG9vb76+vgAAAAAA ++AFJSUtvb2zY2NgkJCTMzM9fX11NTUwAAAAAAAP///wAAAAAAAAAAAAAAAOTk5DMzMwoKCgAAAAAA ++AGpqav7+/mVlZQAAAGVlZf7+/mlpaQAAAAAAAAAAANDQ0GlpaQkJCR0dHWlpab29veLi4iMjIwAA ++AAAAAP///wAAAAAAAAAAAAAAAEhISN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAAAAAAAAAAAAAAAA ++AFtbW8/PzysrKwsLC0NDQ9PT0/7+/gAAAAAAAEhISN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAAAA ++ANHR0c3NzZ6engAAAAAAAAAAAAAAAEhISN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAP///wAAAAAA ++AFJSUtvb2zY2NgkJCTMzM9fX11NTUwAAAAAAAP7+/srKyj09PQoKCjExMdfX10xMTAAAAAAAAEhI ++SN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAFtbW8/PzysrKwsLC0NDQ9PT0/7+/gAAAAAAAAAAAAAA ++AAAAAAAAAP39/c7Ozj09PQoKCi8vL9PT00NDQwAAAAAAAAAAAAAAAHd3d/Hx8WhoaAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAOTk5DMzMwoKCgAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAAAEhI ++SN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAAAAAAAAAAAAAAAAAAAAAKSkpMzMzERERAsLCwoKCj4+ ++PsPDw5ubmwAAAAAAAAAAAAAAAP7+/srKyj09PQoKCjExMdfX10xMTAAAAAAAAEhISN3d3T8/PwkJ ++CRoaGoWFhbS0tAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAFhYWOvr62ZmZhgYGAMDAxQU ++FE1NTdbW1lVVVQAAAAAAAFhYWOvr62ZmZhgYGAMDAxQUFE1NTdbW1lVVVQAAAAAAAP///wAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAFJSUtvb2zY2NgkJCTMzM9fX11NTUwAAAAAAAAAAAP///wAAAAAA ++AEhISN3d3T8/PwkJCRoaGoWFhbS0tAAAAAAAAEdHR9HR0R8fHwkJCWRkZMzMzAAAAAAAAOTk5DMz ++MwoKCgAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8A ++AAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAICAj09PQAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ ++//9KSkoAAAAAAAAAAABOTk7AwMAAAAAAAAD///8AAAAAAAAAAAAAAAC9vb1OTk4AAAAAAAAAAABM ++TEy+vr4AAAAAAADGxsZGRkYAAAAAAAAAAABcXFz///8AAAAAAADx8fESEhIAAAAAAAA8PDz///8A ++AAAAAAC/v79JSUkAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/ ++//8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAC/v79JSUkAAAAAAAAAAAAAAAAA ++AAAAAAD///8AAAAAAADx8fESEhIAAAAAAAA8PDz///8AAAAAAAAAAADGxsZGRkYAAAAAAAAAAABc ++XFz///8AAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAj09PQA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAj09PQAAAAAAAC9vb1OTk4AAAAAAAAAAABM ++TEy+vr4AAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAACpqanHx8ebm5sAAACbm5vF ++xcWoqKgAAAAAAAAAAAD39/cLCwsAAAAAAAAAAABOTk7///8AAAAAAAAAAAD///8AAAAAAAAAAAAA ++AAC4uLhJSUkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGxsZGRkYAAAAAAAAAAABc ++XFz///8AAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAAAAAAAAAAAAAkJCT6+vpDQ0Pq6uoHBwcAAAAA ++AAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAC9vb1OTk4AAAAAAAAAAABM ++TEy+vr4AAAAAAAD///9KSkoAAAAAAAAAAABOTk7AwMAAAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAA ++AAAAAAAAAADGxsZGRkYAAAAAAAAAAABcXFz///8AAAAAAAAAAAAAAAAAAAAAAAD///9TU1MAAAAA ++AAAAAABERESqqqoAAAAAAAAAAAAAAADW1tZycnLJyckAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ ++//8AAAAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAABUVFTd3d0KCgoAAAAAAAAAAAAAAAAHBwfNzc1PT08AAAAAAAAA ++AAD///9KSkoAAAAAAAAAAABOTk7AwMAAAAAAAAC4uLhJSUkAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ ++//8AAAAAAAAAAAAAAAD///8AAAAAAADLy8tGRkYAAAAAAAAAAAAAAAAAAAAlJSXi4uIAAAAAAADL ++y8tGRkYAAAAAAAAAAAAAAAAAAAAlJSXi4uIAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAA ++AAC9vb1OTk4AAAAAAAAAAABMTEy+vr4AAAAAAAAAAAD///8AAAAAAAC4uLhJSUkAAAAAAAAAAAAA ++AAAAAAAAAAAAAAC/v79JSUkAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAA ++////AAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAA////AAAAAAAAAAAA ++AAAAAAAAAAAAIiIiMjIyyMjIAAAAAAAAAAAAAAAAAAAAAAAAAAAA////EBAQAAAAAAAAAAAAFBQU ++5ubmAAAAAAAA////AAAAAAAAAAAAAAAA7u7uEhISAAAAAAAAAAAAEhIS7u7uAAAAAAAA8vLyDQ0N ++AAAAAAAAAAAAFBQU////AAAAAAAA////AAAAAAAAAAAACgoK////AAAAAAAA5+fnERERAAAAAAAA ++AAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA//// ++AAAAAAAAAAAAAAAA////AAAAAAAA5+fnERERAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAA//// ++AAAAAAAAAAAACgoK////AAAAAAAAAAAA8vLyDQ0NAAAAAAAAAAAAFBQU////AAAAAAAA7e3tDg4O ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIiMjIyyMjIAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAIiIiMjIyyMjIAAAAAAAA7u7uEhISAAAAAAAAAAAAEhIS7u7uAAAAAAAA////AAAA ++AAAAAAAAAAAA////AAAAAAAAAAAAAAAA5+fnaWlp0dHRAAAA0dHRZWVl5ubmAAAAAAAAAAAAr6+v ++hYWFJSUlEBAQBgYGBgYG////AAAAAAAAAAAA////AAAAAAAAAAAAAAAA7e3tDg4OAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8vLyDQ0NAAAAAAAAAAAAFBQU////AAAAAAAA7e3tDg4O ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAd3d3oaGhAAAAnJycUlJSAAAAAAAAAAAA7e3tDg4OAAAAAAAA ++AAAAAAAAAAAAAAAAAAAA////AAAAAAAA7u7uEhISAAAAAAAAAAAAEhIS7u7uAAAAAAAA////EBAQ ++AAAAAAAAAAAAFBQU5ubmAAAAAAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAA8vLyDQ0NAAAA ++AAAAAAAAFBQU////AAAAAAAAAAAAAAAAAAAAAAAA////EBAQAAAAAAAAAAAAEBAQ4uLiAAAAAAAA ++AAAANTU12dnZBQUFurq6KioqAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAA////AAAA ++AAAAAAAAAAAA////AAAAAAAAAAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAt7e3Xl5eAAAAAAAAAAAAAAAAAAAAAAAAVFRUtLS0AAAAAAAAAAAA////EBAQAAAAAAAAAAAA ++FBQU5ubmAAAAAAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA//// ++AAAAAAAAAwMDAAAAAAAAAAAAAAAAAAAAAAAAFhYW5+fnAAAAAAAAAwMDAAAAAAAAAAAAAAAAAAAA ++AAAAFhYW5+fnAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA7u7uEhISAAAAAAAAAAAA ++EhIS7u7uAAAAAAAAAAAA////AAAAAAAA7e3tDg4OAAAAAAAAAAAAAAAAAAAAAAAAAAAA5+fnERER ++AAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAP///wAAAAAAAAAAAAoKCn5+ftra2v7+/re3tyMj ++IwAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wMDAwAAAAAAAAAAAAUFBfn5+QAAAAAAAP///wAAAAAA ++AAAAAAAAAPz8/AICAgAAAAAAAAAAAAMDA/z8/AAAAAAAAPr6+gICAgAAAAAAAAAAAAMDA////wAA ++AAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAPr6+gQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ++/wAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAA ++AAAAAPr6+gQEBAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAP///wAAAAAAAAAAAAAAAP///wAA ++AAAAAAAAAPr6+gICAgAAAAAAAAAAAAMDA////wAAAAAAAPz8/P////////////////////j4+AAA ++AAAAAAoKCn5+ftra2v7+/re3tyMjIwAAAAAAAAAAAAAAAAAAAAAAAAoKCn5+ftra2v7+/re3tyMj ++IwAAAAAAAPz8/AICAgAAAAAAAAAAAAMDA/z8/AAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAA ++AAAAACYmJu/v7wkJCfX19RYWFvT09AgICOvr6yUlJQAAAAAAAAcHB4GBgdDQ0O3t7fr6+v7+/v// ++/wAAAAAAAAAAAP///wAAAAAAAAAAAAAAAPz8/P////////////////////j4+AAAAAAAAAAAAAAA ++AAAAAAAAAPr6+gICAgAAAAAAAAAAAAMDA////wAAAAAAAPz8/P////////////////////j4+AAA ++AAAAAMrKylVVVQAAAFFRUaurqwAAAAAAAAAAAPz8/P////////////////////j4+AAAAAAAAP// ++/wAAAAAAAPz8/AICAgAAAAAAAAAAAAMDA/z8/AAAAAAAAP///wMDAwAAAAAAAAAAAAUFBfn5+QAA ++AAAAAPz8/P////////////////////j4+AAAAAAAAPr6+gICAgAAAAAAAAAAAAMDA////wAAAAAA ++AAAAAAAAAAAAAAAAAP///wICAgAAAAAAAAAAAAICAvr6+gAAAAAAAAAAAJSUlGhoaAAAADo6OouL ++iwAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAA ++AAAAAPz8/P////////////////////j4+AAAAAAAAAAAAAAAAAAAAAAAAOvr6xcXFwAAAAAAAAAA ++AAAAAAAAAAAAACIiIunp6QAAAAAAAAAAAP///wMDAwAAAAAAAAAAAAUFBfn5+QAAAAAAAPz8/P// ++//////////////////j4+AAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAA ++AAAAABMTE1hYWNXV1V5eXgAAAAAAAAAAAAAAAAAAAAAAAAAAABMTE1hYWNXV1V5eXgAAAAAAAP// ++/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAPz8/AICAgAAAAAAAAAAAAMDA/z8/AAAAAAAAAAAAP// ++/wAAAAAAAPz8/P////////////////////j4+AAAAAAAAPr6+gQEBAAAAAAAAAAAAAAAAAAAAAAA ++AP///wAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAD///8ICAgAAAAAAAAA ++AAD///8AAAAAAAD///8AAAAAAAAAAACqqqqamppiYmIdHR0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAD///8TExMAAAAAAAAAAAASEhLo6OgAAAAAAAD///8PDw8AAAAAAAAAAADv7+8QEBAAAAAA ++AAAAAAAQEBDw8PAAAAAAAADj4+MPDw8AAAAAAAAAAAAQEBD///8AAAAAAAD///8AAAAAAAAAAAAA ++AAD///8AAAAAAADr6+sREREAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAA ++AAAAAAD///8AAAAAAAAAAAAAAAD///8KCgoAAAAAAAABAQH///8AAAAAAADr6+sREREAAAAAAAAA ++AAAAAAAAAAAAAAD///8AAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAAAAADj4+MPDw8AAAAA ++AAAAAAAQEBD///8AAAAAAADw8PASEhIAAAAAAAAAAAAYGBjh4eEAAAAAAACqqqqamppiYmIdHR0A ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqqqqamppiYmIdHR0AAAAAAAAAAAAAAADv7+8QEBAAAAAA ++AAAAAAAQEBDw8PAAAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAAAAABlZWWvr68AAADGxsZ2 ++dnbHx8cAAACqqqpkZGQAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgL///8AAAAAAAAAAAD///8PDw8A ++AAAAAAAAAADw8PASEhIAAAAAAAAAAAAYGBjh4eEAAAAAAAAAAAAAAAAAAAAAAADj4+MPDw8AAAAA ++AAAAAAAQEBD///8AAAAAAADw8PASEhIAAAAAAAAAAAAYGBjh4eEAAAAeHh75+fkODg4AAAAMDAzw ++8PANDQ0AAAAAAADw8PASEhIAAAAAAAAAAAAYGBjh4eEAAAAAAAD///8AAAAAAADv7+8QEBAAAAAA ++AAAAAAAQEBDw8PAAAAAAAAD///8TExMAAAAAAAAAAAASEhLo6OgAAAAAAADw8PASEhIAAAAAAAAA ++AAAYGBjh4eEAAAAAAADj4+MPDw8AAAAAAAAAAAAQEBD///8AAAAAAAAAAAAAAAAAAAAAAAD///8T ++ExMAAAAAAAAAAAAODg7v7+8AAAAAAAAGBgbr6+sZGRkAAAADAwPY2NgEBAQAAAAAAAAAAAAAAAAA ++AAAAAAD///8AAAAAAAAAAAD///8ICAgAAAAAAAAAAAD///8AAAAAAAAAAADw8PASEhIAAAAAAAAA ++AAAYGBjh4eEAAAAAAAAAAAAAAAAAAAAAAAD7+/sEBAQAAAAAAAAAAAAAAAAAAAAAAAAGBgb6+voA ++AAAAAAAAAAD///8TExMAAAAAAAAAAAASEhLo6OgAAAAAAADw8PASEhIAAAAAAAAAAAAYGBjh4eEA ++AAAAAAD///8KCgoAAAAAAAABAQH///8AAAAAAAAAAAAQEBBoaGiqqqrf39/y8vK0tLROTk4AAAAA ++AAAAAAAAAAAQEBBoaGiqqqrf39/y8vK0tLROTk4AAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAD////////////////////y8vLDw8NbW1sAAAAAAAAAAAD///8PDw8A ++AAAAAAAAAADv7+8QEBAAAAAAAAAAAAAQEBDw8PAAAAAAAAAAAAD///8AAAAAAADw8PASEhIAAAAA ++AAAAAAAYGBjh4eEAAAAAAADr6+sREREAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAA ++AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAA////Ozs7AAAAAAAAExMT8vLyAAAAAAAA////AAAA ++AAAAAAAA8vLyDQ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////U1NTAAAAAAAA ++AAAASkpKxMTEAAAAAAAA////REREAAAAAAAAAAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAAAAAA ++tbW1REREAAAAAAAAAAAAS0tL////AAAAAAAA////AAAAAAAAAAAAAAAA////AAAAAAAAvr6+QUFB ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAA ++AAAA////PT09AAAAAAAAExMT8PDwAAAAAAAAvr6+QUFBAAAAAAAAAAAAAAAAAAAAAAAA////AAAA ++AAAA////AAAAAAAAAAAAAAAA////AAAAAAAAAAAAtbW1REREAAAAAAAAAAAAS0tL////AAAAAAAA ++vr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAA8vLyDQ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAA8vLyDQ0NAAAAAAAAAAAAAAAAAAAAAAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAAAAAA ++////AAAAAAAAAAAAAAAA////AAAAAAAAAAAAo6OjbW1tAAAAjo6OxcXFj4+PAAAAZ2dno6OjAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAHx8f7OzsAAAAAAAAAAAA////REREAAAAAAAAAAAAvr6+VlZWAAAA ++AAAAAAAAWlpaq6urAAAAAAAAAAAAAAAAAAAAAAAAtbW1REREAAAAAAAAAAAAS0tL////AAAAAAAA ++vr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAcHBwvb29AAAAAAAAAAAAu7u7X19fAAAAAAAAvr6+VlZW ++AAAAAAAAAAAAWlpaq6urAAAAAAAA////AAAAAAAAwMDASUlJAAAAAAAAAAAAR0dHw8PDAAAAAAAA ++////U1NTAAAAAAAAAAAASkpKxMTEAAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAAtbW1 ++REREAAAAAAAAAAAAS0tL////AAAAAAAAAAAAAAAAAAAAAAAA////UlJSAAAAAAAAAAAASUlJvr6+ ++AAAAAAAAUlJSyMjIAAAAAAAAAAAAra2tTU1NAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAA ++////Ozs7AAAAAAAAExMT8vLyAAAAAAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAAAAAA ++AAAAAAAAAAAA7e3tFBQUAAAAAAAAAAAAAAAAAAAAAAAAFRUV7OzsAAAAAAAAAAAA////U1NTAAAA ++AAAAAAAASkpKxMTEAAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAA////PT09AAAAAAAA ++ExMT8PDwAAAAAAAARERE6Ojop6enYmJiLS0tAwMDAAAAAAAAAAAAAAAAAAAARERE6Ojop6enYmJi ++LS0tAwMDAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++////AAAAAAAAAAAAAAAABQUFFxcXeHh4eHh4AAAAAAAA////REREAAAAAAAAAAAAwMDASUlJAAAA ++AAAAAAAAR0dHw8PDAAAAAAAAAAAA////AAAAAAAAvr6+VlZWAAAAAAAAAAAAWlpaq6urAAAAAAAA ++vr6+QUFBAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAA ++AAAAAAAAAAAAAPr6+r6+vi0tLQ4ODoSEhL6+vgAAAAAAAP///wAAAAAAAAAAAMnJyWlpaQoKCg0N ++DW9vb8fHxwAAAAAAAAAAAAAAAAAAAAAAAAAAAP39/c7Ozjo6OgsLCzExMdbW1lVVVQAAAAEBAfHx ++8aurqyEhIQcHBwAAAFdXV9fX1zU1NQoKCi4uLtHR0U9PTwAAAAAAAEVFRdLS0i8vLwwMDENDQ87O ++zv///wAAAAAAAP///wAAAAAAAAAAAAAAAP///wAAAAAAAE9PT8jIyCUlJQkJCWdnZ8bGxgAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAPb29sDAwC0tLQsLC4KC ++gr+/vwAAAAAAAE9PT8jIyCUlJQkJCWdnZ8bGxgAAAAAAAP///wAAAAAAAP///wAAAAAAAAAAAAAA ++AP///wAAAAAAAAAAAEVFRdLS0i8vLwwMDENDQ87Ozv///wAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li ++4kJCQgAAAAAAAMnJyWlpaQoKCg0NDW9vb8fHxwAAAAAAAAAAAAAAAAAAAAAAAMnJyWlpaQoKCg0N ++DW9vb8fHxwAAAAAAAFdXV9fX1zU1NQoKCi4uLtHR0U9PTwAAAAAAAP///wAAAAAAAAAAAAAAAP// ++/wAAAAAAAAAAAOLi4isrKwAAAFVVVfz8/FdXVwAAACQkJOHh4QAAAAAAAMfHx21tbRMTEwUFBSQk ++JJ6enqGhoQAAAAAAAAEBAfHx8aurqyEhIQcHBwAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAA ++AAAAAAAAAAAAAAAAAEVFRdLS0i8vLwwMDENDQ87Ozv///wAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li ++4kJCQgAAAMPDw3FxcQAAAAAAAAAAAHBwcLm5uQAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAA ++AAAAAP///wAAAAAAAFdXV9fX1zU1NQoKCi4uLtHR0U9PTwAAAAAAAP39/c7Ozjo6OgsLCzExMdbW ++1lVVVQAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAAAEVFRdLS0i8vLwwMDENDQ87Ozv// ++/wAAAAAAAAAAAAAAAAAAAAAAAP39/dDQ0ENDQwwMDCwsLMzMzFFRUQAAAAAAALGxsXh4eAAAAAAA ++AAAAAGZmZq6urgAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAPr6+r6+vi0tLQ4ODoSEhL6+ ++vgAAAAAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAAAAAAAAAAAAAAAAAAALy8vFBQUAAA ++AAAAAAAAAAAAAAAAAAAAAFRUVLu7uwAAAAAAAAAAAP39/c7Ozjo6OgsLCzExMdbW1lVVVQAAAAAA ++AE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAAAPb29sDAwC0tLQsLC4KCgr+/vwAAAAAAANzc3Dk5 ++OQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANzc3Dk5OQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAA ++AAAAAAwMDOrq6gAAAAEBAfHx8aurqyEhIQcHBwAAAFdXV9fX1zU1NQoKCi4uLtHR0U9PTwAAAAAA ++AAAAAP///wAAAAAAAE1NTeXl5UZGRgsLCz8/P+Li4kJCQgAAAAAAAE9PT8jIyCUlJQkJCWdnZ8bG ++xgAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAD7+/s9PT3S ++0tL5+fnR0dErKysAAAAAAAD///8AAAAAAAAAAAAnJye5ubnw8PDy8vK/v78uLi4AAAAAAAAAAAAA ++AAAAAAAAAAAFBQXz8/M8PDzPz8/5+fnk5ORmZmYAAAAAAAAHBwfo6Og7Ozvb29v5+fkAAAAAAABp ++aWnc3Nz6+vrb29tWVlYAAAAAAAAAAAAAAABVVVXMzMz39/fLy8s6Ojr///8AAAAAAAD///8AAAAA ++AAAAAAAAAAD///8AAAAAAAAAAABgYGDk5OTz8/O4uLgkJCQAAAAAAAD4+Pj///////+QkJAAAAAA ++AAAAAAAAAAAAAAD///8AAAAAAAAAAAAGBgbn5+c+Pj7R0dH29vbLy8suLi4AAAAAAAAAAABgYGDk ++5OTz8/O4uLgkJCQAAAAAAAD///8AAAAAAAD///8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAABV ++VVXMzMz39/fLy8s6Ojr///8AAAAAAAAAAABfX1/R0dH29vba2tpfX18AAAAAAAAAAAAnJye5ubnw ++8PDy8vK/v78uLi4AAAAAAAAAAAAAAAAAAAAAAAAnJye5ubnw8PDy8vK/v78uLi4AAAAAAAAAAABp ++aWnc3Nz6+vrb29tWVlYAAAAwMDD///////////////8AAAD4+Pj///////+QkJAhISHo6OgAAAAA ++AAAcHBz///8fHx8AAAAAAADh4eEgICAAAAAiIiKoqKjs7Oz7+/vh4eGUlJQODg4AAAAAAAAHBwfo ++6Og7Ozvb29v5+fkAAAAAAABfX1/R0dH29vba2tpfX18AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABV ++VVXMzMz39/fLy8s6Ojr///8AAAAAAAAAAABfX1/R0dH29vba2tpfX18AAAAYGBj9/f0lJSUAAAAA ++AAAAAAAlJSX8/PwWFhYAAAAAAABfX1/R0dH29vba2tpfX18AAAAAAAAAAAD///8AAAAAAAAAAABp ++aWnc3Nz6+vrb29tWVlYAAAAAAAAFBQXz8/M8PDzPz8/5+fnk5ORmZmYAAAAAAAAAAAAAAABfX1/R ++0dH29vba2tpfX18AAAAAAAAAAAAAAABVVVXMzMz39/fLy8s6Ojr///8AAAAAAAAAAAAAAAAAAAAA ++AAD///87OzvLy8v4+Pjh4eFmZmYAAAAAAAAVFRX6+vooKCgAAAAAAAAAAAAfHx/6+voVFRUAAAAA ++AAAAAAAAAAD4+Pj///////+QkJAAAAD7+/s9PT3S0tL5+fnR0dErKysAAAAAAAAAAAAAAABfX1/R ++0dH29vba2tpfX18AAAAAAAAAAAAAAAAAAAAAAAAAAABbW1vLy8sGBgYAAAAAAAAAAAAAAAAHBwfO ++zs5ZWVkAAAAAAAAFBQXz8/M8PDzPz8/5+fnk5ORmZmYAAAAAAAAAAAAAAABfX1/R0dH29vba2tpf ++X18AAAAAAAAGBgbn5+c+Pj7R0dH29vbLy8suLi4AAAAAAADs7OwaGhoAAAAAAAAAAAAAAAAAAAAq ++KiqUlJQAAAAAAADs7OwaGhoAAAAAAAAAAAAAAAAAAAAqKiqUlJQAAAAAAAD///8AAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAMDAzw8PAAAAAHBwfo ++6Og7Ozvb29v5+fkAAAAAAABpaWnc3Nz6+vrb29tWVlYAAAAAAAAAAAAAAAD///8AAAAAAAAAAABf ++X1/R0dH29vba2tpfX18AAAAAAAAAAAAAAABgYGDk5OTz8/O4uLgkJCQAAAD4+Pj///////+QkJAA ++AAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3t7eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//// ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAwMD////AAAAAAAAAAAAAAAA3t7eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//// ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3t7eAAAA ++AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAQEBqampw8PDQEBACwsLCgoKQUFBxcXFpqamAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAXFxcxMTEQUFBDw8PBAQEGBgYVlZW39/fb29vAAAAAAAAXFxcxMTE ++QUFBDw8PBAQEGBgYVlZW39/fb29vAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAA////AAAAAAAAAAAAAAAACQkJICAghoaGjo6OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3t7eAAAAAAAAAP////////////////////// ++/////////////wAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAALq6ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPLy8j4+PgcHBwAA ++AAAAALq6ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALq6ugAAAAAAAAAAAP///wAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAICAmlpacvLy/X19fX19cvLy2hoaAICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAE1NTcfHx+rq6vv7+/Hx8cjIyGZmZgAAAAAAAAAAAAAAAE1NTcfHx+rq6vv7+/Hx8cjIyGZm ++ZgAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////// ++//////b29s/Pz3NzcwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAALq6ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ ++//8AAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApKSnU1NT39/cAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAA ++AAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAA//////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////////////////////////////////wAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////+OcGdtRTltRTlvSD5tRTltRTlz ++TUBtRTlvSD5tRTltRTlzTUD///+pkoqOcGeUdm2Udm2Udm2Udm2Udm2Udm2Udm2Udm2Udm2Udm3/ ++///Qw761oZu1oZu1oZu9q6W1oZu1oZu1oZu1oZu1oZu1oZu1oZv9/f3n4d/az8zaz8zaz8zaz8za ++z8zaz8zaz8zaz8zaz8zaz8zaz8z9/f3z8O7n4d/n4d/r5uTn4d/r5uTr5uTv6+rr5uTr5uTn4d/n ++4d/9/Pz7+vr39fT39fT39fT59/f39fT39fT59/f39fT59/f59/f39fT9/f3///////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAA////////////b0g+PAcAQQ0APAcAPAcAQQ0APAcAPAcAPAcAQQ0APAcATBwN ++////lHZtZTsubUU5bUU5bUU5bUU5b0g+b0g+b0g+bUU5b0g+bUU5////vaulmn92oYd+oYd+mn92 ++oYd+oYd+oYd+mn92oYd+mn92mn92/fz82s/M0MO+0MO+0MO+0MO+xrey0MO+0MO+0MO+xreyxrey ++0MO+/fz87+vq4tvY4tvY4tvY4tvY4tvY4tvYxrey0MO+4tvY4tvY4tvY/Pv7+vn58/Du9fPy9fPy ++9fPy9fPy9fPy9fPy9fPy9fPy9fPy9fPy/f39//////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++2s/M5+Hf//////////////////////////////////////////////////////////////////// ++////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////// ++/////21FOUENAEQSAUQSAUQSAUQSAUQSAUQSAUQSAUENAEQSAUQSAf///5p/dm1FOXNNQHNNQHNN ++QHNNQHNNQHNNQHNNQHNNQHNNQHNNQP///72rpZp/dqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqmS ++ipp/dv38/OLb2NDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvv38/O/r6uLb2Ovm5OLb ++2OLb2Ovm5Ovm5IFfVaGHfu/r6ufh3+Lb2Pz7+/38/P39/ff19Pn39/f19Pf19Pf19PXz8vXz8vf1 ++9Pn39/Pw7v39/f////////////////////////////7+/v////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////////////4trYbWhm/////////////// ++//////////////////////////////////////////////////////////////7+/v////////// ++/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////9zTUA8BwBEEgFEEgFB ++DQBEEgFEEgFBDQBEEgFEEgFEEgFEEgH///+Udm1tRTlzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUBz ++TUBzTUD///+9q6Waf3ahh36hh36hh36hh36hh36hh36hh36pkoqhh36hh379/Pzi29jQw77Qw77Q ++w77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw779/Pzv6+ri29ipkopvSD5tRTmaf3bn4d+La2FdMSN8 ++WU21oZvr5uS1oZuBX1Wpkorv6+qaf3bn4d+9q6W9q6X59/f6+fnaz8yhh3759/f9/f3////n4d+h ++h37r5uSLa2GOcGeUdm3r5uShh36pkoq1oZvaz8zn4d+GZVuOcGfr5uTQw761oZv///+pkori29jG ++t7LGt7Lr5uShh37//v7////39fShh37v6+r///////+9q6XQw769q6XGt7L///+hh37z8O6pkorn ++4d/Qw761oZv18/KUdm3i29ipkorQw77///+hh36GZVuUdm3Gt7Kpkorr5uT///+1oZt8WU21oZv9 ++/Pz///////+9q6V8WU2BX1WUdm3v6+r///+9q6V8WU2pkor////39fSGZVvn4d/////Gt7J8WU2a ++f3b39fSpkoraz8zi29iBX1WUdm339fSOcGdtRTmGZVvaz8zQw761oZv18/Khh3759/epkori29jQ ++w76BX1Waf3b39fS9q6XQw77n4d+hh3739fSOcGe9q6X///////////////8AAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAA////////////bUU5PAcARBIBRBIBRBIBRBIBRBIBRBIBRBIBRBIB ++RBIBRBIB////mn92bUU5c01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01A////vauloYd+oYd+ ++qZKKoYd+oYd+oYd+oYd+oYd+oYd+oYd+mn92/fz84tvYxrey0MO+0MO+0MO+0MO+0MO+0MO+0MO+ ++0MO+0MO+0MO+/fz88/DuvaulTBwNtaGbxreyVScYqZKKjnBnXTEjoYd+XTEjtaGbXTEjvaulZTsu ++xreyZTsu4tvYmn92lHZt/Pv7/v79vaulb0g+////////////2s/MbUU5i2thfFlNqZKKPAcA4tvY ++VScY5+Hfb0g+xreyfFlNlHZthmVbjnBntaGbgV9V////b0g+0MO+oYd+lHZt2s/Mb0g+/v79//// ++7+vqXTEj5+Hf////////jnBnqZKKjnBnqZKK////VScY6+bkb0g+0MO+qZKKi2th0MO+PAcAqZKK ++VScYgV9V2s/MTBwNvaulTBwNqZKKbUU52s/M2s/MVScYxreyZTsu2s/M////////i2thi2th4tvY ++i2thd1JG2s/MVScYxreybUU50MO+2s/MPAcAqZKK9fPyVScYvauld1JGvaulgV9VtaGbc01AoYd+ ++fFlNlHZtmn92ZTsuqZKKbUU5oYd+hmVb6+bkZTsu9/X0ZTsuxreyXTEjtaGbfFlNtaGbhmVbtaGb ++2s/MZTsu2s/MVScY7+vq////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AP///////////29IPjwHAEQSAUENAEENAEQSAUQSAUQSAUQSAUQSAUQSAUQSAf///5p/dm1FOXNN ++QHNNQHNNQHNNQHNNQHNNQHNNQHNNQHNNQHNNQP///8a3spp/dqGHfqGHfqGHfqGHfqGHfqGHfqGH ++fqGHfqGHfpp/dv38/NrPzNDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvv38/PPw7nxZ ++TZp/du/r6u/r6qmSim1FOYZlW6GHfvf19G1FOXdSRl0xI4trYW9IPsa3smU7LuLb2KGHfpR2bfv6 +++v39/ca3sl0xI7Whm7Whm/Xz8trPzG1FOdDDvmU7LnxZTUwcDeLb2F0xI////3dSRrWhm21FOevm ++5Ofh32U7LqmSiotrYf///3dSRtrPzKmSiqGHftrPzG1FOf7+/v////Pw7mU7LtDDvuvm5P///5R2 ++bamSipR2bamSiv///10xI+/r6ndSRtDDvrWhm45wZ6GHfl0xI2U7Ll0xI2U7LtrPzHdSRnxZTVUn ++GLWhm3NNQOLb2KmSilUnGItrYXdSRtrPzP///////45wZ6mSiv////Xz8m9IPqGHfkwcDYZlW3dS ++RtDDvpR2bW1FOXxZTdDDvkwcDYZlW3xZTb2rpYFfVbWhm2U7LvPw7tDDvnNNQItrYbWhm////21F ++OYZlW45wZ+/r6mU7Lvn393dSRqmSil0xI4FfVXxZTbWhm45wZ7Whm9rPzG9IPtDDvm1FOf////// ++/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////9tRTk8BwBE ++EgFEEgFEEgFEEgFEEgFEEgFEEgFEEgFEEgFMHA3///+af3ZtRTlzTUBzTUBzTUBzTUBzTUBzTUBz ++TUBzTUBzTUBzTUD////Gt7Kaf3ahh36hh36hh36pkoqhh36hh36hh36hh36hh36hh379/Pzi29jQ ++w77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw779/Pzz8O5zTUCpkorr5uTn4d+9q6VlOy6G ++ZVtvSD7Qw75dMSOhh35dMSPQw75dMSO1oZtVJxjGt7KGZVuaf3b8+/v9/f29q6VdMSOpkop8WU2B ++X1Xaz8xvSD7Qw76OcGe9q6VMHA3az8xVJxjr5uRvSD61oZtlOy7Gt7Kpkop8WU21oZttRTnn4d9t ++RTm1oZuUdm18WU3Gt7JvSD7////////z8O5dMSNtRTlvSD7Gt7KUdm2pkoqOcGeGZVvr5uRMHA3Q ++w75tRTm1oZuhh36BX1VdMSPGt7JBDQCOcGeGZVupkoqOcGfGt7JtRTmpkoptRTm9q6W1oZtlOy7G ++t7JdMSPGt7L///////+OcGehh37///////93Ukahh35VJxjQw75lOy6pkoptRTnQw75lOy61oZtd ++MSPGt7JvSD6pkoqGZVu1oZtlOy7Qw76hh36BX1WOcGd8WU3i29hlOy6af3ZtRTnaz8xVJxjaz8xl ++Oy69q6VdMSO9q6V8WU2hh36La2GUdm3Gt7JlOy7Gt7JlOy77+vr///////////////8AAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////bUU5QQ0AQQ0ARBIBQQ0ARBIBRBIBQQ0A ++RBIBRBIBRBIBRBIB////mn92bUU5c01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01A////vaul ++oYd+oYd+oYd+oYd+oYd+qZKKoYd+oYd+oYd+oYd+oYd+/fz84tvY0MO+0MO+0MO+0MO+0MO+0MO+ ++0MO+0MO+0MO+0MO+0MO+/fz88/Dumn92c01A6+bk7+vqi2thd1JGqZKKZTsuXTEjlHZt4tvYlHZt ++ZTsuhmVb8/DuhmVbb0g+ZTsu0MO++vn5/f39vaulc01A////5+HfVScYxreybUU56+bkc01AbUU5 ++lHZtvaulQQ0AlHZtVScYfFlNtaGbbUU5ZTsu0MO+2s/MXTEjc01AjnBnb0g+ZTsui2thXTEjqZKK ++////////8/DuZTsu5+Hf////////taGbxreytaGbXTEji2thd1JGc01Ac01AfFlNbUU5vaullHZt ++7+vqjnBn0MO+xreyqZKKmn92bUU5d1JG5+HflHZtVScYtaGbhmVbbUU5jnBn+/r6////////i2th ++qZKK////4tvYVScY6+bklHZtZTsujnBn2s/Mi2th////oYd+xreyoYd+ZTsufFlN7+vqgV9Vvaul ++0MO+ZTsubUU54tvYtaGbbUU5ZTsuqZKK2s/Mc01AZTsugV9Vc01AfFlN9/X0qZKKZTsud1JG8/Du ++taGbb0g+ZTsuqZKKoYd+PAcA0MO+////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAP///////////29IPjwHAEQSAUENAEQSAUQSAUQSAUQSAUQSAUQSAUQSAUQSAf///5p/ ++dm1FOXNNQHNNQHNNQHNNQHNNQHNNQHNNQHNNQHNNQHNNQP///72rpZp/dqGHfqGHfqGHfqmSiqGH ++fqmSiqGHfqGHfqGHfpp/dv38/OLb2NDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvv38 ++/PPw7trPzGU7LndSRoFfVVUnGMa3sufh3+Lb2NrPzOfh3+Lb2Pv6+u/r6vXz8vn39/Xz8u/r6vPw ++7vn39/Xz8v39/b2rpV0xI45wZ3dSRotrYdrPzGU7Lv38/P38/PXz8v///+/r6m9IPv///4FfVWU7 ++Luvm5Pv6+vn39/////////z7+/f19P////r5+fn39/38/Pf19P////////////Pw7l0xI4ZlW5R2 ++baGHfr2rpca3sv////r5+fn39/////f19Pr5+fr5+fn39/////7+/v////////////////7+/v// ++//Xz8vz7+/////////f19Pz7+/39/fXz8v38/P///////////5R2bWU7LpR2bV0xI6GHfv////// ++//Xz8v7+/f7+/v7+/v/////+/v7+/v/+//Xz8vv6+v///3xZTb2rpf////f19Pn39/////////z7 +++/Xz8v/+//////39/ff19P////f19Pr5+f/////+//Xz8vv6+v////////38/Pf19P///9rPzHdS ++Rv///////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////9t ++RTlBDQBBDQBEEgFEEgFEEgFEEgFEEgFBDQBEEgFEEgFMHA3///+af3ZtRTlzTUBzTUBzTUBzTUBz ++TUBzTUBzTUBzTUBzTUBzTUD///+9q6Whh36hh36hh36hh36hh36hh36hh36hh36hh36pkoqhh379 ++/Pzi29jQw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw779/Pzv6+ri29jaz8ypkoqpkorQ ++w77n4d/i29ji29jn4d/i29ji29j8+/v7+vr18/L18/L39fT39fT18/L18/L18/L59/fn4d/Gt7K9 ++q6XQw7739fT39fTaz8z+/v7////////////////v6+r////v6+rGt7Lz8O7///////////////// ++///////////////////////////////////////9/PzQw77Gt7LGt7LQw77az8zi29j///////// ++//////////////////////////////////////////////////////////////////////////// ++///////////////////////////n4d/Qw77Gt7Laz8z9/Pz///////////////////////////// ++///////////////////////i29jr5uT///////////////////////////////////////////// ++///////////////////////////////////////////////////r5uT///////////////////8A ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////b0g+PAcARBIBQQ0ARBIBRBIB ++RBIBRBIBQQ0ARBIBQQ0ATBwN////mn92bUU5c01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01A ++////vaulmn92oYd+qZKKoYd+oYd+oYd+oYd+oYd+oYd+oYd+oYd+/fz84tvY0MO+0MO+0MO+0MO+ ++0MO+0MO+0MO+0MO+0MO+0MO+0MO+/fz87+vq4tvY5+Hf6+bk6+bk5+Hf4tvY4tvY4tvY4tvY4tvY ++4tvY/Pv7+vn59fPy9fPy9fPy9fPy9fPy9fPy9fPy9fPy+ff3/Pv7/fz8/v7+//////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAP///////////3NNQEENAEQSAUwcDUQSAUQSAUQSAUQSAUwcDUQSAUwcDUwc ++Df///5p/dm1FOXdSRndSRndSRndSRndSRndSRndSRndSRnNNQHdSRv///72rpaGHfqmSiqGHfqGH ++fqmSiqmSiqGHfqmSiqGHfqmSiqGHfv38/OLb2NDDvtrPzNDDvtDDvtDDvtDDvtDDvtDDvtDDvtDD ++vtDDvv38/O/r6uLb2Ofh3+Lb2OLb2OLb2Ofh3+Lb2OLb2OLb2OLb2OLb2Pz7+/r5+fXz8vXz8vXz ++8vXz8vXz8vXz8vXz8vXz8vXz8vXz8vXz8v39/f////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////v7//v7//v7//v7//v7//v7//v7//v7//v7//v7//v7//v7///////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////taGblHZtmn92mn92 ++mn92lHZtmn92mn92lHZtmn92mn92mn92////0MO+taGbtaGbvaultaGbvaulvaulvaulvaulvaul ++taGbvaul////5+Hf2s/M2s/M2s/M2s/M2s/M2s/M2s/M4tvY2s/M4tvY2s/M/fz8//////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAP///////////45wZ2U7Lm1FOW1FOW1FOW1FOW1FOW1FOW1FOW1F ++OW1FOXNNQP///7Whm5p/dqGHfqGHfpp/dqGHfqGHfpp/dqGHfpp/dqGHfqGHfv///9rPzNDDvtDD ++vtDDvtDDvtDDvtDDvtDDvsa3stDDvtDDvtDDvvz7+/////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAD///////////+OcGdzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUD///+9q6Waf3ah ++h36hh36hh36hh36hh36pkoqhh36pkoqhh36hh37////i29jQw77Qw77Qw77Qw77Qw77Qw77Qw77Q ++w77Qw77Qw77Qw778+/v////////////////9/Pz39fT39fT39fT7+vr///////////////////// ++///////////6+fn39fT39fT39fT9/f3////////////////////6+fnv6+rz8O7v6+rv6+r59/f/ ++///////////6+fn39fT59/fz8O79/Pz////+/v759/f39fT39fT59/f///////////////////// ++///7+vr39fT39fT39fT+/v7////////////////////////////7+vrv6+rz8O7v6+rz8O739fT/ ++///////////////////////////////////////////////////////////4+v/r8v/r8v/r8v/r ++8v/r8v/1+f/////////////////////////////////////////////////////+/v/y9v/r8v/r ++8v/r8v/y9v/8/f/////////////////////////////8/f/y9v/1+f/1+f/8/f////////////// ++///////////////////////////////1+f/r8v/r8v/r8v/r8v/1+f////////////////////// ++//////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////lHZtbUU5 ++c01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ad1JG////vauloYd+oYd+oYd+oYd+oYd+oYd+oYd+ ++oYd+oYd+oYd+oYd+////4tvY0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+/Pv7//// ++////////////2s/MVScYVScYVScYoYd+////////////////////////////////qZKKTBwNVScY ++XTEj5+Hf////////////+ff3oYd+ZTsuTBwNPAcAPAcAQQ0AXTEji2th0MO+/fz8d1JGVScYVScY ++bUU58/Du////9fPyd1JGTBwNVScYi2th////////////////////////qZKKVScYXTEjVScY6+bk ++////////////////////6+bkoYd+ZTsuTBwNPAcAPAcAPAcAVScYjnBnxrey//////////////// ++/////////////////////////P3/wtj/Toz/LHb/AFX/AFX/AFX/AFX/AFX/E2X/ZJr/q8n/+vz/ ++////////////////////////////////9fn/q8n/Toz/E2X/AFX/AFX/AFX/E2X/PoL/lLr/6/L/ ++////////////////////wtj/E2X/LHb/AFX/0+L///////////////////////////////////// ++q8n/ZJr/LHb/E2X/AFX/AFX/AFX/LHb/Toz/wtj/////////////////////////////AAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////45wZ29IPnNNQHNNQHNNQHNNQHNNQHNN ++QHNNQHNNQHNNQHNNQP///72rpZp/dqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfv///+Lb ++2NDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvvz7+////////////////9DDvjwHAEEN ++ADwHAJp/dv///////////////////////////////5p/djwHADwHAEQSAeLb2P////////Xz8m1F ++OTwHAEENAEENADwHADwHADwHADwHADwHAEwcDWU7LkwcDTwHADwHAKmSiv////////Pw7l0xIzwH ++ADwHAHdSRv///////////////////////6mSijwHAEENADwHAO/r6v///////////////8a3skwc ++DTwHADwHADwHADwHADwHADwHAEENADwHAEENAIZlW/n39////////////////////////////8LY ++/z6C/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV/xNl/wBV/wBV/z6C/9Pi//////////////////// ++/////+vy/z6C/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV/yx2/8LY/////////////////6vJ ++/wBV/wBV/wBV/8LY//////////////////////////////X5/3am/wBV/wBV/wBV/wBV/wBV/wBV ++/wBV/wBV/wBV/wBV/3am/////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAD///////////+Udm1tRTlzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUB3Ukb///+9 ++q6Whh36hh36hh36hh36hh36hh36hh36hh36hh36hh36hh37////i29jGt7LQw77Qw77Qw77Qw77Q ++w77Qw77Qw77Qw77Qw77Gt7L8+/v////////////////az8xBDQBEEgE8BwCaf3b///////////// ++//////////////////+af3ZBDQBBDQBMHA3i29j///////+pkoo8BwBEEgFBDQBVJxiOcGepkoqh ++h36GZVtEEgE8BwBBDQBEEgFEEgFEEgHaz8z////////z8O5lOy48BwA8BwB8WU3///////////// ++//////////+pkoo8BwBEEgE8BwDr5uT////////////Qw75MHA1BDQBBDQA8BwBlOy6OcGeaf3Z3 ++UkZEEgE8BwBEEgE8BwB8WU38+/v///////////////////+ryf8TZf8AVf8TZf8AVf8AVf8TZf8+ ++gv8+gv8+gv8TZf8AVf8AVf8AVf8AVf8TZf/C2P/////////////////y9v8sdv8AVf8AVf8AVf8T ++Zf9OjP92pv9kmv8sdv8AVf8AVf8AVf8TZf/C2P////////////+ryf8AVf8TZf8AVf/C2P////// ++//////////////////////92pv8AVf8AVf8AVf8AVf8+gv92pv9kmv8+gv8AVf8AVf8AVf8AVf92 ++pv////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////// ++lHZtb0g+c01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01A////vaulmn92oYd+oYd+oYd+oYd+ ++oYd+oYd+oYd+oYd+oYd+oYd+////2s/M0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+ ++/Pv7////////////////2s/MPAcARBIBPAcAmn92////////////////////////////////oYd+ ++PAcAQQ0ATBwN4tvY////+/r6b0g+PAcAQQ0ATBwNxrey////////////////4tvYc01APAcARBIB ++QQ0AVScY6+bk////////8/DuZTsuPAcAPAcAd1JG////////////////////////oYd+PAcARBIB ++PAcA7+vq/////////fz8XTEjPAcARBIBQQ0AoYd++ff3/////////v7+2s/MZTsuPAcARBIBPAcA ++taGb////////////////0+L/E2X/AFX/E2X/AFX/E2X/q8n/6/L/9fn/+Pr/+Pr/4uz/q8n/E2X/ ++AFX/E2X/AFX/E2X/4uz/////////////dqb/AFX/E2X/AFX/PoL/4uz/////////////8vb/dqb/ ++AFX/AFX/AFX/PoL//f7/////////lLr/AFX/AFX/AFX/wtj/////////////////////////q8n/ ++AFX/AFX/AFX/E2X/q8n/////////////////q8n/E2X/AFX/AFX/AFX/wtj///////////////// ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////5R2bW9IPnNNQHNNQHNNQHNN ++QHNNQHNNQHNNQHNNQHNNQHdSRv///7Whm6GHfqGHfqGHfqmSiqGHfqGHfqGHfqGHfqGHfqGHfqGH ++fv///9rPzNDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvvz7+////////////////9DD ++vkENAEQSATwHAJp/dv///////////////////////////////5p/dkENAEENAEwcDeLb2P////n3 ++921FOTwHAEENAF0xI/Xz8v///////////////////+/r6kwcDUQSAUENAFUnGO/r6v////////Pw ++7mU7LkENADwHAHxZTf///////////////////////6mSijwHAEQSATwHAO/r6v///////72rpTwH ++AEQSATwHAI5wZ////////////////////////9rPzEwcDUQSAUENAGU7Lv7+/v///////////z6C ++/wBV/wBV/wBV/06M//X5/////////////////////////////+Ls/yx2/wBV/wBV/wBV/06M//// ++//////r8/yx2/wBV/wBV/xNl/+vy/////////////////////////z6C/wBV/wBV/wBV/8LY//// ++/////6vJ/wBV/xNl/wBV/8LY/////////////////////////06M/wBV/wBV/wBV/5S6//////// ++/////////////////5S6/wBV/wBV/wBV/2Sa/////////////////wAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAD///////////+Udm1tRTlzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUBzTUBz ++TUD///+9q6Waf3apkoqhh36hh36hh36hh36hh36hh36pkoqhh36pkor////i29jGt7LQw77Qw77Q ++w77Qw77Qw77Qw77Qw77Qw77Qw77Qw778+/v////////////////az8xBDQBBDQA8BwCaf3b///// ++//////////////////////////+hh348BwBBDQBMHA3i29j///////+BX1U8BwBEEgFBDQCGZVvi ++29jr5uT8+/v///////////+La2E8BwBBDQBVJxjv6+r////////z8O5lOy5BDQA8BwB8WU3///// ++//////////////////+hh348BwBBDQA8BwDr5uT///////+OcGc8BwBEEgFEEgHaz8z///////// ++//////////////////98WU1BDQBBDQBEEgHv6+r////////C2P8AVf8AVf8AVf8TZf/y9v////// ++///////////////////////////////T4v8TZf8AVf8TZf8TZf/T4v/////C2P8AVf8AVf8AVf+U ++uv/////////////////////////////C2P8AVf8TZf8AVf92pv////////+ryf8AVf8AVf8AVf/C ++2P/////////////////////y9v8sdv8AVf8AVf8+gv/////////////////////////////+/v+r ++yf/T4v/r8v/6/P/+/v////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//// ++////////lHZtbUU5c01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ac01Ad1JG////taGboYd+oYd+qZKK ++oYd+oYd+oYd+oYd+qZKKoYd+oYd+oYd+////2s/M0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+ ++0MO+0MO+/Pv7////////////////0MO+QQ0ARBIBPAcAmn92//////////////////////////// ++////mn92QQ0AQQ0ATBwN4tvY////////2s/MTBwNPAcARBIBQQ0APAcAXTEjc01AgV9Vmn92xrey ++hmVbPAcAQQ0ATBwN7+vq////////8/DuZTsuQQ0APAcAfFlN////////////////////////oYd+ ++PAcARBIBPAcA7+vq////////d1JGPAcAPAcAXTEj7+vq////////////////////////////qZKK ++PAcARBIBQQ0A2s/M////////Toz/AFX/AFX/AFX/lLr///////////////////////////////// ++////////////ZJr/AFX/AFX/AFX/lLr/////lLr/AFX/E2X/AFX/q8n///////////////////// ++////////4uz/E2X/AFX/AFX/ZJr/////////q8n/AFX/E2X/AFX/wtj///////////////////// ++0+L/E2X/AFX/AFX/E2X/dqb/ZJr/dqb/ZJr/dqb/ZJr/ZJr/ZJr/dqb/dqb/ZJr/q8n///////// ++////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////5R2bXNNQHNNQHNN ++QHNNQHNNQHNNQHNNQHNNQHNNQHNNQHdSRv///72rpZp/dqmSiqGHfqGHfqGHfqGHfqGHfqGHfqGH ++fqGHfqGHfv///9rPzMa3stDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvvz7+/////////// ++/////9DDvkENAEQSATwHAJp/dv///////////////////////////////6GHfjwHAEENAEwcDeLb ++2P///////////9rPzGU7LjwHADwHADwHADwHADwHADwHADwHAEENAEQSAUQSAUENAFUnGO/r6v// ++//////Pw7mU7LjwHADwHAHxZTf///////////////////////6mSijwHAEQSATwHAOvm5P////38 ++/HNNQDwHAEENAF0xI+/r6v///////////////////////////72rpTwHAEQSAUQSAdrPzP////r8 ++/yx2/wBV/wBV/wBV/+Ls/////////////////////////////////////////////8LY/2Sa/6vJ ++/+Ls//r8/////5S6/wBV/wBV/xNl/8LY/////////////////////////////+vy/xNl/wBV/wBV ++/2Sa/////////6vJ/wBV/wBV/wBV/8LY/////////////////////+Ls/wBV/wBV/wBV/wBV/wBV ++/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV/z6C//7//////////////wAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAD///////////+Udm1tRTlzTUBzTUBzTUBzTUBzTUBzTUBzTUBz ++TUBzTUB3Ukb///+9q6Whh36hh36hh36hh36hh36hh36hh36hh36hh36hh36hh37////i29jQw77Q ++w77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw778+/v////////////////Qw75BDQBEEgE8BwCa ++f3b///////////////////////////////+hh348BwBBDQBMHA3i29j////////////////59/fQ ++w76Udm13UkZdMSNMHA1BDQBBDQBBDQBBDQBEEgFBDQBVJxjv6+r////////z8O5lOy5BDQA8BwB3 ++Ukb///////////////////////+hh35BDQBBDQA8BwDv6+r///////93UkY8BwA8BwBdMSPv6+r/ ++//////////////////////////+pkoo8BwBBDQBBDQDaz8z////i7P8TZf8AVf8AVf8sdv/y9v// ++//////////////////////////////////////////////////////////////////+Uuv8AVf8A ++Vf8AVf+ryf/////////////////////////////i7P8AVf8AVf8AVf9kmv////////+ryf8AVf8A ++Vf8AVf/C2P/////////////////////i7P8TZf8AVf8AVf8AVf8AVf8AVf8AVf8TZf8AVf8AVf8A ++Vf8AVf8AVf8TZf8AVf9kmv////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAA//////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////v7+/f39/f39/f39/f39/f39/f39/f39 ++/f39/f39/f39/f39////////////////////2s/MQQ0AQQ0APAcAmn92//////////////////// ++////////////oYd+PAcAQQ0ATBwN4tvY////////8/Du4tvY2s/M2s/M+ff3/////fz8+vn57+vq ++0MO+taGbZTsuQQ0AQQ0ATBwN7+vq////////8/DuXTEjPAcAQQ0AZTsu+ff3//////////////// ++////qZKKPAcARBIBPAcA6+bk////////jnBnPAcARBIBQQ0A2s/M//////////////////////// ++////fFlNQQ0ARBIBRBIB7+vq////0+L/AFX/E2X/AFX/Toz///////////////////////////// ++////////////////////////////////////////////wtj/AFX/AFX/AFX/dqb///////////// ++////////////////q8n/AFX/AFX/AFX/dqb/////////q8n/AFX/AFX/AFX/lLr///////////// ++////////8vb/LHb/AFX/AFX/LHb/wtj/wtj/0+L/wtj/0+L/0+L/0+L/lLr/AFX/AFX/AFX/dqb/ ++////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////8a3sr2r ++pb2rpb2rpb2rpb2rpb2rpb2rpb2rpb2rpb2rpb2rpf///+fh39rPzOLb2NrPzOLb2OLb2NrPzOLb ++2NrPzNrPzOLb2NrPzP7+/f////////////////////////////////////////////////////// ++/////////////9DDvkENAEQSATwHAJp/dv///////////////////////////////5p/dkENAEEN ++AEwcDeLb2P///////7Whm0wcDUQSATwHAMa3sv///////////////////////5R2bTwHAEQSAVUn ++GOvm5P////////Pw7mU7LkENAEENAEQSAdDDvv///////////////////45wZzwHAEQSATwHAO/r ++6v///////8a3sjwHAEQSATwHAIFfVf///////////////////////9DDvkwcDUQSATwHAHNNQP// ++/////8LY/wBV/wBV/wBV/06M//////////////////////////////////////////////////// ++//////////////////////7//xNl/wBV/wBV/xNl/+Ls//////////////////////j6/z6C/wBV ++/wBV/wBV/9Pi/////////6vJ/wBV/xNl/wBV/yx2//7+/////////////////////2Sa/wBV/xNl ++/wBV/5S6/////////////////////////2Sa/wBV/wBV/wBV/8LY/////////////////wAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////+pkoqaf3aaf3ahh36af3aaf3aaf3ah ++h36hh36af3aaf3ahh37////i29jGt7LQw77Qw77Gt7LQw77Gt7LQw77Qw77Qw77Gt7LQw779/f3/ ++///////////////////////////////////////////////////////////////////Qw75BDQBE ++EgE8BwCaf3b///////////////////////////////+af3ZBDQBBDQBMHA3i29j////////i29hM ++HA08BwBBDQBVJxjaz8z9/f3////////9/PzGt7JMHA1EEgFBDQBdMSP8+/v////////z8O5lOy48 ++BwBEEgFBDQBdMSPGt7L18/L////8+/u9q6VMHA1BDQBBDQBVJxjv6+r////////+/v1lOy5BDQBE ++EgFBDQCOcGfr5uT////////6+fm9q6VMHA1BDQBBDQA8BwDGt7L////////T4v8sdv8AVf8AVf8+ ++gv/1+f////////////////////////////////////////////////////////////////////// ++//+Uuv8AVf8AVf8AVf8sdv/C2P/+/v/////////T4v8+gv8AVf8AVf8AVf9OjP////////////+U ++uv8AVf8AVf8AVf8AVf9OjP/C2P/C2P9kmv+ryf/////T4v8TZf8AVf8AVf8TZf+Uuv/4+v////// ++///i7P92pv8AVf8AVf8AVf8+gv////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAA////////////vaulmn92oYd+oYd+oYd+oYd+oYd+oYd+oYd+qZKKoYd+qZKK//// ++2s/M0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+/f39//////////////////////// ++////////////////////////////////////////////2s/MQQ0ARBIBPAcAmn92//////////// ++////////////////////oYd+PAcAQQ0ATBwN4tvY////////////mn92PAcAQQ0AQQ0ARBIBbUU5 ++c01Ac01AZTsuTBwNQQ0ARBIBPAcAjnBn////////////8/DuZTsuQQ0AQQ0AQQ0APAcATBwNXTEj ++bUU5ZTsuRBIBQQ0AQQ0APAcAjnBn////////////////0MO+TBwNPAcARBIBPAcAVScYbUU5c01A ++ZTsuQQ0ARBIBQQ0APAcAmn92////////////6/L/E2X/AFX/AFX/E2X/4uz///////////////// ++////////////////////////////////////////////////////////+Pr/Toz/AFX/AFX/AFX/ ++AFX/LHb/Toz/PoL/E2X/AFX/AFX/AFX/E2X/4uz/////////////q8n/AFX/AFX/AFX/AFX/AFX/ ++AFX/AFX/AFX/PoL/+vz/////lLr/AFX/AFX/AFX/AFX/LHb/PoL/PoL/LHb/AFX/AFX/AFX/E2X/ ++4uz/////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////// ++/7Whm6GHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfv///9rPzNDDvtDDvtDDvtDDvtDD ++vtDDvtDDvtDDvtDDvtDDvtDDvv39/f////////////////////////////////////////////// ++/////////////////////9DDvkENAEENAEENAJp/dv///////////////////////////////5p/ ++djwHADwHAEQSAeLb2P////////////n395R2bUENADwHAEENADwHADwHADwHADwHAEENAEENADwH ++AG1FOfXz8v////////////Pw7mU7LjwHAEENAF0xI0wcDTwHADwHADwHADwHAEENAEENADwHAG9I ++Pu/r6v///////////////////9DDvmU7LjwHADwHAEENADwHADwHADwHAEENADwHAEQSAaGHfv// ++/////////////////06M/wBV/wBV/wBV/6vJ//////////////////////////////////////// ++/////5S6/3am/6vJ/9Pi//j6//////////////X5/2Sa/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV ++/wBV/z6C/+Ls/////////////////6vJ/wBV/wBV/xNl/xNl/wBV/wBV/wBV/wBV/wBV/8LY//// ++/////6vJ/xNl/wBV/wBV/wBV/wBV/wBV/wBV/wBV/wBV/yx2/8LY//////////////////////// ++/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////+9q6Waf3apkoqhh36hh36h ++h36hh36hh36hh36hh36hh36hh37////i29jQw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Q ++w779/f3////////////////////////////////////////////////////////////////////a ++z8w8BwBEEgE8BwCaf3b///////////////////////////////+1oZtzTUBzTUB8WU3r5uT///// ++///////////////az8yUdm1lOy5MHA1VJxhMHA1MHA1VJxhtRTm1oZvz8O7////////////////3 ++9fSLa2FzTUBzTUC1oZvaz8yBX1VVJxhMHA1MHA1VJxhtRTm1oZv18/L///////////////////// ++///////39fS1oZt3UkZMHA1MHA1MHA1MHA1dMSOUdm3i29j///////////////////////+ryf8A ++Vf8TZf8AVf8sdv/9/v/////////////////////////////////////i7P8TZf8AVf8AVf8sdv/i ++7P/////////////////9/v/C2P9kmv8sdv8TZf8TZf8TZf8TZf8+gv/C2P/4+v////////////// ++//////+ryf9OjP8+gv9kmv/T4v8+gv8AVf8TZf8TZf9kmv/i7P/////////////i7P+Uuv8sdv8T ++Zf8TZf8TZf8TZf8+gv+ryf/y9v////////////////////////////8AAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAA////////////taGboYd+oYd+oYd+oYd+oYd+oYd+oYd+oYd+oYd+oYd+ ++qZKK////2s/M0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+/f39//////////////// ++////////////////////////////////////////////////////2s/MQQ0AQQ0APAcAmn92//// ++//////////////////////////////////////////////////////////////////////////// ++////8/Du5+Hf6+bk6+bk+ff3//////////////////////////////////////////////////// ++/////f396+bk5+Hf8/Du/////////////////////////////////////////////////////f39 ++6+bk6+bk8/Du////////////////////////////////////+vz/LHb/AFX/E2X/AFX/ZJr///// ++////////////////////////////+Pr/Toz/AFX/AFX/AFX/PoL///////////////////////// ++/////////v7/4uz/4uz/4uz/+vz///////////////////////////////////////////////// ++////////6/L/4uz/+vz/////////////////////////////////6/L/4uz/4uz/8vb///////// ++////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// ++/////////72rpZp/dqGHfqGHfqGHfqmSiqGHfqGHfqGHfqGHfqGHfqGHfv///+Lb2NDDvtDDvtDD ++vtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvv39/f////////////////////////////////////// ++//Xz8u/r6vPw7u/r6vPw7u/r6vXz8sa3skENAEQSATwHAJR2bfXz8u/r6u/r6u/r6vPw7u/r6u/r ++6v///9DDvqGHfqGHfqmSiu/r6v////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////8LY/xNl/wBV/wBV/wBV/z6C/9Pi//L2//3+//////////j6 ++/9Pi/06M/wBV/wBV/wBV/wBV/9Pi//////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////+1oZuhh36hh36h ++h36hh36hh36hh36hh36hh36hh36hh36pkor////az8zQw77Qw77Qw77Qw77Qw77Qw77Qw77Qw77Q ++w77Qw77Qw779/f3///////////////////////////////////////+hh35MHA1MHA1VJxhVJxhM ++HA1VJxhMHA1EEgFEEgFEEgFMHA1VJxhVJxhVJxhVJxhVJxhVJxhVJxj///+af3Y8BwA8BwBBDQDi ++29j///////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////+ryf8TZf8AVf8TZf8AVf8AVf8sdv9OjP9kmv9kmv8+gv8AVf8AVf8AVf8AVf8AVf+r ++yf////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////8AAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////vaulmn92oYd+qZKKoYd+oYd+oYd+oYd+oYd+ ++oYd+oYd+qZKK////2s/M0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+/f39//////// ++////////////////////////////////lHZtPAcAQQ0APAcAPAcAPAcAPAcAPAcAQQ0AQQ0AQQ0A ++PAcAPAcAPAcAPAcAPAcAPAcAPAcAPAcA////mn92PAcAPAcATBwN4tvY//////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////////////////////////////////wtj/PoL/ ++AFX/AFX/AFX/AFX/AFX/AFX/AFX/AFX/AFX/AFX/AFX/E2X/q8n///////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAP///////////7Whm6GHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfqGHfv///+Lb2NDD ++vtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvtDDvv39/f////////////////////////////// ++/////////6GHflUnGFUnGF0xI10xI1UnGF0xI1UnGFUnGFUnGFUnGF0xI1UnGF0xI1UnGFUnGF0x ++I1UnGFUnGP///6mSilUnGF0xI10xI+fh3/////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////z9/8LY/2Sa/yx2/wBV/wBV/wBV ++/wBV/wBV/wBV/yx2/3am/+vy//////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////+1oZua ++f3ahh36hh36pkoqhh36hh36hh36hh36hh36hh36hh37////az8zGt7LQw77Qw77Qw77Qw77Qw77Q ++w77Qw77Qw77Qw77Qw779/f3////////////////////////////////////////6+fn39fT39fT3 ++9fT39fT39fT39fT39fT39fT39fT39fT39fT39fT39fT39fT39fT39fT39fT39fT////7+vr39fT3 ++9fT39fT9/f3///////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++///////////////////////////////////////1+f/i7P/C2P+ryf/C2P/C2P/i7P/6/P////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////8AAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////taGboYd+oYd+oYd+oYd+oYd+oYd+ ++oYd+oYd+oYd+oYd+oYd+////2s/M0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+0MO+/f39 ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAP////////////39/f38/P38/P38/P38/P38/P38/P38/P38/P38/P38/P38/P// ++//39/f38/P38/P38/P38/P38/P38/P38/P38/P38/P38/P38/P////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////// ++///z8O7r5uTr5uTr5uTr5uTv6+rr5uTv6+rr5uTv6+rr5uTr5uT///////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////5+Hf4tvY4tvY4tvY4tvY ++4tvY4tvY4tvY4tvY4tvY4tvY4tvY//////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAP///////////+fh3+Lb2OLb2OLb2OLb2Ofh3+Lb2OLb2OLb2OLb2OLb ++2OLb2P////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ ++///////////r5uTi29ji29ji29ji29ji29ji29jn4d/i29ji29ji29jn4d////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////5+Hf4tvY4tvY ++4tvY4tvY4tvY5+Hf4tvY5+Hf4tvY4tvY4tvY//////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////////////////////////////AAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////+vm5OLb2OLb2OLb2OLb2OLb2OLb2Ofh3+Lb ++2Ofh3+Lb2OLb2P////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAD////////////n4d/i29ji29ji29ji29ji29ji29ji29ji29ji29ji29ji29j///////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////6+bk ++4tvY4tvY4tvY4tvY4tvY4tvY4tvY4tvY5+Hf4tvY4tvY//////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////////////////////////////////////////////////////////////////AAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////+fh3+Lb2OLb2OLb2OLb2Ofh3+Lb ++2Ofh3+Lb2OLb2OLb2OLb2P////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAD////////////r5uTi29ji29jn4d/i29ji29jn4d/i29ji29ji29ji29ji29j/ ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// ++////5+Hf4tvY4tvY4tvY5+Hf4tvY4tvY4tvY4tvY4tvY4tvY5+Hf//////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////+vm5OLb2OLb2OLb2OLb ++2OLb2OLb2OLb2OLb2OLb2OLb2OLb2P////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////////////////wAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAD////////////9/f39/Pz9/Pz9/Pz9/Pz9/Pz9/Pz9/Pz9/Pz9/Pz9 ++/Pz9/Pz///////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++/////////////////////////////////////////////////////////////////wAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +diff --git a/MdeModulePkg/Logo/Logo-OpenSSL.idf b/MdeModulePkg/Logo/Logo-OpenSSL.idf +new file mode 100644 +index 0000000000..e527cff79b +--- /dev/null ++++ b/MdeModulePkg/Logo/Logo-OpenSSL.idf +@@ -0,0 +1,15 @@ ++// /** @file ++// Platform Logo image definition file. ++// ++// Copyright (c) 2016, 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. ++// ++// **/ ++ ++#image IMG_LOGO Logo-OpenSSL.bmp +diff --git a/MdeModulePkg/Logo/LogoOpenSSLDxe.inf b/MdeModulePkg/Logo/LogoOpenSSLDxe.inf +new file mode 100644 +index 0000000000..2f79d873e2 +--- /dev/null ++++ b/MdeModulePkg/Logo/LogoOpenSSLDxe.inf +@@ -0,0 +1,61 @@ ++## @file ++# The default logo bitmap picture shown on setup screen. ++# ++# Copyright (c) 2016 - 2017, 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. ++# ++# ++## ++ ++[Defines] ++ INF_VERSION = 0x00010005 ++ BASE_NAME = LogoOpenSSLDxe ++ MODULE_UNI_FILE = LogoOpenSSLDxe.uni ++ FILE_GUID = 9CAE7B89-D48D-4D68-BBC4-4C0F1D48CDFF ++ MODULE_TYPE = DXE_DRIVER ++ VERSION_STRING = 1.0 ++ ++ ENTRY_POINT = InitializeLogo ++# ++# This flag specifies whether HII resource section is generated into PE image. ++# ++ UEFI_HII_RESOURCE_SECTION = TRUE ++ ++# ++# The following information is for reference only and not required by the build tools. ++# ++# VALID_ARCHITECTURES = IA32 X64 ++# ++ ++[Sources] ++ Logo-OpenSSL.bmp ++ Logo.c ++ Logo-OpenSSL.idf ++ ++[Packages] ++ MdeModulePkg/MdeModulePkg.dec ++ MdePkg/MdePkg.dec ++ ++[LibraryClasses] ++ UefiBootServicesTableLib ++ UefiDriverEntryPoint ++ DebugLib ++ ++[Protocols] ++ gEfiHiiDatabaseProtocolGuid ## CONSUMES ++ gEfiHiiImageExProtocolGuid ## CONSUMES ++ gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES ++ gEdkiiPlatformLogoProtocolGuid ## PRODUCES ++ ++[Depex] ++ gEfiHiiDatabaseProtocolGuid AND ++ gEfiHiiImageExProtocolGuid ++ ++[UserExtensions.TianoCore."ExtraFiles"] ++ LogoDxeExtra.uni +diff --git a/MdeModulePkg/Logo/LogoOpenSSLDxe.uni b/MdeModulePkg/Logo/LogoOpenSSLDxe.uni +new file mode 100644 +index 0000000000..7227ac3910 +--- /dev/null ++++ b/MdeModulePkg/Logo/LogoOpenSSLDxe.uni +@@ -0,0 +1,22 @@ ++// /** @file ++// The logo bitmap picture (with OpenSSL advertisment) shown on setup screen. ++// ++// This module provides the logo bitmap picture (with OpenSSL advertisment) ++// shown on setup screen, through EDKII Platform Logo protocol. ++// ++// Copyright (c) 2016, 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. ++// ++// **/ ++ ++ ++#string STR_MODULE_ABSTRACT #language en-US "Provides the logo bitmap picture (with OpenSSL advertisment) shown on setup screen." ++ ++#string STR_MODULE_DESCRIPTION #language en-US "This module provides the logo bitmap picture (with OpenSSL advertisment) shown on setup screen, through EDKII Platform Logo protocol." ++ +diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc +index cd0e71869b..0a49336c0d 100644 +--- a/OvmfPkg/OvmfPkgIa32.dsc ++++ b/OvmfPkg/OvmfPkgIa32.dsc +@@ -694,7 +694,11 @@ + NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf + !endif + } ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf +index 52b8b1fea1..4177379a23 100644 +--- a/OvmfPkg/OvmfPkgIa32.fdf ++++ b/OvmfPkg/OvmfPkgIa32.fdf +@@ -295,7 +295,11 @@ INF ShellPkg/Application/Shell/Shell.inf + INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf + !endif + ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Network modules +diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc +index 7f7a78f60a..a3d51ef0f7 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -703,7 +703,11 @@ + NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf + !endif + } ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf +index 70845d6972..5e57161154 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.fdf ++++ b/OvmfPkg/OvmfPkgIa32X64.fdf +@@ -296,7 +296,11 @@ INF ShellPkg/Application/Shell/Shell.inf + INF RuleOverride = BINARY USE = X64 EdkShellBinPkg/FullShell/FullShell.inf + !endif + ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Network modules +diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc +index 739807efc4..f9b4ab4dfa 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -701,7 +701,11 @@ + NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf + !endif + } ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 1eb46ac9a2..c81b422517 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -296,7 +296,11 @@ INF ShellPkg/Application/Shell/Shell.inf + INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf + !endif + ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Network modules diff --git a/0006-EXCLUDE_SHELL_FROM_FD.patch b/0006-EXCLUDE_SHELL_FROM_FD.patch deleted file mode 100644 index 3a67839..0000000 --- a/0006-EXCLUDE_SHELL_FROM_FD.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Gerd Hoffmann kraxel@redhat.com -Date: Thu, 18 Feb 2016 10:52:44 +0100 -Subject: [PATCH] EXCLUDE_SHELL_FROM_FD - ---- - OvmfPkg/OvmfPkgIa32.fdf | 2 ++ - OvmfPkg/OvmfPkgIa32X64.fdf | 2 ++ - OvmfPkg/OvmfPkgX64.fdf | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf -index 2a5b211..ebdab17 100644 ---- a/OvmfPkg/OvmfPkgIa32.fdf -+++ b/OvmfPkg/OvmfPkgIa32.fdf -@@ -281,11 +281,13 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf - - INF FatPkg/EnhancedFatDxe/Fat.inf - -+!ifndef $(EXCLUDE_SHELL_FROM_FD) - !ifndef $(USE_OLD_SHELL) - INF ShellPkg/Application/Shell/Shell.inf - !else - INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf - !endif -+!endif - - INF MdeModulePkg/Logo/LogoDxe.inf - -diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf -index 1c7df21..adf53f3 100644 ---- a/OvmfPkg/OvmfPkgIa32X64.fdf -+++ b/OvmfPkg/OvmfPkgIa32X64.fdf -@@ -281,11 +281,13 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf - - INF FatPkg/EnhancedFatDxe/Fat.inf - -+!ifndef $(EXCLUDE_SHELL_FROM_FD) - !ifndef $(USE_OLD_SHELL) - INF ShellPkg/Application/Shell/Shell.inf - !else - INF RuleOverride = BINARY USE = X64 EdkShellBinPkg/FullShell/FullShell.inf - !endif -+!endif - - INF MdeModulePkg/Logo/LogoDxe.inf - -diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf -index 3bb11cb..edf1098 100644 ---- a/OvmfPkg/OvmfPkgX64.fdf -+++ b/OvmfPkg/OvmfPkgX64.fdf -@@ -281,11 +281,13 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf - - INF FatPkg/EnhancedFatDxe/Fat.inf - -+!ifndef $(EXCLUDE_SHELL_FROM_FD) - !ifndef $(USE_OLD_SHELL) - INF ShellPkg/Application/Shell/Shell.inf - !else - INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf - !endif -+!endif - - INF MdeModulePkg/Logo/LogoDxe.inf - diff --git a/0006-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch b/0006-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch new file mode 100644 index 0000000..33b54aa --- /dev/null +++ b/0006-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch @@ -0,0 +1,540 @@ +From e4021f592da913f7f2b841ce6d4272fb8410ac7f Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Thu, 12 Jun 2014 00:17:59 +0200 +Subject: [PATCH] OvmfPkg: QemuVideoDxe: enable debug messages in VbeShim + +The Int10h VBE Shim is capable of emitting short debug messages when the +win2k8r2 UEFI guest uses (emulates) the Video BIOS. In upstream the quiet +version is preferred; for us debug messages are important as a default. + +For this patch, the DEBUG macro is enabled in the assembly file, and then +the header file is regenerated from the assembly, by running +"OvmfPkg/QemuVideoDxe/VbeShim.sh". + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit ccda46526bb2e573d9b54f0db75d27e442b4566f) +(cherry picked from commit ed45b26dbeadd63dd8f2edf627290957d8bbb3b2) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + OvmfPkg/QemuVideoDxe/VbeShim.asm | 2 +- + OvmfPkg/QemuVideoDxe/VbeShim.h | 481 ++++++++++++++++++++----------- + 2 files changed, 308 insertions(+), 175 deletions(-) + +diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.asm b/OvmfPkg/QemuVideoDxe/VbeShim.asm +index 18fa9209d4..f87ed5cf30 100644 +--- a/OvmfPkg/QemuVideoDxe/VbeShim.asm ++++ b/OvmfPkg/QemuVideoDxe/VbeShim.asm +@@ -18,7 +18,7 @@ + ;------------------------------------------------------------------------------ + + ; enable this macro for debug messages +-;%define DEBUG ++%define DEBUG + + %macro DebugLog 1 + %ifdef DEBUG +diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.h b/OvmfPkg/QemuVideoDxe/VbeShim.h +index cc9b6e14cd..325d6478a1 100644 +--- a/OvmfPkg/QemuVideoDxe/VbeShim.h ++++ b/OvmfPkg/QemuVideoDxe/VbeShim.h +@@ -517,185 +517,318 @@ STATIC CONST UINT8 mVbeShim[] = { + /* 000001FE nop */ 0x90, + /* 000001FF nop */ 0x90, + /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F, +- /* 00000203 jz 0x22d */ 0x74, 0x28, ++ /* 00000203 jz 0x235 */ 0x74, 0x30, + /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F, +- /* 00000208 jz 0x245 */ 0x74, 0x3B, ++ /* 00000208 jz 0x255 */ 0x74, 0x4B, + /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F, +- /* 0000020D jz 0x269 */ 0x74, 0x5A, ++ /* 0000020D jz 0x289 */ 0x74, 0x7A, + /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F, +- /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01, ++ /* 00000212 jz word 0x361 */ 0x0F, 0x84, 0x4B, 0x01, + /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F, +- /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01, ++ /* 00000219 jz word 0x36e */ 0x0F, 0x84, 0x51, 0x01, + /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F, +- /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01, ++ /* 00000220 jz word 0x378 */ 0x0F, 0x84, 0x54, 0x01, + /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00, +- /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01, +- /* 0000022B jmp short 0x22b */ 0xEB, 0xFE, +- /* 0000022D push es */ 0x06, +- /* 0000022E push di */ 0x57, +- /* 0000022F push ds */ 0x1E, +- /* 00000230 push si */ 0x56, +- /* 00000231 push cx */ 0x51, +- /* 00000232 push cs */ 0x0E, +- /* 00000233 pop ds */ 0x1F, +- /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00, +- /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01, +- /* 0000023A cld */ 0xFC, +- /* 0000023B rep movsb */ 0xF3, 0xA4, +- /* 0000023D pop cx */ 0x59, +- /* 0000023E pop si */ 0x5E, +- /* 0000023F pop ds */ 0x1F, +- /* 00000240 pop di */ 0x5F, +- /* 00000241 pop es */ 0x07, +- /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01, +- /* 00000245 push es */ 0x06, +- /* 00000246 push di */ 0x57, +- /* 00000247 push ds */ 0x1E, +- /* 00000248 push si */ 0x56, +- /* 00000249 push cx */ 0x51, +- /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, +- /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, +- /* 00000252 jz 0x256 */ 0x74, 0x02, +- /* 00000254 jmp short 0x22b */ 0xEB, 0xD5, +- /* 00000256 push cs */ 0x0E, +- /* 00000257 pop ds */ 0x1F, +- /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01, +- /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01, +- /* 0000025E cld */ 0xFC, +- /* 0000025F rep movsb */ 0xF3, 0xA4, +- /* 00000261 pop cx */ 0x59, +- /* 00000262 pop si */ 0x5E, +- /* 00000263 pop ds */ 0x1F, +- /* 00000264 pop di */ 0x5F, +- /* 00000265 pop es */ 0x07, +- /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00, +- /* 00000269 push dx */ 0x52, +- /* 0000026A push ax */ 0x50, +- /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, +- /* 0000026F jz 0x273 */ 0x74, 0x02, +- /* 00000271 jmp short 0x22b */ 0xEB, 0xB8, +- /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, +- /* 00000276 mov al,0x20 */ 0xB0, 0x20, +- /* 00000278 out dx,al */ 0xEE, +- /* 00000279 push dx */ 0x52, +- /* 0000027A push ax */ 0x50, +- /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00, +- /* 00000281 out dx,ax */ 0xEF, +- /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 00000288 out dx,ax */ 0xEF, +- /* 00000289 pop ax */ 0x58, +- /* 0000028A pop dx */ 0x5A, +- /* 0000028B push dx */ 0x52, +- /* 0000028C push ax */ 0x50, +- /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00, +- /* 00000293 out dx,ax */ 0xEF, +- /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 0000029A out dx,ax */ 0xEF, +- /* 0000029B pop ax */ 0x58, +- /* 0000029C pop dx */ 0x5A, +- /* 0000029D push dx */ 0x52, +- /* 0000029E push ax */ 0x50, +- /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00, +- /* 000002A5 out dx,ax */ 0xEF, +- /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 000002AC out dx,ax */ 0xEF, +- /* 000002AD pop ax */ 0x58, +- /* 000002AE pop dx */ 0x5A, +- /* 000002AF push dx */ 0x52, +- /* 000002B0 push ax */ 0x50, +- /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00, +- /* 000002B7 out dx,ax */ 0xEF, +- /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 000002BE out dx,ax */ 0xEF, +- /* 000002BF pop ax */ 0x58, +- /* 000002C0 pop dx */ 0x5A, +- /* 000002C1 push dx */ 0x52, +- /* 000002C2 push ax */ 0x50, +- /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00, +- /* 000002C9 out dx,ax */ 0xEF, +- /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00, +- /* 000002D0 out dx,ax */ 0xEF, +- /* 000002D1 pop ax */ 0x58, +- /* 000002D2 pop dx */ 0x5A, +- /* 000002D3 push dx */ 0x52, +- /* 000002D4 push ax */ 0x50, +- /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00, +- /* 000002DB out dx,ax */ 0xEF, +- /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04, +- /* 000002E2 out dx,ax */ 0xEF, +- /* 000002E3 pop ax */ 0x58, +- /* 000002E4 pop dx */ 0x5A, +- /* 000002E5 push dx */ 0x52, +- /* 000002E6 push ax */ 0x50, +- /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00, +- /* 000002ED out dx,ax */ 0xEF, +- /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04, +- /* 000002F4 out dx,ax */ 0xEF, +- /* 000002F5 pop ax */ 0x58, +- /* 000002F6 pop dx */ 0x5A, +- /* 000002F7 push dx */ 0x52, +- /* 000002F8 push ax */ 0x50, +- /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00, +- /* 000002FF out dx,ax */ 0xEF, +- /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03, +- /* 00000306 out dx,ax */ 0xEF, +- /* 00000307 pop ax */ 0x58, +- /* 00000308 pop dx */ 0x5A, +- /* 00000309 push dx */ 0x52, +- /* 0000030A push ax */ 0x50, +- /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00, +- /* 00000311 out dx,ax */ 0xEF, +- /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03, +- /* 00000318 out dx,ax */ 0xEF, +- /* 00000319 pop ax */ 0x58, +- /* 0000031A pop dx */ 0x5A, +- /* 0000031B push dx */ 0x52, +- /* 0000031C push ax */ 0x50, +- /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00, +- /* 00000323 out dx,ax */ 0xEF, +- /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00, +- /* 0000032A out dx,ax */ 0xEF, +- /* 0000032B pop ax */ 0x58, +- /* 0000032C pop dx */ 0x5A, +- /* 0000032D pop ax */ 0x58, +- /* 0000032E pop dx */ 0x5A, +- /* 0000032F jmp short 0x34c */ 0xEB, 0x1B, +- /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, +- /* 00000334 jmp short 0x34c */ 0xEB, 0x16, +- /* 00000336 jmp short 0x350 */ 0xEB, 0x18, +- /* 00000338 jmp short 0x350 */ 0xEB, 0x16, +- /* 0000033A cmp al,0x3 */ 0x3C, 0x03, +- /* 0000033C jz 0x345 */ 0x74, 0x07, +- /* 0000033E cmp al,0x12 */ 0x3C, 0x12, +- /* 00000340 jz 0x349 */ 0x74, 0x07, +- /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE, +- /* 00000345 mov al,0x30 */ 0xB0, 0x30, +- /* 00000347 jmp short 0x34b */ 0xEB, 0x02, +- /* 00000349 mov al,0x20 */ 0xB0, 0x20, +- /* 0000034B iretw */ 0xCF, +- /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00, +- /* 0000034F iretw */ 0xCF, +- /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01, +- /* 00000353 iretw */ 0xCF, ++ /* 00000227 jz word 0x382 */ 0x0F, 0x84, 0x57, 0x01, ++ /* 0000022B push si */ 0x56, ++ /* 0000022C mov si,0x3e9 */ 0xBE, 0xE9, 0x03, ++ /* 0000022F call word 0x3c4 */ 0xE8, 0x92, 0x01, ++ /* 00000232 pop si */ 0x5E, ++ /* 00000233 jmp short 0x233 */ 0xEB, 0xFE, ++ /* 00000235 push es */ 0x06, ++ /* 00000236 push di */ 0x57, ++ /* 00000237 push ds */ 0x1E, ++ /* 00000238 push si */ 0x56, ++ /* 00000239 push cx */ 0x51, ++ /* 0000023A push si */ 0x56, ++ /* 0000023B mov si,0x3fb */ 0xBE, 0xFB, 0x03, ++ /* 0000023E call word 0x3c4 */ 0xE8, 0x83, 0x01, ++ /* 00000241 pop si */ 0x5E, ++ /* 00000242 push cs */ 0x0E, ++ /* 00000243 pop ds */ 0x1F, ++ /* 00000244 mov si,0x0 */ 0xBE, 0x00, 0x00, ++ /* 00000247 mov cx,0x100 */ 0xB9, 0x00, 0x01, ++ /* 0000024A cld */ 0xFC, ++ /* 0000024B rep movsb */ 0xF3, 0xA4, ++ /* 0000024D pop cx */ 0x59, ++ /* 0000024E pop si */ 0x5E, ++ /* 0000024F pop ds */ 0x1F, ++ /* 00000250 pop di */ 0x5F, ++ /* 00000251 pop es */ 0x07, ++ /* 00000252 jmp word 0x3ac */ 0xE9, 0x57, 0x01, ++ /* 00000255 push es */ 0x06, ++ /* 00000256 push di */ 0x57, ++ /* 00000257 push ds */ 0x1E, ++ /* 00000258 push si */ 0x56, ++ /* 00000259 push cx */ 0x51, ++ /* 0000025A push si */ 0x56, ++ /* 0000025B mov si,0x404 */ 0xBE, 0x04, 0x04, ++ /* 0000025E call word 0x3c4 */ 0xE8, 0x63, 0x01, ++ /* 00000261 pop si */ 0x5E, ++ /* 00000262 and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, ++ /* 00000266 cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, ++ /* 0000026A jz 0x276 */ 0x74, 0x0A, ++ /* 0000026C push si */ 0x56, ++ /* 0000026D mov si,0x432 */ 0xBE, 0x32, 0x04, ++ /* 00000270 call word 0x3c4 */ 0xE8, 0x51, 0x01, ++ /* 00000273 pop si */ 0x5E, ++ /* 00000274 jmp short 0x233 */ 0xEB, 0xBD, ++ /* 00000276 push cs */ 0x0E, ++ /* 00000277 pop ds */ 0x1F, ++ /* 00000278 mov si,0x100 */ 0xBE, 0x00, 0x01, ++ /* 0000027B mov cx,0x100 */ 0xB9, 0x00, 0x01, ++ /* 0000027E cld */ 0xFC, ++ /* 0000027F rep movsb */ 0xF3, 0xA4, ++ /* 00000281 pop cx */ 0x59, ++ /* 00000282 pop si */ 0x5E, ++ /* 00000283 pop ds */ 0x1F, ++ /* 00000284 pop di */ 0x5F, ++ /* 00000285 pop es */ 0x07, ++ /* 00000286 jmp word 0x3ac */ 0xE9, 0x23, 0x01, ++ /* 00000289 push dx */ 0x52, ++ /* 0000028A push ax */ 0x50, ++ /* 0000028B push si */ 0x56, ++ /* 0000028C mov si,0x41a */ 0xBE, 0x1A, 0x04, ++ /* 0000028F call word 0x3c4 */ 0xE8, 0x32, 0x01, ++ /* 00000292 pop si */ 0x5E, ++ /* 00000293 cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, ++ /* 00000297 jz 0x2a3 */ 0x74, 0x0A, ++ /* 00000299 push si */ 0x56, ++ /* 0000029A mov si,0x432 */ 0xBE, 0x32, 0x04, ++ /* 0000029D call word 0x3c4 */ 0xE8, 0x24, 0x01, ++ /* 000002A0 pop si */ 0x5E, ++ /* 000002A1 jmp short 0x233 */ 0xEB, 0x90, ++ /* 000002A3 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, ++ /* 000002A6 mov al,0x20 */ 0xB0, 0x20, ++ /* 000002A8 out dx,al */ 0xEE, ++ /* 000002A9 push dx */ 0x52, ++ /* 000002AA push ax */ 0x50, ++ /* 000002AB mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002AE mov ax,0x4 */ 0xB8, 0x04, 0x00, ++ /* 000002B1 out dx,ax */ 0xEF, ++ /* 000002B2 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002B5 mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002B8 out dx,ax */ 0xEF, ++ /* 000002B9 pop ax */ 0x58, ++ /* 000002BA pop dx */ 0x5A, ++ /* 000002BB push dx */ 0x52, ++ /* 000002BC push ax */ 0x50, ++ /* 000002BD mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002C0 mov ax,0x5 */ 0xB8, 0x05, 0x00, ++ /* 000002C3 out dx,ax */ 0xEF, ++ /* 000002C4 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002C7 mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002CA out dx,ax */ 0xEF, ++ /* 000002CB pop ax */ 0x58, ++ /* 000002CC pop dx */ 0x5A, ++ /* 000002CD push dx */ 0x52, ++ /* 000002CE push ax */ 0x50, ++ /* 000002CF mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002D2 mov ax,0x8 */ 0xB8, 0x08, 0x00, ++ /* 000002D5 out dx,ax */ 0xEF, ++ /* 000002D6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002D9 mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002DC out dx,ax */ 0xEF, ++ /* 000002DD pop ax */ 0x58, ++ /* 000002DE pop dx */ 0x5A, ++ /* 000002DF push dx */ 0x52, ++ /* 000002E0 push ax */ 0x50, ++ /* 000002E1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002E4 mov ax,0x9 */ 0xB8, 0x09, 0x00, ++ /* 000002E7 out dx,ax */ 0xEF, ++ /* 000002E8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002EB mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002EE out dx,ax */ 0xEF, ++ /* 000002EF pop ax */ 0x58, ++ /* 000002F0 pop dx */ 0x5A, ++ /* 000002F1 push dx */ 0x52, ++ /* 000002F2 push ax */ 0x50, ++ /* 000002F3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002F6 mov ax,0x3 */ 0xB8, 0x03, 0x00, ++ /* 000002F9 out dx,ax */ 0xEF, ++ /* 000002FA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002FD mov ax,0x20 */ 0xB8, 0x20, 0x00, ++ /* 00000300 out dx,ax */ 0xEF, ++ /* 00000301 pop ax */ 0x58, ++ /* 00000302 pop dx */ 0x5A, ++ /* 00000303 push dx */ 0x52, ++ /* 00000304 push ax */ 0x50, ++ /* 00000305 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 00000308 mov ax,0x1 */ 0xB8, 0x01, 0x00, ++ /* 0000030B out dx,ax */ 0xEF, ++ /* 0000030C mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 0000030F mov ax,0x400 */ 0xB8, 0x00, 0x04, ++ /* 00000312 out dx,ax */ 0xEF, ++ /* 00000313 pop ax */ 0x58, ++ /* 00000314 pop dx */ 0x5A, ++ /* 00000315 push dx */ 0x52, ++ /* 00000316 push ax */ 0x50, ++ /* 00000317 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 0000031A mov ax,0x6 */ 0xB8, 0x06, 0x00, ++ /* 0000031D out dx,ax */ 0xEF, ++ /* 0000031E mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000321 mov ax,0x400 */ 0xB8, 0x00, 0x04, ++ /* 00000324 out dx,ax */ 0xEF, ++ /* 00000325 pop ax */ 0x58, ++ /* 00000326 pop dx */ 0x5A, ++ /* 00000327 push dx */ 0x52, ++ /* 00000328 push ax */ 0x50, ++ /* 00000329 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 0000032C mov ax,0x2 */ 0xB8, 0x02, 0x00, ++ /* 0000032F out dx,ax */ 0xEF, ++ /* 00000330 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000333 mov ax,0x300 */ 0xB8, 0x00, 0x03, ++ /* 00000336 out dx,ax */ 0xEF, ++ /* 00000337 pop ax */ 0x58, ++ /* 00000338 pop dx */ 0x5A, ++ /* 00000339 push dx */ 0x52, ++ /* 0000033A push ax */ 0x50, ++ /* 0000033B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 0000033E mov ax,0x7 */ 0xB8, 0x07, 0x00, ++ /* 00000341 out dx,ax */ 0xEF, ++ /* 00000342 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000345 mov ax,0x300 */ 0xB8, 0x00, 0x03, ++ /* 00000348 out dx,ax */ 0xEF, ++ /* 00000349 pop ax */ 0x58, ++ /* 0000034A pop dx */ 0x5A, ++ /* 0000034B push dx */ 0x52, ++ /* 0000034C push ax */ 0x50, ++ /* 0000034D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 00000350 mov ax,0x4 */ 0xB8, 0x04, 0x00, ++ /* 00000353 out dx,ax */ 0xEF, ++ /* 00000354 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000357 mov ax,0x41 */ 0xB8, 0x41, 0x00, ++ /* 0000035A out dx,ax */ 0xEF, ++ /* 0000035B pop ax */ 0x58, ++ /* 0000035C pop dx */ 0x5A, ++ /* 0000035D pop ax */ 0x58, ++ /* 0000035E pop dx */ 0x5A, ++ /* 0000035F jmp short 0x3ac */ 0xEB, 0x4B, ++ /* 00000361 push si */ 0x56, ++ /* 00000362 mov si,0x411 */ 0xBE, 0x11, 0x04, ++ /* 00000365 call word 0x3c4 */ 0xE8, 0x5C, 0x00, ++ /* 00000368 pop si */ 0x5E, ++ /* 00000369 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, ++ /* 0000036C jmp short 0x3ac */ 0xEB, 0x3E, ++ /* 0000036E push si */ 0x56, ++ /* 0000036F mov si,0x43f */ 0xBE, 0x3F, 0x04, ++ /* 00000372 call word 0x3c4 */ 0xE8, 0x4F, 0x00, ++ /* 00000375 pop si */ 0x5E, ++ /* 00000376 jmp short 0x3b8 */ 0xEB, 0x40, ++ /* 00000378 push si */ 0x56, ++ /* 00000379 mov si,0x452 */ 0xBE, 0x52, 0x04, ++ /* 0000037C call word 0x3c4 */ 0xE8, 0x45, 0x00, ++ /* 0000037F pop si */ 0x5E, ++ /* 00000380 jmp short 0x3b8 */ 0xEB, 0x36, ++ /* 00000382 push si */ 0x56, ++ /* 00000383 mov si,0x423 */ 0xBE, 0x23, 0x04, ++ /* 00000386 call word 0x3c4 */ 0xE8, 0x3B, 0x00, ++ /* 00000389 pop si */ 0x5E, ++ /* 0000038A cmp al,0x3 */ 0x3C, 0x03, ++ /* 0000038C jz 0x39d */ 0x74, 0x0F, ++ /* 0000038E cmp al,0x12 */ 0x3C, 0x12, ++ /* 00000390 jz 0x3a1 */ 0x74, 0x0F, ++ /* 00000392 push si */ 0x56, ++ /* 00000393 mov si,0x432 */ 0xBE, 0x32, 0x04, ++ /* 00000396 call word 0x3c4 */ 0xE8, 0x2B, 0x00, ++ /* 00000399 pop si */ 0x5E, ++ /* 0000039A jmp word 0x233 */ 0xE9, 0x96, 0xFE, ++ /* 0000039D mov al,0x30 */ 0xB0, 0x30, ++ /* 0000039F jmp short 0x3a3 */ 0xEB, 0x02, ++ /* 000003A1 mov al,0x20 */ 0xB0, 0x20, ++ /* 000003A3 push si */ 0x56, ++ /* 000003A4 mov si,0x3d6 */ 0xBE, 0xD6, 0x03, ++ /* 000003A7 call word 0x3c4 */ 0xE8, 0x1A, 0x00, ++ /* 000003AA pop si */ 0x5E, ++ /* 000003AB iretw */ 0xCF, ++ /* 000003AC push si */ 0x56, ++ /* 000003AD mov si,0x3d6 */ 0xBE, 0xD6, 0x03, ++ /* 000003B0 call word 0x3c4 */ 0xE8, 0x11, 0x00, ++ /* 000003B3 pop si */ 0x5E, ++ /* 000003B4 mov ax,0x4f */ 0xB8, 0x4F, 0x00, ++ /* 000003B7 iretw */ 0xCF, ++ /* 000003B8 push si */ 0x56, ++ /* 000003B9 mov si,0x3dc */ 0xBE, 0xDC, 0x03, ++ /* 000003BC call word 0x3c4 */ 0xE8, 0x05, 0x00, ++ /* 000003BF pop si */ 0x5E, ++ /* 000003C0 mov ax,0x14f */ 0xB8, 0x4F, 0x01, ++ /* 000003C3 iretw */ 0xCF, ++ /* 000003C4 pushaw */ 0x60, ++ /* 000003C5 push ds */ 0x1E, ++ /* 000003C6 push cs */ 0x0E, ++ /* 000003C7 pop ds */ 0x1F, ++ /* 000003C8 mov dx,0x402 */ 0xBA, 0x02, 0x04, ++ /* 000003CB lodsb */ 0xAC, ++ /* 000003CC cmp al,0x0 */ 0x3C, 0x00, ++ /* 000003CE jz 0x3d3 */ 0x74, 0x03, ++ /* 000003D0 out dx,al */ 0xEE, ++ /* 000003D1 jmp short 0x3cb */ 0xEB, 0xF8, ++ /* 000003D3 pop ds */ 0x1F, ++ /* 000003D4 popaw */ 0x61, ++ /* 000003D5 ret */ 0xC3, ++ /* 000003D6 inc bp */ 0x45, ++ /* 000003D7 js 0x442 */ 0x78, 0x69, ++ /* 000003D9 jz 0x3e5 */ 0x74, 0x0A, ++ /* 000003DB add [di+0x6e],dl */ 0x00, 0x55, 0x6E, ++ /* 000003DE jnc 0x455 */ 0x73, 0x75, ++ /* 000003E0 jo 0x452 */ 0x70, 0x70, ++ /* 000003E2 outsw */ 0x6F, ++ /* 000003E3 jc 0x459 */ 0x72, 0x74, ++ /* 000003E5 or al,[fs:bx+si] */ 0x65, 0x64, 0x0A, 0x00, ++ /* 000003E9 push bp */ 0x55, ++ /* 000003EA outsb */ 0x6E, ++ /* 000003EB imul bp,[bp+0x6f],byte +0x77 */ 0x6B, 0x6E, 0x6F, 0x77, ++ /* 000003EF outsb */ 0x6E, ++ /* 000003F0 and [bp+0x75],al */ 0x20, 0x46, 0x75, ++ /* 000003F3 outsb */ 0x6E, ++ /* 000003F4 arpl [si+0x69],si */ 0x63, 0x74, 0x69, ++ /* 000003F7 outsw */ 0x6F, ++ /* 000003F8 outsb */ 0x6E, ++ /* 000003F9 or al,[bx+si] */ 0x0A, 0x00, ++ /* 000003FB inc di */ 0x47, ++ /* 000003FC gs jz 0x448 */ 0x65, 0x74, 0x49, ++ /* 000003FF outsb */ 0x6E, ++ /* 00000400 outsd */ 0x66, 0x6F, ++ /* 00000402 or al,[bx+si] */ 0x0A, 0x00, ++ /* 00000404 inc di */ 0x47, ++ /* 00000405 gs jz 0x455 */ 0x65, 0x74, 0x4D, ++ /* 00000408 outsw */ 0x6F, ++ /* 00000409 gs dec cx */ 0x64, 0x65, 0x49, ++ /* 0000040C outsb */ 0x6E, ++ /* 0000040D outsd */ 0x66, 0x6F, ++ /* 0000040F or al,[bx+si] */ 0x0A, 0x00, ++ /* 00000411 inc di */ 0x47, ++ /* 00000412 gs jz 0x462 */ 0x65, 0x74, 0x4D, ++ /* 00000415 outsw */ 0x6F, ++ /* 00000416 or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, ++ /* 0000041A push bx */ 0x53, ++ /* 0000041B gs jz 0x46b */ 0x65, 0x74, 0x4D, ++ /* 0000041E outsw */ 0x6F, ++ /* 0000041F or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, ++ /* 00000423 push bx */ 0x53, ++ /* 00000424 gs jz 0x474 */ 0x65, 0x74, 0x4D, ++ /* 00000427 outsw */ 0x6F, ++ /* 00000428 gs dec sp */ 0x64, 0x65, 0x4C, ++ /* 0000042B gs a32 popaw */ 0x65, 0x67, 0x61, ++ /* 0000042E arpl [bx+di+0xa],di */ 0x63, 0x79, 0x0A, ++ /* 00000431 add [di+0x6e],dl */ 0x00, 0x55, 0x6E, ++ /* 00000434 imul bp,[bx+0x77],byte +0x6e */ 0x6B, 0x6F, 0x77, 0x6E, ++ /* 00000438 and [di+0x6f],cl */ 0x20, 0x4D, 0x6F, ++ /* 0000043B or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, ++ /* 0000043F inc di */ 0x47, ++ /* 00000440 gs jz 0x493 */ 0x65, 0x74, 0x50, ++ /* 00000443 insw */ 0x6D, ++ /* 00000444 inc bx */ 0x43, ++ /* 00000445 popaw */ 0x61, ++ /* 00000446 jo 0x4a9 */ 0x70, 0x61, ++ /* 00000448 bound bp,[bx+di+0x6c] */ 0x62, 0x69, 0x6C, ++ /* 0000044B imul si,[si+0x69],word 0x7365 */ 0x69, 0x74, 0x69, 0x65, 0x73, ++ /* 00000450 or al,[bx+si] */ 0x0A, 0x00, ++ /* 00000452 push dx */ 0x52, ++ /* 00000453 gs popaw */ 0x65, 0x61, ++ /* 00000455 fs inc bp */ 0x64, 0x45, ++ /* 00000457 fs */ 0x64, ++ /* 00000458 db 0x69 */ 0x69, ++ /* 00000459 or al,[fs:bx+si] */ 0x64, 0x0A, 0x00, + }; + #endif diff --git a/0007-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch b/0007-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch new file mode 100644 index 0000000..a651a68 --- /dev/null +++ b/0007-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch @@ -0,0 +1,129 @@ +From b6e4c1bf03878da7bd82224d523c44fd1fa96aaa Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Tue, 25 Feb 2014 18:40:35 +0100 +Subject: [PATCH] MdeModulePkg: TerminalDxe: add other text resolutions + +When the console output is multiplexed to several devices by +ConSplitterDxe, then ConSplitterDxe builds an intersection of text modes +supported by all console output devices. + +Two notable output devices are provided by: +(1) MdeModulePkg/Universal/Console/GraphicsConsoleDxe, +(2) MdeModulePkg/Universal/Console/TerminalDxe. + +GraphicsConsoleDxe supports four modes at most -- see +InitializeGraphicsConsoleTextMode() and "mGraphicsConsoleModeData": + +(1a) 80x25 (required by the UEFI spec as mode 0), +(1b) 80x50 (not necessarily supported, but if it is, then the UEFI spec + requires the driver to provide it as mode 1), +(1c) 100x31 (corresponding to graphics resolution 800x600, which the UEFI + spec requires from all plug-in graphics devices), +(1d) "full screen" resolution, derived form the underlying GOP's + horizontal and vertical resolutions with division by EFI_GLYPH_WIDTH + (8) and EFI_GLYPH_HEIGHT (19), respectively. + +The automatic "full screen resolution" makes GraphicsConsoleDxe's +character console very flexible. However, TerminalDxe (which runs on +serial ports) only provides the following fixed resolutions -- see +InitializeTerminalConsoleTextMode() and "mTerminalConsoleModeData": + +(2a) 80x25 (required by the UEFI spec as mode 0), +(2b) 80x50 (since the character resolution of a serial device cannot be + interrogated easily, this is added unconditionally as mode 1), +(2c) 100x31 (since the character resolution of a serial device cannot be + interrogated easily, this is added unconditionally as mode 2). + +When ConSplitterDxe combines (1) and (2), multiplexing console output to +both video output and serial terminal, the list of commonly supported text +modes (ie. the "intersection") comprises: + +(3a) 80x25, unconditionally, from (1a) and (2a), +(3b) 80x50, if the graphics console provides at least 640x950 pixel + resolution, from (1b) and (2b) +(3c) 100x31, if the graphics device is a plug-in one (because in that case + 800x600 is a mandated pixel resolution), from (1c) and (2c). + +Unfortunately, the "full screen resolution" (1d) of the GOP-based text +console is not available in general. + +Mitigate this problem by extending "mTerminalConsoleModeData" with a +handful of text resolutions that are derived from widespread maximal pixel +resolutions. This way TerminalDxe won't cause ConSplitterDxe to filter out +the most frequent (1d) values from the intersection, and eg. the MODE +command in the UEFI shell will offer the "best" (ie. full screen) +resolution too. + +Upstream status: three calendar months (with on-and-off discussion and +patches) have not been enough to find a solution to this problem that +would please all stakeholders. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- adapt commit 0bc77c63de03 (code and commit message) to upstream commit + 390b95a49c14 ("MdeModulePkg/TerminalDxe: Refine + InitializeTerminalConsoleTextMode", 2017-01-10). + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 99dc3720ac86059f60156197328cc433603c536e) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + .../Universal/Console/TerminalDxe/Terminal.c | 41 +++++++++++++++++-- + 1 file changed, 38 insertions(+), 3 deletions(-) + +diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c +index 66dd3ad550..78a198379a 100644 +--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c ++++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c +@@ -113,9 +113,44 @@ TERMINAL_DEV mTerminalDevTemplate = { + }; + + TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData[] = { +- {80, 25}, +- {80, 50}, +- {100, 31}, ++ { 80, 25 }, // from graphics resolution 640 x 480 ++ { 80, 50 }, // from graphics resolution 640 x 960 ++ { 100, 25 }, // from graphics resolution 800 x 480 ++ { 100, 31 }, // from graphics resolution 800 x 600 ++ { 104, 32 }, // from graphics resolution 832 x 624 ++ { 120, 33 }, // from graphics resolution 960 x 640 ++ { 128, 31 }, // from graphics resolution 1024 x 600 ++ { 128, 40 }, // from graphics resolution 1024 x 768 ++ { 144, 45 }, // from graphics resolution 1152 x 864 ++ { 144, 45 }, // from graphics resolution 1152 x 870 ++ { 160, 37 }, // from graphics resolution 1280 x 720 ++ { 160, 40 }, // from graphics resolution 1280 x 760 ++ { 160, 40 }, // from graphics resolution 1280 x 768 ++ { 160, 42 }, // from graphics resolution 1280 x 800 ++ { 160, 50 }, // from graphics resolution 1280 x 960 ++ { 160, 53 }, // from graphics resolution 1280 x 1024 ++ { 170, 40 }, // from graphics resolution 1360 x 768 ++ { 170, 40 }, // from graphics resolution 1366 x 768 ++ { 175, 55 }, // from graphics resolution 1400 x 1050 ++ { 180, 47 }, // from graphics resolution 1440 x 900 ++ { 200, 47 }, // from graphics resolution 1600 x 900 ++ { 200, 63 }, // from graphics resolution 1600 x 1200 ++ { 210, 55 }, // from graphics resolution 1680 x 1050 ++ { 240, 56 }, // from graphics resolution 1920 x 1080 ++ { 240, 63 }, // from graphics resolution 1920 x 1200 ++ { 240, 75 }, // from graphics resolution 1920 x 1440 ++ { 250, 105 }, // from graphics resolution 2000 x 2000 ++ { 256, 80 }, // from graphics resolution 2048 x 1536 ++ { 256, 107 }, // from graphics resolution 2048 x 2048 ++ { 320, 75 }, // from graphics resolution 2560 x 1440 ++ { 320, 84 }, // from graphics resolution 2560 x 1600 ++ { 320, 107 }, // from graphics resolution 2560 x 2048 ++ { 350, 110 }, // from graphics resolution 2800 x 2100 ++ { 400, 126 }, // from graphics resolution 3200 x 2400 ++ { 480, 113 }, // from graphics resolution 3840 x 2160 ++ { 512, 113 }, // from graphics resolution 4096 x 2160 ++ { 960, 227 }, // from graphics resolution 7680 x 4320 ++ { 1024, 227 }, // from graphics resolution 8192 x 4320 + // + // New modes can be added here. + // diff --git a/0007-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch b/0007-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch deleted file mode 100644 index 6882c12..0000000 --- a/0007-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch +++ /dev/null @@ -1,1129 +0,0 @@ -From da502f7cc283055a65ab3caeaa62eb5c6a6fddb5 Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek lersek@redhat.com -Date: Mon, 6 Jul 2015 20:22:02 +0200 -Subject: [PATCH] OvmfPkg: EnrollDefaultKeys: application for enrolling default - keys - -(A port of the https://bugzilla.redhat.com/show_bug.cgi?id=1148296 patch -to Gerd's public RPMs.) - -This application is meant to be invoked by the management layer, after -booting the UEFI shell and getting a shell prompt on the serial console. -The app enrolls a number of certificates (see below), and then reports -status to the serial console as well. The expected output is "info: -success": - -> Shell> EnrollDefaultKeys.efi -> info: SetupMode=1 SecureBoot=0 SecureBootEnable=0 CustomMode=0 VendorKeys=1 -> info: SetupMode=0 SecureBoot=1 SecureBootEnable=1 CustomMode=0 VendorKeys=0 -> info: success -> Shell> - -In case of success, the management layer can force off or reboot the VM -(for example with the "reset -s" or "reset -c" UEFI shell commands, -respectively), and start the guest installation with SecureBoot enabled. - -PK: -- A unique, static, ad-hoc certificate whose private half has been - destroyed (more precisely, never saved) and is therefore unusable for - signing. (The command for creating this certificate is saved in the - source code.) - -KEK: -- same ad-hoc certificate as used for the PK, -- "Microsoft Corporation KEK CA 2011" -- the dbx data in Fedora's dbxtool - package is signed (indirectly, through a chain) with this; enrolling - such a KEK should allow guests to install those updates. - -DB: -- "Microsoft Windows Production PCA 2011" -- to load Windows 8 and Windows - Server 2012 R2, -- "Microsoft Corporation UEFI CA 2011" -- to load Linux and signed PCI - oproms. - -Contributed-under: TianoCore Contribution Agreement 1.0 -Signed-off-by: Laszlo Ersek lersek@redhat.com ---- - OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c | 963 ++++++++++++++++++++++++ - OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf | 51 ++ - OvmfPkg/OvmfPkgIa32.dsc | 4 + - OvmfPkg/OvmfPkgIa32X64.dsc | 4 + - OvmfPkg/OvmfPkgX64.dsc | 4 + - 5 files changed, 1026 insertions(+) - create mode 100644 OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c - create mode 100644 OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf - -diff --git a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c -new file mode 100644 -index 0000000..447288f ---- /dev/null -+++ b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c -@@ -0,0 +1,963 @@ -+/** @file -+ Enroll default PK, KEK, DB. -+ -+ Copyright (C) 2014, Red Hat, Inc. -+ -+ 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. -+ -+ 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 <Guid/AuthenticatedVariableFormat.h> // gEfiCustomModeEnableGuid -+#include <Guid/GlobalVariable.h> // EFI_SETUP_MODE_NAME -+#include <Guid/ImageAuthentication.h> // EFI_IMAGE_SECURITY_DATABASE -+#include <Library/BaseMemoryLib.h> // CopyGuid() -+#include <Library/DebugLib.h> // ASSERT() -+#include <Library/MemoryAllocationLib.h> // FreePool() -+#include <Library/ShellCEntryLib.h> // ShellAppMain() -+#include <Library/UefiLib.h> // AsciiPrint() -+#include <Library/UefiRuntimeServicesTableLib.h> // gRT -+ -+// -+// The example self-signed certificate below, which we'll use for both Platform -+// Key, and first Key Exchange Key, has been generated with the following -+// non-interactive openssl command. The passphrase is read from /dev/urandom, -+// and not saved, and the private key is written to /dev/null. In other words, -+// we can't sign anything else against this certificate, which is our purpose. -+// -+/* -+ openssl req \ -+ -passout file:<(head -c 16 /dev/urandom) \ -+ -x509 \ -+ -newkey rsa:2048 \ -+ -keyout /dev/null \ -+ -outform DER \ -+ -subj $( -+ printf /C=US -+ printf /ST=TestStateOrProvince -+ printf /L=TestLocality -+ printf /O=TestOrganization -+ printf /OU=TestOrganizationalUnit -+ printf /CN=TestCommonName -+ printf /emailAddress=test@example.com -+ ) \ -+ 2>/dev/null \ -+ | xxd -i -+*/ -+STATIC CONST UINT8 ExampleCert[] = { -+ 0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0x2d, 0xa0, 0x03, 0x02, 0x01, 0x02, -+ 0x02, 0x09, 0x00, 0xcf, 0x9f, 0x51, 0xa3, 0x07, 0xdb, 0x54, 0xa1, 0x30, 0x0d, -+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, -+ 0x30, 0x81, 0xb8, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, -+ 0x02, 0x55, 0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, -+ 0x13, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x50, -+ 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, -+ 0x55, 0x04, 0x07, 0x0c, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, -+ 0x6c, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, -+ 0x0c, 0x10, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, -+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, -+ 0x0b, 0x0c, 0x16, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, -+ 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x74, 0x31, -+ 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x54, 0x65, 0x73, -+ 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x31, 0x1f, -+ 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, -+ 0x16, 0x10, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, -+ 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, -+ 0x30, 0x39, 0x31, 0x33, 0x32, 0x38, 0x32, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x34, -+ 0x31, 0x31, 0x30, 0x38, 0x31, 0x33, 0x32, 0x38, 0x32, 0x32, 0x5a, 0x30, 0x81, -+ 0xb8, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, -+ 0x53, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x13, 0x54, -+ 0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x50, 0x72, 0x6f, -+ 0x76, 0x69, 0x6e, 0x63, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, -+ 0x07, 0x0c, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, -+ 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x10, -+ 0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, -+ 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, -+ 0x16, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, -+ 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x17, 0x30, -+ 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x54, 0x65, 0x73, 0x74, 0x43, -+ 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x31, 0x1f, 0x30, 0x1d, -+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, -+ 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, -+ 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, -+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, -+ 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbf, 0xf1, 0xce, -+ 0x17, 0x32, 0xac, 0xc4, 0x4b, 0xb2, 0xed, 0x84, 0x76, 0xe5, 0xd0, 0xf8, 0x21, -+ 0xac, 0x10, 0xf8, 0x18, 0x09, 0x0e, 0x07, 0x13, 0x76, 0x21, 0x5c, 0xc4, 0xcc, -+ 0xd5, 0xe6, 0x25, 0xa7, 0x26, 0x53, 0x79, 0x2f, 0x16, 0x4b, 0x85, 0xbd, 0xae, -+ 0x42, 0x64, 0x58, 0xcb, 0x5e, 0xe8, 0x6e, 0x5a, 0xd0, 0xc4, 0x0f, 0x38, 0x16, -+ 0xbe, 0xd3, 0x22, 0xa7, 0x3c, 0x9b, 0x8b, 0x5e, 0xcb, 0x62, 0x35, 0xc5, 0x9b, -+ 0xe2, 0x8e, 0x4c, 0x65, 0x57, 0x4f, 0xcb, 0x27, 0xad, 0xe7, 0x63, 0xa7, 0x77, -+ 0x2b, 0xd5, 0x02, 0x42, 0x70, 0x46, 0xac, 0xba, 0xb6, 0x60, 0x57, 0xd9, 0xce, -+ 0x31, 0xc5, 0x12, 0x03, 0x4a, 0xf7, 0x2a, 0x2b, 0x40, 0x06, 0xb4, 0xdb, 0x31, -+ 0xb7, 0x83, 0x6c, 0x67, 0x87, 0x98, 0x8b, 0xce, 0x1b, 0x30, 0x7a, 0xfa, 0x35, -+ 0x6c, 0x86, 0x20, 0x74, 0xc5, 0x7d, 0x32, 0x31, 0x18, 0xeb, 0x69, 0xf7, 0x2d, -+ 0x20, 0xc4, 0xf0, 0xd2, 0xfa, 0x67, 0x81, 0xc1, 0xbb, 0x23, 0xbb, 0x75, 0x1a, -+ 0xe4, 0xb4, 0x49, 0x99, 0xdf, 0x12, 0x4c, 0xe3, 0x6d, 0x76, 0x24, 0x85, 0x24, -+ 0xae, 0x5a, 0x9e, 0xbd, 0x54, 0x1c, 0xf9, 0x0e, 0xed, 0x96, 0xb5, 0xd8, 0xa2, -+ 0x0d, 0x2a, 0x38, 0x5d, 0x12, 0x97, 0xb0, 0x4d, 0x75, 0x85, 0x1e, 0x47, 0x6d, -+ 0xe1, 0x25, 0x59, 0xcb, 0xe9, 0x33, 0x86, 0x6a, 0xef, 0x98, 0x24, 0xa0, 0x2b, -+ 0x02, 0x7b, 0xc0, 0x9f, 0x88, 0x03, 0xb0, 0xbe, 0x22, 0x65, 0x83, 0x77, 0xb3, -+ 0x30, 0xba, 0xe0, 0x3b, 0x54, 0x31, 0x3a, 0x45, 0x81, 0x9c, 0x48, 0xaf, 0xc1, -+ 0x11, 0x5b, 0xf2, 0x3a, 0x1e, 0x33, 0x1b, 0x8f, 0x0e, 0x04, 0xa4, 0x16, 0xd4, -+ 0x6b, 0x57, 0xee, 0xe7, 0xba, 0xf5, 0xee, 0xaf, 0xe2, 0x4c, 0x50, 0xf8, 0x68, -+ 0x57, 0x88, 0xfb, 0x7f, 0xa3, 0xcf, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, -+ 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, -+ 0x1e, 0x44, 0xe5, 0xef, 0xcd, 0x6e, 0x1f, 0xdb, 0xcb, 0x4f, 0x94, 0x8f, 0xe3, -+ 0x3b, 0x1a, 0x8c, 0xe6, 0x95, 0x29, 0x61, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, -+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x1e, 0x44, 0xe5, 0xef, 0xcd, 0x6e, -+ 0x1f, 0xdb, 0xcb, 0x4f, 0x94, 0x8f, 0xe3, 0x3b, 0x1a, 0x8c, 0xe6, 0x95, 0x29, -+ 0x61, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, -+ 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, -+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x12, 0x9c, 0x3e, 0x38, -+ 0xfc, 0x26, 0xea, 0x6d, 0xb7, 0x5c, 0x29, 0x3c, 0x76, 0x20, 0x0c, 0xb2, 0xa9, -+ 0x0f, 0xdf, 0xc0, 0x85, 0xfe, 0xeb, 0xec, 0x1d, 0x5d, 0x73, 0x84, 0xac, 0x8a, -+ 0xb4, 0x2a, 0x86, 0x38, 0x30, 0xaf, 0xd2, 0x2d, 0x2a, 0xde, 0x54, 0xc8, 0x5c, -+ 0x29, 0x90, 0x24, 0xf2, 0x39, 0xc1, 0xa5, 0x00, 0xb4, 0xb7, 0xd8, 0xdc, 0x59, -+ 0x64, 0x50, 0x62, 0x5f, 0x54, 0xf1, 0x73, 0x02, 0x4d, 0x43, 0xc5, 0xc3, 0xc4, -+ 0x0e, 0x62, 0x60, 0x8c, 0x53, 0x66, 0x57, 0x77, 0xb5, 0x81, 0xda, 0x1f, 0x81, -+ 0xda, 0xe9, 0xd6, 0x5e, 0x82, 0xce, 0xa7, 0x5c, 0xc0, 0xa6, 0xbe, 0x9c, 0x5c, -+ 0x7b, 0xa5, 0x15, 0xc8, 0xd7, 0x14, 0x53, 0xd3, 0x5c, 0x1c, 0x9f, 0x8a, 0x9f, -+ 0x66, 0x15, 0xd5, 0xd3, 0x2a, 0x27, 0x0c, 0xee, 0x9f, 0x80, 0x39, 0x88, 0x7b, -+ 0x24, 0xde, 0x0c, 0x61, 0xa3, 0x44, 0xd8, 0x8d, 0x2e, 0x79, 0xf8, 0x1e, 0x04, -+ 0x5a, 0xcb, 0xd6, 0x9c, 0xa3, 0x22, 0x8f, 0x09, 0x32, 0x1e, 0xe1, 0x65, 0x8f, -+ 0x10, 0x5f, 0xd8, 0x52, 0x56, 0xd5, 0x77, 0xac, 0x58, 0x46, 0x60, 0xba, 0x2e, -+ 0xe2, 0x3f, 0x58, 0x7d, 0x60, 0xfc, 0x31, 0x4a, 0x3a, 0xaf, 0x61, 0x55, 0x5f, -+ 0xfb, 0x68, 0x14, 0x74, 0xda, 0xdc, 0x42, 0x78, 0xcc, 0xee, 0xff, 0x5c, 0x03, -+ 0x24, 0x26, 0x2c, 0xb8, 0x3a, 0x81, 0xad, 0xdb, 0xe7, 0xed, 0xe1, 0x62, 0x84, -+ 0x07, 0x1a, 0xc8, 0xa4, 0x4e, 0xb0, 0x87, 0xf7, 0x96, 0xd8, 0x33, 0x9b, 0x0d, -+ 0xa7, 0x77, 0xae, 0x5b, 0xaf, 0xad, 0xe6, 0x5a, 0xc9, 0xfa, 0xa4, 0xe4, 0xe5, -+ 0x57, 0xbb, 0x97, 0xdd, 0x92, 0x85, 0xd8, 0x03, 0x45, 0xfe, 0xd8, 0x6b, 0xb1, -+ 0xdb, 0x85, 0x36, 0xb9, 0xd9, 0x28, 0xbf, 0x17, 0xae, 0x11, 0xde, 0x10, 0x19, -+ 0x26, 0x5b, 0xc0, 0x3d, 0xc7 -+}; -+ -+// -+// Second KEK: "Microsoft Corporation KEK CA 2011". -+// SHA1: 31:59:0b:fd:89:c9:d7:4e:d0:87:df:ac:66:33:4b:39:31:25:4b:30 -+// -+// "dbx" updates in "dbxtool" are signed with a key derived from this KEK. -+// -+STATIC CONST UINT8 MicrosoftKEK[] = { -+ 0x30, 0x82, 0x05, 0xe8, 0x30, 0x82, 0x03, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02, -+ 0x02, 0x0a, 0x61, 0x0a, 0xd1, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, -+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, -+ 0x00, 0x30, 0x81, 0x91, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, -+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, -+ 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, -+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, -+ 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, -+ 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, -+ 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x3b, 0x30, -+ 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x4d, 0x69, 0x63, 0x72, 0x6f, -+ 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, -+ 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x50, 0x61, 0x72, -+ 0x74, 0x79, 0x20, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x70, 0x6c, 0x61, 0x63, -+ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, -+ 0x36, 0x32, 0x34, 0x32, 0x30, 0x34, 0x31, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x32, -+ 0x36, 0x30, 0x36, 0x32, 0x34, 0x32, 0x30, 0x35, 0x31, 0x32, 0x39, 0x5a, 0x30, -+ 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, -+ 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, -+ 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, -+ 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, -+ 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, -+ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, -+ 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x2a, 0x30, 0x28, 0x06, -+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, -+ 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, -+ 0x6e, 0x20, 0x4b, 0x45, 0x4b, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x31, -+ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, -+ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, -+ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xe8, 0xb5, 0x8a, 0xbf, 0xad, -+ 0x57, 0x26, 0xb0, 0x26, 0xc3, 0xea, 0xe7, 0xfb, 0x57, 0x7a, 0x44, 0x02, 0x5d, -+ 0x07, 0x0d, 0xda, 0x4a, 0xe5, 0x74, 0x2a, 0xe6, 0xb0, 0x0f, 0xec, 0x6d, 0xeb, -+ 0xec, 0x7f, 0xb9, 0xe3, 0x5a, 0x63, 0x32, 0x7c, 0x11, 0x17, 0x4f, 0x0e, 0xe3, -+ 0x0b, 0xa7, 0x38, 0x15, 0x93, 0x8e, 0xc6, 0xf5, 0xe0, 0x84, 0xb1, 0x9a, 0x9b, -+ 0x2c, 0xe7, 0xf5, 0xb7, 0x91, 0xd6, 0x09, 0xe1, 0xe2, 0xc0, 0x04, 0xa8, 0xac, -+ 0x30, 0x1c, 0xdf, 0x48, 0xf3, 0x06, 0x50, 0x9a, 0x64, 0xa7, 0x51, 0x7f, 0xc8, -+ 0x85, 0x4f, 0x8f, 0x20, 0x86, 0xce, 0xfe, 0x2f, 0xe1, 0x9f, 0xff, 0x82, 0xc0, -+ 0xed, 0xe9, 0xcd, 0xce, 0xf4, 0x53, 0x6a, 0x62, 0x3a, 0x0b, 0x43, 0xb9, 0xe2, -+ 0x25, 0xfd, 0xfe, 0x05, 0xf9, 0xd4, 0xc4, 0x14, 0xab, 0x11, 0xe2, 0x23, 0x89, -+ 0x8d, 0x70, 0xb7, 0xa4, 0x1d, 0x4d, 0xec, 0xae, 0xe5, 0x9c, 0xfa, 0x16, 0xc2, -+ 0xd7, 0xc1, 0xcb, 0xd4, 0xe8, 0xc4, 0x2f, 0xe5, 0x99, 0xee, 0x24, 0x8b, 0x03, -+ 0xec, 0x8d, 0xf2, 0x8b, 0xea, 0xc3, 0x4a, 0xfb, 0x43, 0x11, 0x12, 0x0b, 0x7e, -+ 0xb5, 0x47, 0x92, 0x6c, 0xdc, 0xe6, 0x04, 0x89, 0xeb, 0xf5, 0x33, 0x04, 0xeb, -+ 0x10, 0x01, 0x2a, 0x71, 0xe5, 0xf9, 0x83, 0x13, 0x3c, 0xff, 0x25, 0x09, 0x2f, -+ 0x68, 0x76, 0x46, 0xff, 0xba, 0x4f, 0xbe, 0xdc, 0xad, 0x71, 0x2a, 0x58, 0xaa, -+ 0xfb, 0x0e, 0xd2, 0x79, 0x3d, 0xe4, 0x9b, 0x65, 0x3b, 0xcc, 0x29, 0x2a, 0x9f, -+ 0xfc, 0x72, 0x59, 0xa2, 0xeb, 0xae, 0x92, 0xef, 0xf6, 0x35, 0x13, 0x80, 0xc6, -+ 0x02, 0xec, 0xe4, 0x5f, 0xcc, 0x9d, 0x76, 0xcd, 0xef, 0x63, 0x92, 0xc1, 0xaf, -+ 0x79, 0x40, 0x84, 0x79, 0x87, 0x7f, 0xe3, 0x52, 0xa8, 0xe8, 0x9d, 0x7b, 0x07, -+ 0x69, 0x8f, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4f, 0x30, -+ 0x82, 0x01, 0x4b, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, -+ 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, -+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x62, 0xfc, 0x43, 0xcd, 0xa0, 0x3e, 0xa4, -+ 0xcb, 0x67, 0x12, 0xd2, 0x5b, 0xd9, 0x55, 0xac, 0x7b, 0xcc, 0xb6, 0x8a, 0x5f, -+ 0x30, 0x19, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, -+ 0x04, 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, -+ 0x41, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, -+ 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, -+ 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, -+ 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0x66, 0x52, 0x43, 0xe1, 0x7e, 0x58, 0x11, -+ 0xbf, 0xd6, 0x4e, 0x9e, 0x23, 0x55, 0x08, 0x3b, 0x3a, 0x22, 0x6a, 0xa8, 0x30, -+ 0x5c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x55, 0x30, 0x53, 0x30, 0x51, 0xa0, -+ 0x4f, 0xa0, 0x4d, 0x86, 0x4b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, -+ 0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, -+ 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x70, -+ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, -+ 0x72, 0x54, 0x68, 0x69, 0x50, 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, -+ 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, -+ 0x72, 0x6c, 0x30, 0x60, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, -+ 0x01, 0x04, 0x54, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, -+ 0x05, 0x07, 0x30, 0x02, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, -+ 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, -+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, 0x72, 0x74, -+ 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, 0x61, -+ 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, -+ 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, -+ 0x02, 0x01, 0x00, 0xd4, 0x84, 0x88, 0xf5, 0x14, 0x94, 0x18, 0x02, 0xca, 0x2a, -+ 0x3c, 0xfb, 0x2a, 0x92, 0x1c, 0x0c, 0xd7, 0xa0, 0xd1, 0xf1, 0xe8, 0x52, 0x66, -+ 0xa8, 0xee, 0xa2, 0xb5, 0x75, 0x7a, 0x90, 0x00, 0xaa, 0x2d, 0xa4, 0x76, 0x5a, -+ 0xea, 0x79, 0xb7, 0xb9, 0x37, 0x6a, 0x51, 0x7b, 0x10, 0x64, 0xf6, 0xe1, 0x64, -+ 0xf2, 0x02, 0x67, 0xbe, 0xf7, 0xa8, 0x1b, 0x78, 0xbd, 0xba, 0xce, 0x88, 0x58, -+ 0x64, 0x0c, 0xd6, 0x57, 0xc8, 0x19, 0xa3, 0x5f, 0x05, 0xd6, 0xdb, 0xc6, 0xd0, -+ 0x69, 0xce, 0x48, 0x4b, 0x32, 0xb7, 0xeb, 0x5d, 0xd2, 0x30, 0xf5, 0xc0, 0xf5, -+ 0xb8, 0xba, 0x78, 0x07, 0xa3, 0x2b, 0xfe, 0x9b, 0xdb, 0x34, 0x56, 0x84, 0xec, -+ 0x82, 0xca, 0xae, 0x41, 0x25, 0x70, 0x9c, 0x6b, 0xe9, 0xfe, 0x90, 0x0f, 0xd7, -+ 0x96, 0x1f, 0xe5, 0xe7, 0x94, 0x1f, 0xb2, 0x2a, 0x0c, 0x8d, 0x4b, 0xff, 0x28, -+ 0x29, 0x10, 0x7b, 0xf7, 0xd7, 0x7c, 0xa5, 0xd1, 0x76, 0xb9, 0x05, 0xc8, 0x79, -+ 0xed, 0x0f, 0x90, 0x92, 0x9c, 0xc2, 0xfe, 0xdf, 0x6f, 0x7e, 0x6c, 0x0f, 0x7b, -+ 0xd4, 0xc1, 0x45, 0xdd, 0x34, 0x51, 0x96, 0x39, 0x0f, 0xe5, 0x5e, 0x56, 0xd8, -+ 0x18, 0x05, 0x96, 0xf4, 0x07, 0xa6, 0x42, 0xb3, 0xa0, 0x77, 0xfd, 0x08, 0x19, -+ 0xf2, 0x71, 0x56, 0xcc, 0x9f, 0x86, 0x23, 0xa4, 0x87, 0xcb, 0xa6, 0xfd, 0x58, -+ 0x7e, 0xd4, 0x69, 0x67, 0x15, 0x91, 0x7e, 0x81, 0xf2, 0x7f, 0x13, 0xe5, 0x0d, -+ 0x8b, 0x8a, 0x3c, 0x87, 0x84, 0xeb, 0xe3, 0xce, 0xbd, 0x43, 0xe5, 0xad, 0x2d, -+ 0x84, 0x93, 0x8e, 0x6a, 0x2b, 0x5a, 0x7c, 0x44, 0xfa, 0x52, 0xaa, 0x81, 0xc8, -+ 0x2d, 0x1c, 0xbb, 0xe0, 0x52, 0xdf, 0x00, 0x11, 0xf8, 0x9a, 0x3d, 0xc1, 0x60, -+ 0xb0, 0xe1, 0x33, 0xb5, 0xa3, 0x88, 0xd1, 0x65, 0x19, 0x0a, 0x1a, 0xe7, 0xac, -+ 0x7c, 0xa4, 0xc1, 0x82, 0x87, 0x4e, 0x38, 0xb1, 0x2f, 0x0d, 0xc5, 0x14, 0x87, -+ 0x6f, 0xfd, 0x8d, 0x2e, 0xbc, 0x39, 0xb6, 0xe7, 0xe6, 0xc3, 0xe0, 0xe4, 0xcd, -+ 0x27, 0x84, 0xef, 0x94, 0x42, 0xef, 0x29, 0x8b, 0x90, 0x46, 0x41, 0x3b, 0x81, -+ 0x1b, 0x67, 0xd8, 0xf9, 0x43, 0x59, 0x65, 0xcb, 0x0d, 0xbc, 0xfd, 0x00, 0x92, -+ 0x4f, 0xf4, 0x75, 0x3b, 0xa7, 0xa9, 0x24, 0xfc, 0x50, 0x41, 0x40, 0x79, 0xe0, -+ 0x2d, 0x4f, 0x0a, 0x6a, 0x27, 0x76, 0x6e, 0x52, 0xed, 0x96, 0x69, 0x7b, 0xaf, -+ 0x0f, 0xf7, 0x87, 0x05, 0xd0, 0x45, 0xc2, 0xad, 0x53, 0x14, 0x81, 0x1f, 0xfb, -+ 0x30, 0x04, 0xaa, 0x37, 0x36, 0x61, 0xda, 0x4a, 0x69, 0x1b, 0x34, 0xd8, 0x68, -+ 0xed, 0xd6, 0x02, 0xcf, 0x6c, 0x94, 0x0c, 0xd3, 0xcf, 0x6c, 0x22, 0x79, 0xad, -+ 0xb1, 0xf0, 0xbc, 0x03, 0xa2, 0x46, 0x60, 0xa9, 0xc4, 0x07, 0xc2, 0x21, 0x82, -+ 0xf1, 0xfd, 0xf2, 0xe8, 0x79, 0x32, 0x60, 0xbf, 0xd8, 0xac, 0xa5, 0x22, 0x14, -+ 0x4b, 0xca, 0xc1, 0xd8, 0x4b, 0xeb, 0x7d, 0x3f, 0x57, 0x35, 0xb2, 0xe6, 0x4f, -+ 0x75, 0xb4, 0xb0, 0x60, 0x03, 0x22, 0x53, 0xae, 0x91, 0x79, 0x1d, 0xd6, 0x9b, -+ 0x41, 0x1f, 0x15, 0x86, 0x54, 0x70, 0xb2, 0xde, 0x0d, 0x35, 0x0f, 0x7c, 0xb0, -+ 0x34, 0x72, 0xba, 0x97, 0x60, 0x3b, 0xf0, 0x79, 0xeb, 0xa2, 0xb2, 0x1c, 0x5d, -+ 0xa2, 0x16, 0xb8, 0x87, 0xc5, 0xe9, 0x1b, 0xf6, 0xb5, 0x97, 0x25, 0x6f, 0x38, -+ 0x9f, 0xe3, 0x91, 0xfa, 0x8a, 0x79, 0x98, 0xc3, 0x69, 0x0e, 0xb7, 0xa3, 0x1c, -+ 0x20, 0x05, 0x97, 0xf8, 0xca, 0x14, 0xae, 0x00, 0xd7, 0xc4, 0xf3, 0xc0, 0x14, -+ 0x10, 0x75, 0x6b, 0x34, 0xa0, 0x1b, 0xb5, 0x99, 0x60, 0xf3, 0x5c, 0xb0, 0xc5, -+ 0x57, 0x4e, 0x36, 0xd2, 0x32, 0x84, 0xbf, 0x9e -+}; -+ -+// -+// First DB entry: "Microsoft Windows Production PCA 2011" -+// SHA1: 58:0a:6f:4c:c4:e4:b6:69:b9:eb:dc:1b:2b:3e:08:7b:80:d0:67:8d -+// -+// Windows 8 and Windows Server 2012 R2 boot loaders are signed with a chain -+// rooted in this certificate. -+// -+STATIC CONST UINT8 MicrosoftPCA[] = { -+ 0x30, 0x82, 0x05, 0xd7, 0x30, 0x82, 0x03, 0xbf, 0xa0, 0x03, 0x02, 0x01, 0x02, -+ 0x02, 0x0a, 0x61, 0x07, 0x76, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, -+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, -+ 0x00, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, -+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, -+ 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, -+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, -+ 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, -+ 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, -+ 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x32, 0x30, -+ 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x4d, 0x69, 0x63, 0x72, 0x6f, -+ 0x73, 0x6f, 0x66, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, -+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, -+ 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x30, 0x30, 0x1e, 0x17, -+ 0x0d, 0x31, 0x31, 0x31, 0x30, 0x31, 0x39, 0x31, 0x38, 0x34, 0x31, 0x34, 0x32, -+ 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x30, 0x31, 0x39, 0x31, 0x38, 0x35, 0x31, -+ 0x34, 0x32, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, -+ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, -+ 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, -+ 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, -+ 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, -+ 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, -+ 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, -+ 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x4d, 0x69, 0x63, -+ 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, -+ 0x73, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, -+ 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30, -+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, -+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, -+ 0x01, 0x00, 0xdd, 0x0c, 0xbb, 0xa2, 0xe4, 0x2e, 0x09, 0xe3, 0xe7, 0xc5, 0xf7, -+ 0x96, 0x69, 0xbc, 0x00, 0x21, 0xbd, 0x69, 0x33, 0x33, 0xef, 0xad, 0x04, 0xcb, -+ 0x54, 0x80, 0xee, 0x06, 0x83, 0xbb, 0xc5, 0x20, 0x84, 0xd9, 0xf7, 0xd2, 0x8b, -+ 0xf3, 0x38, 0xb0, 0xab, 0xa4, 0xad, 0x2d, 0x7c, 0x62, 0x79, 0x05, 0xff, 0xe3, -+ 0x4a, 0x3f, 0x04, 0x35, 0x20, 0x70, 0xe3, 0xc4, 0xe7, 0x6b, 0xe0, 0x9c, 0xc0, -+ 0x36, 0x75, 0xe9, 0x8a, 0x31, 0xdd, 0x8d, 0x70, 0xe5, 0xdc, 0x37, 0xb5, 0x74, -+ 0x46, 0x96, 0x28, 0x5b, 0x87, 0x60, 0x23, 0x2c, 0xbf, 0xdc, 0x47, 0xa5, 0x67, -+ 0xf7, 0x51, 0x27, 0x9e, 0x72, 0xeb, 0x07, 0xa6, 0xc9, 0xb9, 0x1e, 0x3b, 0x53, -+ 0x35, 0x7c, 0xe5, 0xd3, 0xec, 0x27, 0xb9, 0x87, 0x1c, 0xfe, 0xb9, 0xc9, 0x23, -+ 0x09, 0x6f, 0xa8, 0x46, 0x91, 0xc1, 0x6e, 0x96, 0x3c, 0x41, 0xd3, 0xcb, 0xa3, -+ 0x3f, 0x5d, 0x02, 0x6a, 0x4d, 0xec, 0x69, 0x1f, 0x25, 0x28, 0x5c, 0x36, 0xff, -+ 0xfd, 0x43, 0x15, 0x0a, 0x94, 0xe0, 0x19, 0xb4, 0xcf, 0xdf, 0xc2, 0x12, 0xe2, -+ 0xc2, 0x5b, 0x27, 0xee, 0x27, 0x78, 0x30, 0x8b, 0x5b, 0x2a, 0x09, 0x6b, 0x22, -+ 0x89, 0x53, 0x60, 0x16, 0x2c, 0xc0, 0x68, 0x1d, 0x53, 0xba, 0xec, 0x49, 0xf3, -+ 0x9d, 0x61, 0x8c, 0x85, 0x68, 0x09, 0x73, 0x44, 0x5d, 0x7d, 0xa2, 0x54, 0x2b, -+ 0xdd, 0x79, 0xf7, 0x15, 0xcf, 0x35, 0x5d, 0x6c, 0x1c, 0x2b, 0x5c, 0xce, 0xbc, -+ 0x9c, 0x23, 0x8b, 0x6f, 0x6e, 0xb5, 0x26, 0xd9, 0x36, 0x13, 0xc3, 0x4f, 0xd6, -+ 0x27, 0xae, 0xb9, 0x32, 0x3b, 0x41, 0x92, 0x2c, 0xe1, 0xc7, 0xcd, 0x77, 0xe8, -+ 0xaa, 0x54, 0x4e, 0xf7, 0x5c, 0x0b, 0x04, 0x87, 0x65, 0xb4, 0x43, 0x18, 0xa8, -+ 0xb2, 0xe0, 0x6d, 0x19, 0x77, 0xec, 0x5a, 0x24, 0xfa, 0x48, 0x03, 0x02, 0x03, -+ 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x43, 0x30, 0x82, 0x01, 0x3f, 0x30, 0x10, -+ 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, -+ 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, -+ 0x14, 0xa9, 0x29, 0x02, 0x39, 0x8e, 0x16, 0xc4, 0x97, 0x78, 0xcd, 0x90, 0xf9, -+ 0x9e, 0x4f, 0x9a, 0xe1, 0x7c, 0x55, 0xaf, 0x53, 0x30, 0x19, 0x06, 0x09, 0x2b, -+ 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0c, 0x1e, 0x0a, 0x00, -+ 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0b, 0x06, 0x03, -+ 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, -+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, -+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, -+ 0xd5, 0xf6, 0x56, 0xcb, 0x8f, 0xe8, 0xa2, 0x5c, 0x62, 0x68, 0xd1, 0x3d, 0x94, -+ 0x90, 0x5b, 0xd7, 0xce, 0x9a, 0x18, 0xc4, 0x30, 0x56, 0x06, 0x03, 0x55, 0x1d, -+ 0x1f, 0x04, 0x4f, 0x30, 0x4d, 0x30, 0x4b, 0xa0, 0x49, 0xa0, 0x47, 0x86, 0x45, -+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x6d, 0x69, -+ 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, -+ 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, -+ 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x52, 0x6f, 0x6f, 0x43, 0x65, 0x72, 0x41, -+ 0x75, 0x74, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x33, -+ 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x5a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, -+ 0x07, 0x01, 0x01, 0x04, 0x4e, 0x30, 0x4c, 0x30, 0x4a, 0x06, 0x08, 0x2b, 0x06, -+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 0x74, 0x74, 0x70, 0x3a, -+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, -+ 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, -+ 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x52, 0x6f, 0x6f, 0x43, 0x65, 0x72, -+ 0x41, 0x75, 0x74, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x36, 0x2d, 0x32, -+ 0x33, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, -+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x14, -+ 0xfc, 0x7c, 0x71, 0x51, 0xa5, 0x79, 0xc2, 0x6e, 0xb2, 0xef, 0x39, 0x3e, 0xbc, -+ 0x3c, 0x52, 0x0f, 0x6e, 0x2b, 0x3f, 0x10, 0x13, 0x73, 0xfe, 0xa8, 0x68, 0xd0, -+ 0x48, 0xa6, 0x34, 0x4d, 0x8a, 0x96, 0x05, 0x26, 0xee, 0x31, 0x46, 0x90, 0x61, -+ 0x79, 0xd6, 0xff, 0x38, 0x2e, 0x45, 0x6b, 0xf4, 0xc0, 0xe5, 0x28, 0xb8, 0xda, -+ 0x1d, 0x8f, 0x8a, 0xdb, 0x09, 0xd7, 0x1a, 0xc7, 0x4c, 0x0a, 0x36, 0x66, 0x6a, -+ 0x8c, 0xec, 0x1b, 0xd7, 0x04, 0x90, 0xa8, 0x18, 0x17, 0xa4, 0x9b, 0xb9, 0xe2, -+ 0x40, 0x32, 0x36, 0x76, 0xc4, 0xc1, 0x5a, 0xc6, 0xbf, 0xe4, 0x04, 0xc0, 0xea, -+ 0x16, 0xd3, 0xac, 0xc3, 0x68, 0xef, 0x62, 0xac, 0xdd, 0x54, 0x6c, 0x50, 0x30, -+ 0x58, 0xa6, 0xeb, 0x7c, 0xfe, 0x94, 0xa7, 0x4e, 0x8e, 0xf4, 0xec, 0x7c, 0x86, -+ 0x73, 0x57, 0xc2, 0x52, 0x21, 0x73, 0x34, 0x5a, 0xf3, 0xa3, 0x8a, 0x56, 0xc8, -+ 0x04, 0xda, 0x07, 0x09, 0xed, 0xf8, 0x8b, 0xe3, 0xce, 0xf4, 0x7e, 0x8e, 0xae, -+ 0xf0, 0xf6, 0x0b, 0x8a, 0x08, 0xfb, 0x3f, 0xc9, 0x1d, 0x72, 0x7f, 0x53, 0xb8, -+ 0xeb, 0xbe, 0x63, 0xe0, 0xe3, 0x3d, 0x31, 0x65, 0xb0, 0x81, 0xe5, 0xf2, 0xac, -+ 0xcd, 0x16, 0xa4, 0x9f, 0x3d, 0xa8, 0xb1, 0x9b, 0xc2, 0x42, 0xd0, 0x90, 0x84, -+ 0x5f, 0x54, 0x1d, 0xff, 0x89, 0xea, 0xba, 0x1d, 0x47, 0x90, 0x6f, 0xb0, 0x73, -+ 0x4e, 0x41, 0x9f, 0x40, 0x9f, 0x5f, 0xe5, 0xa1, 0x2a, 0xb2, 0x11, 0x91, 0x73, -+ 0x8a, 0x21, 0x28, 0xf0, 0xce, 0xde, 0x73, 0x39, 0x5f, 0x3e, 0xab, 0x5c, 0x60, -+ 0xec, 0xdf, 0x03, 0x10, 0xa8, 0xd3, 0x09, 0xe9, 0xf4, 0xf6, 0x96, 0x85, 0xb6, -+ 0x7f, 0x51, 0x88, 0x66, 0x47, 0x19, 0x8d, 0xa2, 0xb0, 0x12, 0x3d, 0x81, 0x2a, -+ 0x68, 0x05, 0x77, 0xbb, 0x91, 0x4c, 0x62, 0x7b, 0xb6, 0xc1, 0x07, 0xc7, 0xba, -+ 0x7a, 0x87, 0x34, 0x03, 0x0e, 0x4b, 0x62, 0x7a, 0x99, 0xe9, 0xca, 0xfc, 0xce, -+ 0x4a, 0x37, 0xc9, 0x2d, 0xa4, 0x57, 0x7c, 0x1c, 0xfe, 0x3d, 0xdc, 0xb8, 0x0f, -+ 0x5a, 0xfa, 0xd6, 0xc4, 0xb3, 0x02, 0x85, 0x02, 0x3a, 0xea, 0xb3, 0xd9, 0x6e, -+ 0xe4, 0x69, 0x21, 0x37, 0xde, 0x81, 0xd1, 0xf6, 0x75, 0x19, 0x05, 0x67, 0xd3, -+ 0x93, 0x57, 0x5e, 0x29, 0x1b, 0x39, 0xc8, 0xee, 0x2d, 0xe1, 0xcd, 0xe4, 0x45, -+ 0x73, 0x5b, 0xd0, 0xd2, 0xce, 0x7a, 0xab, 0x16, 0x19, 0x82, 0x46, 0x58, 0xd0, -+ 0x5e, 0x9d, 0x81, 0xb3, 0x67, 0xaf, 0x6c, 0x35, 0xf2, 0xbc, 0xe5, 0x3f, 0x24, -+ 0xe2, 0x35, 0xa2, 0x0a, 0x75, 0x06, 0xf6, 0x18, 0x56, 0x99, 0xd4, 0x78, 0x2c, -+ 0xd1, 0x05, 0x1b, 0xeb, 0xd0, 0x88, 0x01, 0x9d, 0xaa, 0x10, 0xf1, 0x05, 0xdf, -+ 0xba, 0x7e, 0x2c, 0x63, 0xb7, 0x06, 0x9b, 0x23, 0x21, 0xc4, 0xf9, 0x78, 0x6c, -+ 0xe2, 0x58, 0x17, 0x06, 0x36, 0x2b, 0x91, 0x12, 0x03, 0xcc, 0xa4, 0xd9, 0xf2, -+ 0x2d, 0xba, 0xf9, 0x94, 0x9d, 0x40, 0xed, 0x18, 0x45, 0xf1, 0xce, 0x8a, 0x5c, -+ 0x6b, 0x3e, 0xab, 0x03, 0xd3, 0x70, 0x18, 0x2a, 0x0a, 0x6a, 0xe0, 0x5f, 0x47, -+ 0xd1, 0xd5, 0x63, 0x0a, 0x32, 0xf2, 0xaf, 0xd7, 0x36, 0x1f, 0x2a, 0x70, 0x5a, -+ 0xe5, 0x42, 0x59, 0x08, 0x71, 0x4b, 0x57, 0xba, 0x7e, 0x83, 0x81, 0xf0, 0x21, -+ 0x3c, 0xf4, 0x1c, 0xc1, 0xc5, 0xb9, 0x90, 0x93, 0x0e, 0x88, 0x45, 0x93, 0x86, -+ 0xe9, 0xb1, 0x20, 0x99, 0xbe, 0x98, 0xcb, 0xc5, 0x95, 0xa4, 0x5d, 0x62, 0xd6, -+ 0xa0, 0x63, 0x08, 0x20, 0xbd, 0x75, 0x10, 0x77, 0x7d, 0x3d, 0xf3, 0x45, 0xb9, -+ 0x9f, 0x97, 0x9f, 0xcb, 0x57, 0x80, 0x6f, 0x33, 0xa9, 0x04, 0xcf, 0x77, 0xa4, -+ 0x62, 0x1c, 0x59, 0x7e -+}; -+ -+// -+// Second DB entry: "Microsoft Corporation UEFI CA 2011" -+// SHA1: 46:de:f6:3b:5c:e6:1c:f8:ba:0d:e2:e6:63:9c:10:19:d0:ed:14:f3 -+// -+// To verify the "shim" binary and PCI expansion ROMs with. -+// -+STATIC CONST UINT8 MicrosoftUefiCA[] = { -+ 0x30, 0x82, 0x06, 0x10, 0x30, 0x82, 0x03, 0xf8, 0xa0, 0x03, 0x02, 0x01, 0x02, -+ 0x02, 0x0a, 0x61, 0x08, 0xd3, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, -+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, -+ 0x00, 0x30, 0x81, 0x91, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, -+ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, -+ 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, -+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, -+ 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, -+ 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, -+ 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x3b, 0x30, -+ 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x4d, 0x69, 0x63, 0x72, 0x6f, -+ 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, -+ 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x50, 0x61, 0x72, -+ 0x74, 0x79, 0x20, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x70, 0x6c, 0x61, 0x63, -+ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, -+ 0x36, 0x32, 0x37, 0x32, 0x31, 0x32, 0x32, 0x34, 0x35, 0x5a, 0x17, 0x0d, 0x32, -+ 0x36, 0x30, 0x36, 0x32, 0x37, 0x32, 0x31, 0x33, 0x32, 0x34, 0x35, 0x5a, 0x30, -+ 0x81, 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, -+ 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, -+ 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, -+ 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, -+ 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, -+ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, -+ 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x2b, 0x30, 0x29, 0x06, -+ 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, -+ 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, -+ 0x6e, 0x20, 0x55, 0x45, 0x46, 0x49, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, -+ 0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, -+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, -+ 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x08, 0x6c, 0x4c, 0xc7, -+ 0x45, 0x09, 0x6a, 0x4b, 0x0c, 0xa4, 0xc0, 0x87, 0x7f, 0x06, 0x75, 0x0c, 0x43, -+ 0x01, 0x54, 0x64, 0xe0, 0x16, 0x7f, 0x07, 0xed, 0x92, 0x7d, 0x0b, 0xb2, 0x73, -+ 0xbf, 0x0c, 0x0a, 0xc6, 0x4a, 0x45, 0x61, 0xa0, 0xc5, 0x16, 0x2d, 0x96, 0xd3, -+ 0xf5, 0x2b, 0xa0, 0xfb, 0x4d, 0x49, 0x9b, 0x41, 0x80, 0x90, 0x3c, 0xb9, 0x54, -+ 0xfd, 0xe6, 0xbc, 0xd1, 0x9d, 0xc4, 0xa4, 0x18, 0x8a, 0x7f, 0x41, 0x8a, 0x5c, -+ 0x59, 0x83, 0x68, 0x32, 0xbb, 0x8c, 0x47, 0xc9, 0xee, 0x71, 0xbc, 0x21, 0x4f, -+ 0x9a, 0x8a, 0x7c, 0xff, 0x44, 0x3f, 0x8d, 0x8f, 0x32, 0xb2, 0x26, 0x48, 0xae, -+ 0x75, 0xb5, 0xee, 0xc9, 0x4c, 0x1e, 0x4a, 0x19, 0x7e, 0xe4, 0x82, 0x9a, 0x1d, -+ 0x78, 0x77, 0x4d, 0x0c, 0xb0, 0xbd, 0xf6, 0x0f, 0xd3, 0x16, 0xd3, 0xbc, 0xfa, -+ 0x2b, 0xa5, 0x51, 0x38, 0x5d, 0xf5, 0xfb, 0xba, 0xdb, 0x78, 0x02, 0xdb, 0xff, -+ 0xec, 0x0a, 0x1b, 0x96, 0xd5, 0x83, 0xb8, 0x19, 0x13, 0xe9, 0xb6, 0xc0, 0x7b, -+ 0x40, 0x7b, 0xe1, 0x1f, 0x28, 0x27, 0xc9, 0xfa, 0xef, 0x56, 0x5e, 0x1c, 0xe6, -+ 0x7e, 0x94, 0x7e, 0xc0, 0xf0, 0x44, 0xb2, 0x79, 0x39, 0xe5, 0xda, 0xb2, 0x62, -+ 0x8b, 0x4d, 0xbf, 0x38, 0x70, 0xe2, 0x68, 0x24, 0x14, 0xc9, 0x33, 0xa4, 0x08, -+ 0x37, 0xd5, 0x58, 0x69, 0x5e, 0xd3, 0x7c, 0xed, 0xc1, 0x04, 0x53, 0x08, 0xe7, -+ 0x4e, 0xb0, 0x2a, 0x87, 0x63, 0x08, 0x61, 0x6f, 0x63, 0x15, 0x59, 0xea, 0xb2, -+ 0x2b, 0x79, 0xd7, 0x0c, 0x61, 0x67, 0x8a, 0x5b, 0xfd, 0x5e, 0xad, 0x87, 0x7f, -+ 0xba, 0x86, 0x67, 0x4f, 0x71, 0x58, 0x12, 0x22, 0x04, 0x22, 0x22, 0xce, 0x8b, -+ 0xef, 0x54, 0x71, 0x00, 0xce, 0x50, 0x35, 0x58, 0x76, 0x95, 0x08, 0xee, 0x6a, -+ 0xb1, 0xa2, 0x01, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x76, -+ 0x30, 0x82, 0x01, 0x72, 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, -+ 0x82, 0x37, 0x15, 0x01, 0x04, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x23, -+ 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x02, 0x04, 0x16, -+ 0x04, 0x14, 0xf8, 0xc1, 0x6b, 0xb7, 0x7f, 0x77, 0x53, 0x4a, 0xf3, 0x25, 0x37, -+ 0x1d, 0x4e, 0xa1, 0x26, 0x7b, 0x0f, 0x20, 0x70, 0x80, 0x30, 0x1d, 0x06, 0x03, -+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x13, 0xad, 0xbf, 0x43, 0x09, 0xbd, -+ 0x82, 0x70, 0x9c, 0x8c, 0xd5, 0x4f, 0x31, 0x6e, 0xd5, 0x22, 0x98, 0x8a, 0x1b, -+ 0xd4, 0x30, 0x19, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, -+ 0x02, 0x04, 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, -+ 0x00, 0x41, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, -+ 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, -+ 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, -+ 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0x66, 0x52, 0x43, 0xe1, 0x7e, 0x58, -+ 0x11, 0xbf, 0xd6, 0x4e, 0x9e, 0x23, 0x55, 0x08, 0x3b, 0x3a, 0x22, 0x6a, 0xa8, -+ 0x30, 0x5c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x55, 0x30, 0x53, 0x30, 0x51, -+ 0xa0, 0x4f, 0xa0, 0x4d, 0x86, 0x4b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, -+ 0x63, 0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, -+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, -+ 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, -+ 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, -+ 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, -+ 0x63, 0x72, 0x6c, 0x30, 0x60, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, -+ 0x01, 0x01, 0x04, 0x54, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01, -+ 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, -+ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, -+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, 0x72, -+ 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, -+ 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, -+ 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, -+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, -+ 0x82, 0x02, 0x01, 0x00, 0x35, 0x08, 0x42, 0xff, 0x30, 0xcc, 0xce, 0xf7, 0x76, -+ 0x0c, 0xad, 0x10, 0x68, 0x58, 0x35, 0x29, 0x46, 0x32, 0x76, 0x27, 0x7c, 0xef, -+ 0x12, 0x41, 0x27, 0x42, 0x1b, 0x4a, 0xaa, 0x6d, 0x81, 0x38, 0x48, 0x59, 0x13, -+ 0x55, 0xf3, 0xe9, 0x58, 0x34, 0xa6, 0x16, 0x0b, 0x82, 0xaa, 0x5d, 0xad, 0x82, -+ 0xda, 0x80, 0x83, 0x41, 0x06, 0x8f, 0xb4, 0x1d, 0xf2, 0x03, 0xb9, 0xf3, 0x1a, -+ 0x5d, 0x1b, 0xf1, 0x50, 0x90, 0xf9, 0xb3, 0x55, 0x84, 0x42, 0x28, 0x1c, 0x20, -+ 0xbd, 0xb2, 0xae, 0x51, 0x14, 0xc5, 0xc0, 0xac, 0x97, 0x95, 0x21, 0x1c, 0x90, -+ 0xdb, 0x0f, 0xfc, 0x77, 0x9e, 0x95, 0x73, 0x91, 0x88, 0xca, 0xbd, 0xbd, 0x52, -+ 0xb9, 0x05, 0x50, 0x0d, 0xdf, 0x57, 0x9e, 0xa0, 0x61, 0xed, 0x0d, 0xe5, 0x6d, -+ 0x25, 0xd9, 0x40, 0x0f, 0x17, 0x40, 0xc8, 0xce, 0xa3, 0x4a, 0xc2, 0x4d, 0xaf, -+ 0x9a, 0x12, 0x1d, 0x08, 0x54, 0x8f, 0xbd, 0xc7, 0xbc, 0xb9, 0x2b, 0x3d, 0x49, -+ 0x2b, 0x1f, 0x32, 0xfc, 0x6a, 0x21, 0x69, 0x4f, 0x9b, 0xc8, 0x7e, 0x42, 0x34, -+ 0xfc, 0x36, 0x06, 0x17, 0x8b, 0x8f, 0x20, 0x40, 0xc0, 0xb3, 0x9a, 0x25, 0x75, -+ 0x27, 0xcd, 0xc9, 0x03, 0xa3, 0xf6, 0x5d, 0xd1, 0xe7, 0x36, 0x54, 0x7a, 0xb9, -+ 0x50, 0xb5, 0xd3, 0x12, 0xd1, 0x07, 0xbf, 0xbb, 0x74, 0xdf, 0xdc, 0x1e, 0x8f, -+ 0x80, 0xd5, 0xed, 0x18, 0xf4, 0x2f, 0x14, 0x16, 0x6b, 0x2f, 0xde, 0x66, 0x8c, -+ 0xb0, 0x23, 0xe5, 0xc7, 0x84, 0xd8, 0xed, 0xea, 0xc1, 0x33, 0x82, 0xad, 0x56, -+ 0x4b, 0x18, 0x2d, 0xf1, 0x68, 0x95, 0x07, 0xcd, 0xcf, 0xf0, 0x72, 0xf0, 0xae, -+ 0xbb, 0xdd, 0x86, 0x85, 0x98, 0x2c, 0x21, 0x4c, 0x33, 0x2b, 0xf0, 0x0f, 0x4a, -+ 0xf0, 0x68, 0x87, 0xb5, 0x92, 0x55, 0x32, 0x75, 0xa1, 0x6a, 0x82, 0x6a, 0x3c, -+ 0xa3, 0x25, 0x11, 0xa4, 0xed, 0xad, 0xd7, 0x04, 0xae, 0xcb, 0xd8, 0x40, 0x59, -+ 0xa0, 0x84, 0xd1, 0x95, 0x4c, 0x62, 0x91, 0x22, 0x1a, 0x74, 0x1d, 0x8c, 0x3d, -+ 0x47, 0x0e, 0x44, 0xa6, 0xe4, 0xb0, 0x9b, 0x34, 0x35, 0xb1, 0xfa, 0xb6, 0x53, -+ 0xa8, 0x2c, 0x81, 0xec, 0xa4, 0x05, 0x71, 0xc8, 0x9d, 0xb8, 0xba, 0xe8, 0x1b, -+ 0x44, 0x66, 0xe4, 0x47, 0x54, 0x0e, 0x8e, 0x56, 0x7f, 0xb3, 0x9f, 0x16, 0x98, -+ 0xb2, 0x86, 0xd0, 0x68, 0x3e, 0x90, 0x23, 0xb5, 0x2f, 0x5e, 0x8f, 0x50, 0x85, -+ 0x8d, 0xc6, 0x8d, 0x82, 0x5f, 0x41, 0xa1, 0xf4, 0x2e, 0x0d, 0xe0, 0x99, 0xd2, -+ 0x6c, 0x75, 0xe4, 0xb6, 0x69, 0xb5, 0x21, 0x86, 0xfa, 0x07, 0xd1, 0xf6, 0xe2, -+ 0x4d, 0xd1, 0xda, 0xad, 0x2c, 0x77, 0x53, 0x1e, 0x25, 0x32, 0x37, 0xc7, 0x6c, -+ 0x52, 0x72, 0x95, 0x86, 0xb0, 0xf1, 0x35, 0x61, 0x6a, 0x19, 0xf5, 0xb2, 0x3b, -+ 0x81, 0x50, 0x56, 0xa6, 0x32, 0x2d, 0xfe, 0xa2, 0x89, 0xf9, 0x42, 0x86, 0x27, -+ 0x18, 0x55, 0xa1, 0x82, 0xca, 0x5a, 0x9b, 0xf8, 0x30, 0x98, 0x54, 0x14, 0xa6, -+ 0x47, 0x96, 0x25, 0x2f, 0xc8, 0x26, 0xe4, 0x41, 0x94, 0x1a, 0x5c, 0x02, 0x3f, -+ 0xe5, 0x96, 0xe3, 0x85, 0x5b, 0x3c, 0x3e, 0x3f, 0xbb, 0x47, 0x16, 0x72, 0x55, -+ 0xe2, 0x25, 0x22, 0xb1, 0xd9, 0x7b, 0xe7, 0x03, 0x06, 0x2a, 0xa3, 0xf7, 0x1e, -+ 0x90, 0x46, 0xc3, 0x00, 0x0d, 0xd6, 0x19, 0x89, 0xe3, 0x0e, 0x35, 0x27, 0x62, -+ 0x03, 0x71, 0x15, 0xa6, 0xef, 0xd0, 0x27, 0xa0, 0xa0, 0x59, 0x37, 0x60, 0xf8, -+ 0x38, 0x94, 0xb8, 0xe0, 0x78, 0x70, 0xf8, 0xba, 0x4c, 0x86, 0x87, 0x94, 0xf6, -+ 0xe0, 0xae, 0x02, 0x45, 0xee, 0x65, 0xc2, 0xb6, 0xa3, 0x7e, 0x69, 0x16, 0x75, -+ 0x07, 0x92, 0x9b, 0xf5, 0xa6, 0xbc, 0x59, 0x83, 0x58 -+}; -+ -+// -+// The most important thing about the variable payload is that it is a list of -+// lists, where the element size of any given *inner* list is constant. -+// -+// Since X509 certificates vary in size, each of our *inner* lists will contain -+// one element only (one X.509 certificate). This is explicitly mentioned in -+// the UEFI specification, in "28.4.1 Signature Database", in a Note. -+// -+// The list structure looks as follows: -+// -+// struct EFI_VARIABLE_AUTHENTICATION_2 { | -+// struct EFI_TIME { | -+// UINT16 Year; | -+// UINT8 Month; | -+// UINT8 Day; | -+// UINT8 Hour; | -+// UINT8 Minute; | -+// UINT8 Second; | -+// UINT8 Pad1; | -+// UINT32 Nanosecond; | -+// INT16 TimeZone; | -+// UINT8 Daylight; | -+// UINT8 Pad2; | -+// } TimeStamp; | -+// | -+// struct WIN_CERTIFICATE_UEFI_GUID { | | -+// struct WIN_CERTIFICATE { | | -+// UINT32 dwLength; ----------------------------------------+ | -+// UINT16 wRevision; | | -+// UINT16 wCertificateType; | | -+// } Hdr; | +- DataSize -+// | | -+// EFI_GUID CertType; | | -+// UINT8 CertData[1] = { <--- "struct hack" | | -+// struct EFI_SIGNATURE_LIST { | | | -+// EFI_GUID SignatureType; | | | -+// UINT32 SignatureListSize; -------------------------+ | | -+// UINT32 SignatureHeaderSize; | | | -+// UINT32 SignatureSize; ---------------------------+ | | | -+// UINT8 SignatureHeader[SignatureHeaderSize]; | | | | -+// v | | | -+// struct EFI_SIGNATURE_DATA { | | | | -+// EFI_GUID SignatureOwner; | | | | -+// UINT8 SignatureData[1] = { <--- "struct hack" | | | | -+// X.509 payload | | | | -+// } | | | | -+// } Signatures[]; | | | -+// } SigLists[]; | | -+// }; | | -+// } AuthInfo; | | -+// }; | -+// -+// Given that the "struct hack" invokes undefined behavior (which is why C99 -+// introduced the flexible array member), and because subtracting those pesky -+// sizes of 1 is annoying, and because the format is fully specified in the -+// UEFI specification, we'll introduce two matching convenience structures that -+// are customized for our X.509 purposes. -+// -+#pragma pack(1) -+typedef struct { -+ EFI_TIME TimeStamp; -+ -+ // -+ // dwLength covers data below -+ // -+ UINT32 dwLength; -+ UINT16 wRevision; -+ UINT16 wCertificateType; -+ EFI_GUID CertType; -+} SINGLE_HEADER; -+ -+typedef struct { -+ // -+ // SignatureListSize covers data below -+ // -+ EFI_GUID SignatureType; -+ UINT32 SignatureListSize; -+ UINT32 SignatureHeaderSize; // constant 0 -+ UINT32 SignatureSize; -+ -+ // -+ // SignatureSize covers data below -+ // -+ EFI_GUID SignatureOwner; -+ -+ // -+ // X.509 certificate follows -+ // -+} REPEATING_HEADER; -+#pragma pack() -+ -+/** -+ Enroll a set of DER-formatted X.509 certificates in a global variable, -+ overwriting it. -+ -+ The variable will be rewritten with NV+BS+RT+AT attributes. -+ -+ @param[in] VariableName The name of the variable to overwrite. -+ -+ @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable to -+ overwrite. -+ -+ @param[in] ... A list of -+ -+ IN CONST UINT8 *Cert, -+ IN UINTN CertSize, -+ IN CONST EFI_GUID *OwnerGuid -+ -+ triplets. If the first component of a triplet is -+ NULL, then the other two components are not -+ accessed, and processing is terminated. The list of -+ X.509 certificates is enrolled in the variable -+ specified, overwriting it. The OwnerGuid component -+ identifies the agent installing the certificate. -+ -+ @retval EFI_INVALID_PARAMETER The triplet list is empty (ie. the first Cert -+ value is NULL), or one of the CertSize values -+ is 0, or one of the CertSize values would -+ overflow the accumulated UINT32 data size. -+ -+ @retval EFI_OUT_OF_RESOURCES Out of memory while formatting variable -+ payload. -+ -+ @retval EFI_SUCCESS Enrollment successful; the variable has been -+ overwritten (or created). -+ -+ @return Error codes from gRT->GetTime() and -+ gRT->SetVariable(). -+**/ -+STATIC -+EFI_STATUS -+EFIAPI -+EnrollListOfX509Certs ( -+ IN CHAR16 *VariableName, -+ IN EFI_GUID *VendorGuid, -+ ... -+ ) -+{ -+ UINTN DataSize; -+ SINGLE_HEADER *SingleHeader; -+ REPEATING_HEADER *RepeatingHeader; -+ VA_LIST Marker; -+ CONST UINT8 *Cert; -+ EFI_STATUS Status; -+ UINT8 *Data; -+ UINT8 *Position; -+ -+ Status = EFI_SUCCESS; -+ -+ // -+ // compute total size first, for UINT32 range check, and allocation -+ // -+ DataSize = sizeof *SingleHeader; -+ VA_START (Marker, VendorGuid); -+ for (Cert = VA_ARG (Marker, CONST UINT8 *); -+ Cert != NULL; -+ Cert = VA_ARG (Marker, CONST UINT8 *)) { -+ UINTN CertSize; -+ -+ CertSize = VA_ARG (Marker, UINTN); -+ (VOID)VA_ARG (Marker, CONST EFI_GUID *); -+ -+ if (CertSize == 0 || -+ CertSize > MAX_UINT32 - sizeof *RepeatingHeader || -+ DataSize > MAX_UINT32 - sizeof *RepeatingHeader - CertSize) { -+ Status = EFI_INVALID_PARAMETER; -+ break; -+ } -+ DataSize += sizeof *RepeatingHeader + CertSize; -+ } -+ VA_END (Marker); -+ -+ if (DataSize == sizeof *SingleHeader) { -+ Status = EFI_INVALID_PARAMETER; -+ } -+ if (EFI_ERROR (Status)) { -+ goto Out; -+ } -+ -+ Data = AllocatePool (DataSize); -+ if (Data == NULL) { -+ Status = EFI_OUT_OF_RESOURCES; -+ goto Out; -+ } -+ -+ Position = Data; -+ -+ SingleHeader = (SINGLE_HEADER *)Position; -+ Status = gRT->GetTime (&SingleHeader->TimeStamp, NULL); -+ if (EFI_ERROR (Status)) { -+ goto FreeData; -+ } -+ SingleHeader->TimeStamp.Pad1 = 0; -+ SingleHeader->TimeStamp.Nanosecond = 0; -+ SingleHeader->TimeStamp.TimeZone = 0; -+ SingleHeader->TimeStamp.Daylight = 0; -+ SingleHeader->TimeStamp.Pad2 = 0; -+#if 0 -+ SingleHeader->dwLength = DataSize - sizeof SingleHeader->TimeStamp; -+#else -+ // -+ // This looks like a bug in edk2. According to the UEFI specification, -+ // dwLength is "The length of the entire certificate, including the length of -+ // the header, in bytes". That shouldn't stop right after CertType -- it -+ // should include everything below it. -+ // -+ SingleHeader->dwLength = sizeof *SingleHeader -+ - sizeof SingleHeader->TimeStamp; -+#endif -+ SingleHeader->wRevision = 0x0200; -+ SingleHeader->wCertificateType = WIN_CERT_TYPE_EFI_GUID; -+ CopyGuid (&SingleHeader->CertType, &gEfiCertPkcs7Guid); -+ Position += sizeof *SingleHeader; -+ -+ VA_START (Marker, VendorGuid); -+ for (Cert = VA_ARG (Marker, CONST UINT8 *); -+ Cert != NULL; -+ Cert = VA_ARG (Marker, CONST UINT8 *)) { -+ UINTN CertSize; -+ CONST EFI_GUID *OwnerGuid; -+ -+ CertSize = VA_ARG (Marker, UINTN); -+ OwnerGuid = VA_ARG (Marker, CONST EFI_GUID *); -+ -+ RepeatingHeader = (REPEATING_HEADER *)Position; -+ CopyGuid (&RepeatingHeader->SignatureType, &gEfiCertX509Guid); -+ RepeatingHeader->SignatureListSize = -+ (UINT32)(sizeof *RepeatingHeader + CertSize); -+ RepeatingHeader->SignatureHeaderSize = 0; -+ RepeatingHeader->SignatureSize = -+ (UINT32)(sizeof RepeatingHeader->SignatureOwner + CertSize); -+ CopyGuid (&RepeatingHeader->SignatureOwner, OwnerGuid); -+ Position += sizeof *RepeatingHeader; -+ -+ CopyMem (Position, Cert, CertSize); -+ Position += CertSize; -+ } -+ VA_END (Marker); -+ -+ ASSERT (Data + DataSize == Position); -+ -+ Status = gRT->SetVariable (VariableName, VendorGuid, -+ (EFI_VARIABLE_NON_VOLATILE | -+ EFI_VARIABLE_BOOTSERVICE_ACCESS | -+ EFI_VARIABLE_RUNTIME_ACCESS | -+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), -+ DataSize, Data); -+ -+FreeData: -+ FreePool (Data); -+ -+Out: -+ if (EFI_ERROR (Status)) { -+ AsciiPrint ("error: %a("%s", %g): %r\n", __FUNCTION__, VariableName, -+ VendorGuid, Status); -+ } -+ return Status; -+} -+ -+ -+STATIC -+EFI_STATUS -+EFIAPI -+GetExact ( -+ IN CHAR16 *VariableName, -+ IN EFI_GUID *VendorGuid, -+ OUT VOID *Data, -+ IN UINTN DataSize, -+ IN BOOLEAN AllowMissing -+ ) -+{ -+ UINTN Size; -+ EFI_STATUS Status; -+ -+ Size = DataSize; -+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &Size, Data); -+ if (EFI_ERROR (Status)) { -+ if (Status == EFI_NOT_FOUND && AllowMissing) { -+ ZeroMem (Data, DataSize); -+ return EFI_SUCCESS; -+ } -+ -+ AsciiPrint ("error: GetVariable("%s", %g): %r\n", VariableName, -+ VendorGuid, Status); -+ return Status; -+ } -+ -+ if (Size != DataSize) { -+ AsciiPrint ("error: GetVariable("%s", %g): expected size 0x%Lx, " -+ "got 0x%Lx\n", VariableName, VendorGuid, (UINT64)DataSize, (UINT64)Size); -+ return EFI_PROTOCOL_ERROR; -+ } -+ -+ return EFI_SUCCESS; -+} -+ -+typedef struct { -+ UINT8 SetupMode; -+ UINT8 SecureBoot; -+ UINT8 SecureBootEnable; -+ UINT8 CustomMode; -+ UINT8 VendorKeys; -+} SETTINGS; -+ -+STATIC -+EFI_STATUS -+EFIAPI -+GetSettings ( -+ OUT SETTINGS *Settings -+ ) -+{ -+ EFI_STATUS Status; -+ -+ Status = GetExact (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, -+ &Settings->SetupMode, sizeof Settings->SetupMode, FALSE); -+ if (EFI_ERROR (Status)) { -+ return Status; -+ } -+ -+ Status = GetExact (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, -+ &Settings->SecureBoot, sizeof Settings->SecureBoot, FALSE); -+ if (EFI_ERROR (Status)) { -+ return Status; -+ } -+ -+ Status = GetExact (EFI_SECURE_BOOT_ENABLE_NAME, -+ &gEfiSecureBootEnableDisableGuid, &Settings->SecureBootEnable, -+ sizeof Settings->SecureBootEnable, TRUE); -+ if (EFI_ERROR (Status)) { -+ return Status; -+ } -+ -+ Status = GetExact (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, -+ &Settings->CustomMode, sizeof Settings->CustomMode, FALSE); -+ if (EFI_ERROR (Status)) { -+ return Status; -+ } -+ -+ Status = GetExact (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid, -+ &Settings->VendorKeys, sizeof Settings->VendorKeys, FALSE); -+ return Status; -+} -+ -+STATIC -+VOID -+EFIAPI -+PrintSettings ( -+ IN CONST SETTINGS *Settings -+ ) -+{ -+ AsciiPrint ("info: SetupMode=%d SecureBoot=%d SecureBootEnable=%d " -+ "CustomMode=%d VendorKeys=%d\n", Settings->SetupMode, Settings->SecureBoot, -+ Settings->SecureBootEnable, Settings->CustomMode, Settings->VendorKeys); -+} -+ -+ -+INTN -+EFIAPI -+ShellAppMain ( -+ IN UINTN Argc, -+ IN CHAR16 **Argv -+ ) -+{ -+ EFI_STATUS Status; -+ SETTINGS Settings; -+ -+ Status = GetSettings (&Settings); -+ if (EFI_ERROR (Status)) { -+ return 1; -+ } -+ PrintSettings (&Settings); -+ -+ if (Settings.SetupMode != 1) { -+ AsciiPrint ("error: already in User Mode\n"); -+ return 1; -+ } -+ -+ if (Settings.CustomMode != CUSTOM_SECURE_BOOT_MODE) { -+ Settings.CustomMode = CUSTOM_SECURE_BOOT_MODE; -+ Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, -+ (EFI_VARIABLE_NON_VOLATILE | -+ EFI_VARIABLE_BOOTSERVICE_ACCESS), -+ sizeof Settings.CustomMode, &Settings.CustomMode); -+ if (EFI_ERROR (Status)) { -+ AsciiPrint ("error: SetVariable("%s", %g): %r\n", EFI_CUSTOM_MODE_NAME, -+ &gEfiCustomModeEnableGuid, Status); -+ return 1; -+ } -+ } -+ -+ Status = EnrollListOfX509Certs ( -+ EFI_IMAGE_SECURITY_DATABASE, -+ &gEfiImageSecurityDatabaseGuid, -+ MicrosoftPCA, sizeof MicrosoftPCA, &gEfiCallerIdGuid, -+ MicrosoftUefiCA, sizeof MicrosoftUefiCA, &gEfiCallerIdGuid, -+ NULL); -+ if (EFI_ERROR (Status)) { -+ return 1; -+ } -+ -+ Status = EnrollListOfX509Certs ( -+ EFI_KEY_EXCHANGE_KEY_NAME, -+ &gEfiGlobalVariableGuid, -+ ExampleCert, sizeof ExampleCert, &gEfiCallerIdGuid, -+ MicrosoftKEK, sizeof MicrosoftKEK, &gEfiCallerIdGuid, -+ NULL); -+ if (EFI_ERROR (Status)) { -+ return 1; -+ } -+ -+ Status = EnrollListOfX509Certs ( -+ EFI_PLATFORM_KEY_NAME, -+ &gEfiGlobalVariableGuid, -+ ExampleCert, sizeof ExampleCert, &gEfiGlobalVariableGuid, -+ NULL); -+ if (EFI_ERROR (Status)) { -+ return 1; -+ } -+ -+ Settings.CustomMode = STANDARD_SECURE_BOOT_MODE; -+ Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, -+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, -+ sizeof Settings.CustomMode, &Settings.CustomMode); -+ if (EFI_ERROR (Status)) { -+ AsciiPrint ("error: SetVariable("%s", %g): %r\n", EFI_CUSTOM_MODE_NAME, -+ &gEfiCustomModeEnableGuid, Status); -+ return 1; -+ } -+ -+ Status = GetSettings (&Settings); -+ if (EFI_ERROR (Status)) { -+ return 1; -+ } -+ PrintSettings (&Settings); -+ -+ if (Settings.SetupMode != 0 || Settings.SecureBoot != 1 || -+ Settings.SecureBootEnable != 1 || Settings.CustomMode != 0 || -+ Settings.VendorKeys != 0) { -+ AsciiPrint ("error: unexpected\n"); -+ return 1; -+ } -+ -+ AsciiPrint ("info: success\n"); -+ return 0; -+} -diff --git a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf -new file mode 100644 -index 0000000..ac919bb ---- /dev/null -+++ b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf -@@ -0,0 +1,51 @@ -+## @file -+# Enroll default PK, KEK, DB. -+# -+# Copyright (C) 2014, Red Hat, Inc. -+# -+# 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. -+# -+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED. -+## -+ -+[Defines] -+ INF_VERSION = 0x00010006 -+ BASE_NAME = EnrollDefaultKeys -+ FILE_GUID = D5C1DF0B-1BAC-4EDF-BA48-08834009CA5A -+ MODULE_TYPE = UEFI_APPLICATION -+ VERSION_STRING = 0.1 -+ ENTRY_POINT = ShellCEntryLib -+ -+# -+# VALID_ARCHITECTURES = IA32 X64 -+# -+ -+[Sources] -+ EnrollDefaultKeys.c -+ -+[Packages] -+ MdePkg/MdePkg.dec -+ MdeModulePkg/MdeModulePkg.dec -+ SecurityPkg/SecurityPkg.dec -+ ShellPkg/ShellPkg.dec -+ -+[Guids] -+ gEfiCertPkcs7Guid -+ gEfiCertX509Guid -+ gEfiCustomModeEnableGuid -+ gEfiGlobalVariableGuid -+ gEfiImageSecurityDatabaseGuid -+ gEfiSecureBootEnableDisableGuid -+ -+[LibraryClasses] -+ BaseMemoryLib -+ DebugLib -+ MemoryAllocationLib -+ ShellCEntryLib -+ UefiLib -+ UefiRuntimeServicesTableLib -diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc -index 8af3267..6fb5c9c 100644 ---- a/OvmfPkg/OvmfPkgIa32.dsc -+++ b/OvmfPkg/OvmfPkgIa32.dsc -@@ -749,6 +749,10 @@ - - !if $(SECURE_BOOT_ENABLE) == TRUE - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf -+ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf { -+ <LibraryClasses> -+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf -+ } - !endif - - OvmfPkg/PlatformDxe/Platform.inf -diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc -index 4bb38d0..e5abaff 100644 ---- a/OvmfPkg/OvmfPkgIa32X64.dsc -+++ b/OvmfPkg/OvmfPkgIa32X64.dsc -@@ -758,6 +758,10 @@ - - !if $(SECURE_BOOT_ENABLE) == TRUE - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf -+ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf { -+ <LibraryClasses> -+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf -+ } - !endif - - OvmfPkg/PlatformDxe/Platform.inf -diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc -index be3aa1f..4c36a7d 100644 ---- a/OvmfPkg/OvmfPkgX64.dsc -+++ b/OvmfPkg/OvmfPkgX64.dsc -@@ -756,6 +756,10 @@ - - !if $(SECURE_BOOT_ENABLE) == TRUE - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf -+ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf { -+ <LibraryClasses> -+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf -+ } - !endif - - OvmfPkg/PlatformDxe/Platform.inf --- -1.8.3.1 - diff --git a/0008-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch b/0008-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch deleted file mode 100644 index 61aa133..0000000 --- a/0008-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch +++ /dev/null @@ -1,113 +0,0 @@ -From: Laszlo Ersek lersek@redhat.com -Date: Tue, 25 Feb 2014 18:40:35 +0100 -Subject: [PATCH] MdeModulePkg: TerminalDxe: add other text resolutions - -When the console output is multiplexed to several devices by -ConSplitterDxe, then ConSplitterDxe builds an intersection of text modes -supported by all console output devices. - -Two notable output devices are provided by: -(1) MdeModulePkg/Universal/Console/GraphicsConsoleDxe, -(2) MdeModulePkg/Universal/Console/TerminalDxe. - -GraphicsConsoleDxe supports four modes at most -- see -InitializeGraphicsConsoleTextMode(): - -(1a) 80x25 (required by the UEFI spec as mode 0), -(1b) 80x50 (not necessarily supported, but if it is, then the UEFI spec - requires the driver to provide it as mode 1), -(1c) 100x31 (corresponding to graphics resolution 800x600, which the UEFI - spec requires from all plug-in graphics devices), -(1d) "full screen" resolution, derived form the underlying GOP's - horizontal and vertical resolutions with division by EFI_GLYPH_WIDTH - (8) and EFI_GLYPH_HEIGHT (19), respectively. - -The automatic "full screen resolution" makes GraphicsConsoleDxe's -character console very flexible. However, TerminalDxe (which runs on -serial ports) only provides the following fixed resolutions -- see -InitializeTerminalConsoleTextMode(): - -(2a) 80x25 (required by the UEFI spec as mode 0), -(2b) 80x50 (since the character resolution of a serial device cannot be - interrogated easily, this is added unconditionally as mode 1) -(2c) modes 2 and above come from "mTerminalConsoleModeData". This table - currently only contains one mode, 100x31. - -When ConSplitterDxe combines (1) and (2), multiplexing console output to -both video output and serial terminal, the list of commonly supported text -modes (ie. the "intersection") comprises: - -(3a) 80x25, unconditionally, from (1a) and (2a), -(3b) 80x50, if the graphics console provides at least 640x950 pixel - resolution, from (1b) and (2b) -(3c) 100x31, if the graphics device is a plug-in one (because in that case - 800x600 is a mandated pixel resolution), from (1c) and (2c). - -Unfortunately, the "full screen resolution" (1d) of the GOP-based text -console is not available in general. - -Mitigate this problem by extending "mTerminalConsoleModeData" with a -handful of text resolutions that are derived from widespread maximal pixel -resolutions. This way TerminalDxe won't cause ConSplitterDxe to filter out -the most frequent (1d) values from the intersection, and eg. the MODE -command in the UEFI shell will offer the "best" (ie. full screen) -resolution too. - -Contributed-under: TianoCore Contribution Agreement 1.0 -Signed-off-by: Laszlo Ersek lersek@redhat.com ---- - .../Universal/Console/TerminalDxe/Terminal.c | 41 ++++++++++++++++++++-- - 1 file changed, 38 insertions(+), 3 deletions(-) - -diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c -index 5d55969..13620ac 100644 ---- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c -+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c -@@ -113,9 +113,44 @@ TERMINAL_DEV mTerminalDevTemplate = { - }; - - TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData[] = { -- {80, 25}, -- {80, 50}, -- {100, 31}, -+ { 80, 25 }, // from graphics resolution 640 x 480 -+ { 80, 50 }, // from graphics resolution 640 x 480 -+ { 100, 25 }, // from graphics resolution 800 x 480 -+ { 100, 31 }, // from graphics resolution 800 x 600 -+ { 104, 32 }, // from graphics resolution 832 x 624 -+ { 120, 33 }, // from graphics resolution 960 x 640 -+ { 128, 31 }, // from graphics resolution 1024 x 600 -+ { 128, 40 }, // from graphics resolution 1024 x 768 -+ { 144, 45 }, // from graphics resolution 1152 x 864 -+ { 144, 45 }, // from graphics resolution 1152 x 870 -+ { 160, 37 }, // from graphics resolution 1280 x 720 -+ { 160, 40 }, // from graphics resolution 1280 x 760 -+ { 160, 40 }, // from graphics resolution 1280 x 768 -+ { 160, 42 }, // from graphics resolution 1280 x 800 -+ { 160, 50 }, // from graphics resolution 1280 x 960 -+ { 160, 53 }, // from graphics resolution 1280 x 1024 -+ { 170, 40 }, // from graphics resolution 1360 x 768 -+ { 170, 40 }, // from graphics resolution 1366 x 768 -+ { 175, 55 }, // from graphics resolution 1400 x 1050 -+ { 180, 47 }, // from graphics resolution 1440 x 900 -+ { 200, 47 }, // from graphics resolution 1600 x 900 -+ { 200, 63 }, // from graphics resolution 1600 x 1200 -+ { 210, 55 }, // from graphics resolution 1680 x 1050 -+ { 240, 56 }, // from graphics resolution 1920 x 1080 -+ { 240, 63 }, // from graphics resolution 1920 x 1200 -+ { 240, 75 }, // from graphics resolution 1920 x 1440 -+ { 250, 105 }, // from graphics resolution 2000 x 2000 -+ { 256, 80 }, // from graphics resolution 2048 x 1536 -+ { 256, 107 }, // from graphics resolution 2048 x 2048 -+ { 320, 75 }, // from graphics resolution 2560 x 1440 -+ { 320, 84 }, // from graphics resolution 2560 x 1600 -+ { 320, 107 }, // from graphics resolution 2560 x 2048 -+ { 350, 110 }, // from graphics resolution 2800 x 2100 -+ { 400, 126 }, // from graphics resolution 3200 x 2400 -+ { 480, 113 }, // from graphics resolution 3840 x 2160 -+ { 512, 113 }, // from graphics resolution 4096 x 2160 -+ { 960, 227 }, // from graphics resolution 7680 x 4320 -+ { 1024, 227 }, // from graphics resolution 8192 x 4320 - // - // New modes can be added here. - // diff --git a/0008-MdeModulePkg-TerminalDxe-set-xterm-resolution-on-mod.patch b/0008-MdeModulePkg-TerminalDxe-set-xterm-resolution-on-mod.patch new file mode 100644 index 0000000..51edfae --- /dev/null +++ b/0008-MdeModulePkg-TerminalDxe-set-xterm-resolution-on-mod.patch @@ -0,0 +1,128 @@ +From f337eb3972afcccabe86fe663202a758337d0ab8 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Tue, 25 Feb 2014 22:40:01 +0100 +Subject: [PATCH] MdeModulePkg: TerminalDxe: set xterm resolution on mode + change (RH only) + +The + + CSI Ps ; Ps ; Ps t + +escape sequence serves for window manipulation. We can use the + + CSI 8 ; <rows> ; <columns> t + +sequence to adapt eg. the xterm window size to the selected console mode. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- refresh commit 519b9751573e against various context changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- Refresh downstream-only commit 2909e025db68 against "MdeModulePkg.dec" + context change from upstream commits e043f7895b83 ("MdeModulePkg: Add + PCD PcdPteMemoryEncryptionAddressOrMask", 2017-02-27) and 76081dfcc5b2 + ("MdeModulePkg: Add PROMPT&HELP string of pcd to UNI file", 2017-03-03). + +Reference: http://rtfm.etla.org/xterm/ctlseq.html +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 2909e025db6878723b49644a8a0cf160d07e6444) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + MdeModulePkg/MdeModulePkg.dec | 4 +++ + .../Console/TerminalDxe/TerminalConOut.c | 30 +++++++++++++++++++ + .../Console/TerminalDxe/TerminalDxe.inf | 2 ++ + 3 files changed, 36 insertions(+) + +diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec +index 6a6d9660ed..2dc1cf94e2 100644 +--- a/MdeModulePkg/MdeModulePkg.dec ++++ b/MdeModulePkg/MdeModulePkg.dec +@@ -1936,6 +1936,10 @@ + # @Prompt The address mask when memory encryption is enabled. + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0|UINT64|0x30001047 + ++ ## Controls whether TerminalDxe outputs an XTerm resize sequence on terminal ++ # mode change. ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm|FALSE|BOOLEAN|0x00010080 ++ + [PcdsPatchableInModule] + ## Specify memory size with page number for PEI code when + # Loading Module at Fixed Address feature is enabled. +diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c +index 4d7218e415..295e7641a5 100644 +--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c ++++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConOut.c +@@ -13,6 +13,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + **/ + ++#include <Library/PrintLib.h> ++ + #include "Terminal.h" + + // +@@ -86,6 +88,16 @@ CHAR16 mSetCursorPositionString[] = { ESC, '[', '0', '0', ';', '0', '0', 'H', 0 + CHAR16 mCursorForwardString[] = { ESC, '[', '0', '0', 'C', 0 }; + CHAR16 mCursorBackwardString[] = { ESC, '[', '0', '0', 'D', 0 }; + ++// ++// Note that this is an ASCII format string, taking two INT32 arguments: ++// rows, columns. ++// ++// A %d (INT32) format specification can expand to at most 11 characters. ++// ++CHAR8 mResizeTextAreaFormatString[] = "\x1B[8;%d;%dt"; ++#define RESIZE_SEQ_SIZE (sizeof mResizeTextAreaFormatString + 2 * (11 - 2)) ++ ++ + // + // Body of the ConOut functions + // +@@ -508,6 +520,24 @@ TerminalConOutSetMode ( + return EFI_DEVICE_ERROR; + } + ++ if (PcdGetBool (PcdResizeXterm)) { ++ CHAR16 ResizeSequence[RESIZE_SEQ_SIZE]; ++ ++ UnicodeSPrintAsciiFormat ( ++ ResizeSequence, ++ sizeof ResizeSequence, ++ mResizeTextAreaFormatString, ++ (INT32) TerminalDevice->TerminalConsoleModeData[ModeNumber].Rows, ++ (INT32) TerminalDevice->TerminalConsoleModeData[ModeNumber].Columns ++ ); ++ TerminalDevice->OutputEscChar = TRUE; ++ Status = This->OutputString (This, ResizeSequence); ++ TerminalDevice->OutputEscChar = FALSE; ++ if (EFI_ERROR (Status)) { ++ return EFI_DEVICE_ERROR; ++ } ++ } ++ + This->Mode->Mode = (INT32) ModeNumber; + + Status = This->ClearScreen (This); +diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +index 0780296798..bd2ba828a6 100644 +--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf ++++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +@@ -60,6 +60,7 @@ + DebugLib + PcdLib + BaseLib ++ PrintLib + + [Guids] + ## SOMETIMES_PRODUCES ## Variable:L"ConInDev" +@@ -88,6 +89,7 @@ + [Pcd] + gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable ## CONSUMES ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm ## CONSUMES + + # [Event] + # # Relative timer event set by UnicodeToEfiKey(), used to be one 2 seconds input timeout. diff --git a/0009-OvmfPkg-take-PcdResizeXterm-from-the-QEMU-command-li.patch b/0009-OvmfPkg-take-PcdResizeXterm-from-the-QEMU-command-li.patch new file mode 100644 index 0000000..0672e56 --- /dev/null +++ b/0009-OvmfPkg-take-PcdResizeXterm-from-the-QEMU-command-li.patch @@ -0,0 +1,90 @@ +From 30251344cfbd25212394c377b80cd720a3b85d46 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 14 Oct 2015 15:59:06 +0200 +Subject: [PATCH] OvmfPkg: take PcdResizeXterm from the QEMU command line (RH + only) + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- refresh downstream-only commit 8abc2a6ddad2 against context differences + in the DSC files from upstream commit 5e167d7e784c + ("OvmfPkg/PlatformPei: don't allocate reserved mem varstore if + SMM_REQUIRE", 2017-03-12). + +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 6fa0c4d67c0bb8bde2ddd6db41c19eb0c40b2721) +(cherry picked from commit 8abc2a6ddad25af7e88dc0cf57d55dfb75fbf92d) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + OvmfPkg/OvmfPkgIa32.dsc | 1 + + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + + OvmfPkg/OvmfPkgX64.dsc | 1 + + OvmfPkg/PlatformPei/Platform.c | 1 + + OvmfPkg/PlatformPei/PlatformPei.inf | 1 + + 5 files changed, 5 insertions(+) + +diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc +index 0a49336c0d..8dc3ad2be4 100644 +--- a/OvmfPkg/OvmfPkgIa32.dsc ++++ b/OvmfPkg/OvmfPkgIa32.dsc +@@ -535,6 +535,7 @@ + # ($(SMM_REQUIRE) == FALSE) + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 + ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0 +diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc +index a3d51ef0f7..d81cd865d5 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -541,6 +541,7 @@ + # ($(SMM_REQUIRE) == FALSE) + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 + ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0 +diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc +index f9b4ab4dfa..85bd8d4bf6 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -540,6 +540,7 @@ + # ($(SMM_REQUIRE) == FALSE) + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 + ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0 +diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c +index 5a78668126..544ac547bf 100644 +--- a/OvmfPkg/PlatformPei/Platform.c ++++ b/OvmfPkg/PlatformPei/Platform.c +@@ -670,6 +670,7 @@ InitializePlatform ( + PeiFvInitialization (); + MemMapInitialization (); + NoexecDxeInitialization (); ++ UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdResizeXterm); + } + + AmdSevInitialize (); +diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf +index 9c5ad9961c..31baaa0a22 100644 +--- a/OvmfPkg/PlatformPei/PlatformPei.inf ++++ b/OvmfPkg/PlatformPei/PlatformPei.inf +@@ -94,6 +94,7 @@ + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack diff --git a/0009-Tweak-the-tools_def-to-support-cross-compiling.patch b/0009-Tweak-the-tools_def-to-support-cross-compiling.patch deleted file mode 100644 index a9b8dfb..0000000 --- a/0009-Tweak-the-tools_def-to-support-cross-compiling.patch +++ /dev/null @@ -1,515 +0,0 @@ -From 63b708ccad8afd0b887258888a53fd4945cff682 Mon Sep 17 00:00:00 2001 -Message-Id: 63b708ccad8afd0b887258888a53fd4945cff682.1478467625.git.crobinso@redhat.com -From: Paolo Bonzini pbonzini@redhat.com -Date: Sun, 6 Nov 2016 13:50:31 -0500 -Subject: [PATCH] Tweak the tools_def to support cross-compiling. - -These files are meant for customization, so this is not upstream. ---- - BaseTools/Conf/tools_def.template | 343 ++++++++++++++++++-------------------- - 1 file changed, 161 insertions(+), 182 deletions(-) - -diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template -index 39fda78..97f5557 100755 ---- a/BaseTools/Conf/tools_def.template -+++ b/BaseTools/Conf/tools_def.template -@@ -178,27 +178,6 @@ DEFINE CYGWIN_BINIA32 = c:/cygwin/opt/tiano/i386-tiano-pe/i386-tiano-pe - DEFINE CYGWIN_BINX64 = c:/cygwin/opt/tiano/x86_64-pc-mingw64/x86_64-pc-mingw64/bin/ - DEFINE CYGWIN_BINIPF = c:/cygwin/opt/tiano/gcc/ipf/bin/ia64-pc-elf- - --DEFINE GCC44_IA32_PREFIX = ENV(GCC44_BIN) --DEFINE GCC44_X64_PREFIX = ENV(GCC44_BIN) -- --DEFINE GCC45_IA32_PREFIX = ENV(GCC45_BIN) --DEFINE GCC45_X64_PREFIX = ENV(GCC45_BIN) -- --DEFINE GCC46_IA32_PREFIX = ENV(GCC46_BIN) --DEFINE GCC46_X64_PREFIX = ENV(GCC46_BIN) -- --DEFINE GCC47_IA32_PREFIX = ENV(GCC47_BIN) --DEFINE GCC47_X64_PREFIX = ENV(GCC47_BIN) -- --DEFINE GCC48_IA32_PREFIX = ENV(GCC48_BIN) --DEFINE GCC48_X64_PREFIX = ENV(GCC48_BIN) -- --DEFINE GCC49_IA32_PREFIX = ENV(GCC49_BIN) --DEFINE GCC49_X64_PREFIX = ENV(GCC49_BIN) -- --DEFINE GCC5_IA32_PREFIX = ENV(GCC5_BIN) --DEFINE GCC5_X64_PREFIX = ENV(GCC5_BIN) -- - DEFINE UNIX_IASL_BIN = ENV(IASL_PREFIX)iasl - DEFINE WIN_IASL_BIN = ENV(IASL_PREFIX)iasl.exe - DEFINE WIN_ASL_BIN = ENV(IASL_PREFIX)asl.exe -@@ -4590,7 +4569,7 @@ DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS) - #################################################################################### - *_GCC44_*_*_FAMILY = GCC - --*_GCC44_*_MAKE_PATH = DEF(GCC44_IA32_PREFIX)make -+*_GCC44_*_MAKE_PATH = make - *_GCC44_*_*_DLL = ENV(GCC44_DLL) - *_GCC44_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -@@ -4605,17 +4584,17 @@ DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS) - ################## - # GCC44 IA32 definitions - ################## --*_GCC44_IA32_OBJCOPY_PATH = DEF(GCC44_IA32_PREFIX)objcopy --*_GCC44_IA32_CC_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_SLINK_PATH = DEF(GCC44_IA32_PREFIX)ar --*_GCC44_IA32_DLINK_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_ASLDLINK_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_ASM_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_PP_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_VFRPP_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_ASLCC_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_ASLPP_PATH = DEF(GCC44_IA32_PREFIX)gcc --*_GCC44_IA32_RC_PATH = DEF(GCC44_IA32_PREFIX)objcopy -+*_GCC44_IA32_OBJCOPY_PATH = ENV(GCC44_IA32_PREFIX)objcopy -+*_GCC44_IA32_CC_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_SLINK_PATH = ENV(GCC44_IA32_PREFIX)ar -+*_GCC44_IA32_DLINK_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_ASLDLINK_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_ASM_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_PP_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_VFRPP_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_ASLCC_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_ASLPP_PATH = ENV(GCC44_IA32_PREFIX)gcc -+*_GCC44_IA32_RC_PATH = ENV(GCC44_IA32_PREFIX)objcopy - - *_GCC44_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 - *_GCC44_IA32_ASLDLINK_FLAGS = DEF(GCC44_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -@@ -4633,17 +4612,17 @@ RELEASE_GCC44_IA32_CC_FLAGS = DEF(GCC44_IA32_CC_FLAGS) -Os - ################## - # GCC44 X64 definitions - ################## --*_GCC44_X64_OBJCOPY_PATH = DEF(GCC44_X64_PREFIX)objcopy --*_GCC44_X64_CC_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_SLINK_PATH = DEF(GCC44_X64_PREFIX)ar --*_GCC44_X64_DLINK_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_ASLDLINK_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_ASM_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_PP_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_VFRPP_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_ASLCC_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_ASLPP_PATH = DEF(GCC44_X64_PREFIX)gcc --*_GCC44_X64_RC_PATH = DEF(GCC44_X64_PREFIX)objcopy -+*_GCC44_X64_OBJCOPY_PATH = ENV(GCC44_X64_PREFIX)objcopy -+*_GCC44_X64_CC_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_SLINK_PATH = ENV(GCC44_X64_PREFIX)ar -+*_GCC44_X64_DLINK_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_ASLDLINK_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_ASM_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_PP_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_VFRPP_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_ASLCC_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_ASLPP_PATH = ENV(GCC44_X64_PREFIX)gcc -+*_GCC44_X64_RC_PATH = ENV(GCC44_X64_PREFIX)objcopy - - *_GCC44_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 - *_GCC44_X64_ASLDLINK_FLAGS = DEF(GCC44_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -@@ -4666,7 +4645,7 @@ RELEASE_GCC44_X64_CC_FLAGS = DEF(GCC44_X64_CC_FLAGS) -Os - #################################################################################### - *_GCC45_*_*_FAMILY = GCC - --*_GCC45_*_MAKE_PATH = DEF(GCC45_IA32_PREFIX)make -+*_GCC45_*_MAKE_PATH = make - *_GCC45_*_*_DLL = ENV(GCC45_DLL) - *_GCC45_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -@@ -4681,17 +4660,17 @@ RELEASE_GCC44_X64_CC_FLAGS = DEF(GCC44_X64_CC_FLAGS) -Os - ################## - # GCC45 IA32 definitions - ################## --*_GCC45_IA32_OBJCOPY_PATH = DEF(GCC45_IA32_PREFIX)objcopy --*_GCC45_IA32_CC_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_SLINK_PATH = DEF(GCC45_IA32_PREFIX)ar --*_GCC45_IA32_DLINK_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_ASLDLINK_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_ASM_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_PP_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_VFRPP_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_ASLCC_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_ASLPP_PATH = DEF(GCC45_IA32_PREFIX)gcc --*_GCC45_IA32_RC_PATH = DEF(GCC45_IA32_PREFIX)objcopy -+*_GCC45_IA32_OBJCOPY_PATH = ENV(GCC45_IA32_PREFIX)objcopy -+*_GCC45_IA32_CC_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_SLINK_PATH = ENV(GCC45_IA32_PREFIX)ar -+*_GCC45_IA32_DLINK_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_ASLDLINK_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_ASM_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_PP_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_VFRPP_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_ASLCC_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_ASLPP_PATH = ENV(GCC45_IA32_PREFIX)gcc -+*_GCC45_IA32_RC_PATH = ENV(GCC45_IA32_PREFIX)objcopy - - *_GCC45_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 - *_GCC45_IA32_ASLDLINK_FLAGS = DEF(GCC45_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -@@ -4709,17 +4688,17 @@ RELEASE_GCC45_IA32_CC_FLAGS = DEF(GCC45_IA32_CC_FLAGS) -Os - ################## - # GCC45 X64 definitions - ################## --*_GCC45_X64_OBJCOPY_PATH = DEF(GCC45_X64_PREFIX)objcopy --*_GCC45_X64_CC_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_SLINK_PATH = DEF(GCC45_X64_PREFIX)ar --*_GCC45_X64_DLINK_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_ASLDLINK_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_ASM_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_PP_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_VFRPP_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_ASLCC_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_ASLPP_PATH = DEF(GCC45_X64_PREFIX)gcc --*_GCC45_X64_RC_PATH = DEF(GCC45_X64_PREFIX)objcopy -+*_GCC45_X64_OBJCOPY_PATH = ENV(GCC45_X64_PREFIX)objcopy -+*_GCC45_X64_CC_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_SLINK_PATH = ENV(GCC45_X64_PREFIX)ar -+*_GCC45_X64_DLINK_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_ASLDLINK_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_ASM_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_PP_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_VFRPP_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_ASLCC_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_ASLPP_PATH = ENV(GCC45_X64_PREFIX)gcc -+*_GCC45_X64_RC_PATH = ENV(GCC45_X64_PREFIX)objcopy - - *_GCC45_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 - *_GCC45_X64_ASLDLINK_FLAGS = DEF(GCC45_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -@@ -4742,7 +4721,7 @@ RELEASE_GCC45_X64_CC_FLAGS = DEF(GCC45_X64_CC_FLAGS) -Os - #################################################################################### - *_GCC46_*_*_FAMILY = GCC - --*_GCC46_*_MAKE_PATH = DEF(GCC46_IA32_PREFIX)make -+*_GCC46_*_MAKE_PATH = make - *_GCC46_*_*_DLL = ENV(GCC46_DLL) - *_GCC46_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -@@ -4757,17 +4736,17 @@ RELEASE_GCC45_X64_CC_FLAGS = DEF(GCC45_X64_CC_FLAGS) -Os - ################## - # GCC46 IA32 definitions - ################## --*_GCC46_IA32_OBJCOPY_PATH = DEF(GCC46_IA32_PREFIX)objcopy --*_GCC46_IA32_CC_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_SLINK_PATH = DEF(GCC46_IA32_PREFIX)ar --*_GCC46_IA32_DLINK_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_ASLDLINK_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_ASM_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_PP_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_VFRPP_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_ASLCC_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_ASLPP_PATH = DEF(GCC46_IA32_PREFIX)gcc --*_GCC46_IA32_RC_PATH = DEF(GCC46_IA32_PREFIX)objcopy -+*_GCC46_IA32_OBJCOPY_PATH = ENV(GCC46_IA32_PREFIX)objcopy -+*_GCC46_IA32_CC_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_SLINK_PATH = ENV(GCC46_IA32_PREFIX)ar -+*_GCC46_IA32_DLINK_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_ASLDLINK_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_ASM_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_PP_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_VFRPP_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_ASLCC_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_ASLPP_PATH = ENV(GCC46_IA32_PREFIX)gcc -+*_GCC46_IA32_RC_PATH = ENV(GCC46_IA32_PREFIX)objcopy - - *_GCC46_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 - *_GCC46_IA32_ASLDLINK_FLAGS = DEF(GCC46_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -@@ -4785,17 +4764,17 @@ RELEASE_GCC46_IA32_CC_FLAGS = DEF(GCC46_IA32_CC_FLAGS) -Os -Wno-unused-but - ################## - # GCC46 X64 definitions - ################## --*_GCC46_X64_OBJCOPY_PATH = DEF(GCC46_X64_PREFIX)objcopy --*_GCC46_X64_CC_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_SLINK_PATH = DEF(GCC46_X64_PREFIX)ar --*_GCC46_X64_DLINK_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_ASLDLINK_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_ASM_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_PP_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_VFRPP_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_ASLCC_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_ASLPP_PATH = DEF(GCC46_X64_PREFIX)gcc --*_GCC46_X64_RC_PATH = DEF(GCC46_X64_PREFIX)objcopy -+*_GCC46_X64_OBJCOPY_PATH = ENV(GCC46_X64_PREFIX)objcopy -+*_GCC46_X64_CC_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_SLINK_PATH = ENV(GCC46_X64_PREFIX)ar -+*_GCC46_X64_DLINK_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_ASLDLINK_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_ASM_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_PP_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_VFRPP_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_ASLCC_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_ASLPP_PATH = ENV(GCC46_X64_PREFIX)gcc -+*_GCC46_X64_RC_PATH = ENV(GCC46_X64_PREFIX)objcopy - - *_GCC46_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 - *_GCC46_X64_ASLDLINK_FLAGS = DEF(GCC46_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -@@ -4851,7 +4830,7 @@ RELEASE_GCC46_ARM_CC_FLAGS = DEF(GCC46_ARM_CC_FLAGS) -Wno-unused-but-set-v - #################################################################################### - *_GCC47_*_*_FAMILY = GCC - --*_GCC47_*_MAKE_PATH = DEF(GCC47_IA32_PREFIX)make -+*_GCC47_*_MAKE_PATH = make - *_GCC47_*_*_DLL = ENV(GCC47_DLL) - *_GCC47_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -@@ -4866,17 +4845,17 @@ RELEASE_GCC46_ARM_CC_FLAGS = DEF(GCC46_ARM_CC_FLAGS) -Wno-unused-but-set-v - ################## - # GCC47 IA32 definitions - ################## --*_GCC47_IA32_OBJCOPY_PATH = DEF(GCC47_IA32_PREFIX)objcopy --*_GCC47_IA32_CC_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_SLINK_PATH = DEF(GCC47_IA32_PREFIX)ar --*_GCC47_IA32_DLINK_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_ASLDLINK_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_ASM_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_PP_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_VFRPP_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_ASLCC_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_ASLPP_PATH = DEF(GCC47_IA32_PREFIX)gcc --*_GCC47_IA32_RC_PATH = DEF(GCC47_IA32_PREFIX)objcopy -+*_GCC47_IA32_OBJCOPY_PATH = ENV(GCC47_IA32_PREFIX)objcopy -+*_GCC47_IA32_CC_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_SLINK_PATH = ENV(GCC47_IA32_PREFIX)ar -+*_GCC47_IA32_DLINK_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_ASLDLINK_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_ASM_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_PP_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_VFRPP_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_ASLCC_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_ASLPP_PATH = ENV(GCC47_IA32_PREFIX)gcc -+*_GCC47_IA32_RC_PATH = ENV(GCC47_IA32_PREFIX)objcopy - - *_GCC47_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 - *_GCC47_IA32_ASLDLINK_FLAGS = DEF(GCC47_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -@@ -4894,17 +4873,17 @@ RELEASE_GCC47_IA32_CC_FLAGS = DEF(GCC47_IA32_CC_FLAGS) -Os -Wno-unused-but - ################## - # GCC47 X64 definitions - ################## --*_GCC47_X64_OBJCOPY_PATH = DEF(GCC47_X64_PREFIX)objcopy --*_GCC47_X64_CC_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_SLINK_PATH = DEF(GCC47_X64_PREFIX)ar --*_GCC47_X64_DLINK_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_ASLDLINK_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_ASM_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_PP_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_VFRPP_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_ASLCC_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_ASLPP_PATH = DEF(GCC47_X64_PREFIX)gcc --*_GCC47_X64_RC_PATH = DEF(GCC47_X64_PREFIX)objcopy -+*_GCC47_X64_OBJCOPY_PATH = ENV(GCC47_X64_PREFIX)objcopy -+*_GCC47_X64_CC_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_SLINK_PATH = ENV(GCC47_X64_PREFIX)ar -+*_GCC47_X64_DLINK_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_ASLDLINK_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_ASM_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_PP_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_VFRPP_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_ASLCC_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_ASLPP_PATH = ENV(GCC47_X64_PREFIX)gcc -+*_GCC47_X64_RC_PATH = ENV(GCC47_X64_PREFIX)objcopy - - *_GCC47_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 - *_GCC47_X64_ASLDLINK_FLAGS = DEF(GCC47_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -@@ -4988,7 +4967,7 @@ RELEASE_GCC47_AARCH64_CC_FLAGS = DEF(GCC47_AARCH64_CC_FLAGS) -Wno-unused-but-s - #################################################################################### - *_GCC48_*_*_FAMILY = GCC - --*_GCC48_*_MAKE_PATH = DEF(GCC48_IA32_PREFIX)make -+*_GCC48_*_MAKE_PATH = make - *_GCC48_*_*_DLL = ENV(GCC48_DLL) - *_GCC48_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -@@ -5003,17 +4982,17 @@ RELEASE_GCC47_AARCH64_CC_FLAGS = DEF(GCC47_AARCH64_CC_FLAGS) -Wno-unused-but-s - ################## - # GCC48 IA32 definitions - ################## --*_GCC48_IA32_OBJCOPY_PATH = DEF(GCC48_IA32_PREFIX)objcopy --*_GCC48_IA32_CC_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_SLINK_PATH = DEF(GCC48_IA32_PREFIX)ar --*_GCC48_IA32_DLINK_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_ASLDLINK_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_ASM_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_PP_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_VFRPP_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_ASLCC_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_ASLPP_PATH = DEF(GCC48_IA32_PREFIX)gcc --*_GCC48_IA32_RC_PATH = DEF(GCC48_IA32_PREFIX)objcopy -+*_GCC48_IA32_OBJCOPY_PATH = ENV(GCC48_IA32_PREFIX)objcopy -+*_GCC48_IA32_CC_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_SLINK_PATH = ENV(GCC48_IA32_PREFIX)ar -+*_GCC48_IA32_DLINK_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_ASLDLINK_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_ASM_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_PP_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_VFRPP_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_ASLCC_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_ASLPP_PATH = ENV(GCC48_IA32_PREFIX)gcc -+*_GCC48_IA32_RC_PATH = ENV(GCC48_IA32_PREFIX)objcopy - - *_GCC48_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 - *_GCC48_IA32_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -@@ -5031,17 +5010,17 @@ RELEASE_GCC48_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -Os -Wno-unused-but - ################## - # GCC48 X64 definitions - ################## --*_GCC48_X64_OBJCOPY_PATH = DEF(GCC48_X64_PREFIX)objcopy --*_GCC48_X64_CC_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_SLINK_PATH = DEF(GCC48_X64_PREFIX)ar --*_GCC48_X64_DLINK_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_ASLDLINK_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_ASM_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_PP_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_VFRPP_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_ASLCC_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_ASLPP_PATH = DEF(GCC48_X64_PREFIX)gcc --*_GCC48_X64_RC_PATH = DEF(GCC48_X64_PREFIX)objcopy -+*_GCC48_X64_OBJCOPY_PATH = ENV(GCC48_X64_PREFIX)objcopy -+*_GCC48_X64_CC_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_SLINK_PATH = ENV(GCC48_X64_PREFIX)ar -+*_GCC48_X64_DLINK_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_ASLDLINK_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_ASM_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_PP_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_VFRPP_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_ASLCC_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_ASLPP_PATH = ENV(GCC48_X64_PREFIX)gcc -+*_GCC48_X64_RC_PATH = ENV(GCC48_X64_PREFIX)objcopy - - *_GCC48_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 - *_GCC48_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -@@ -5125,7 +5104,7 @@ RELEASE_GCC48_AARCH64_CC_FLAGS = DEF(GCC48_AARCH64_CC_FLAGS) -Wno-unused-but-s - #################################################################################### - *_GCC49_*_*_FAMILY = GCC - --*_GCC49_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make -+*_GCC49_*_MAKE_PATH = make - *_GCC49_*_*_DLL = ENV(GCC49_DLL) - *_GCC49_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -@@ -5140,17 +5119,17 @@ RELEASE_GCC48_AARCH64_CC_FLAGS = DEF(GCC48_AARCH64_CC_FLAGS) -Wno-unused-but-s - ################## - # GCC49 IA32 definitions - ################## --*_GCC49_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy --*_GCC49_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)ar --*_GCC49_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc --*_GCC49_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy -+*_GCC49_IA32_OBJCOPY_PATH = ENV(GCC49_IA32_PREFIX)objcopy -+*_GCC49_IA32_CC_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_SLINK_PATH = ENV(GCC49_IA32_PREFIX)ar -+*_GCC49_IA32_DLINK_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_ASLDLINK_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_ASM_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_PP_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_VFRPP_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_ASLCC_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_ASLPP_PATH = ENV(GCC49_IA32_PREFIX)gcc -+*_GCC49_IA32_RC_PATH = ENV(GCC49_IA32_PREFIX)objcopy - - *_GCC49_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 - *_GCC49_IA32_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -@@ -5168,17 +5147,17 @@ RELEASE_GCC49_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -Os -Wno-unused-but - ################## - # GCC49 X64 definitions - ################## --*_GCC49_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy --*_GCC49_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)ar --*_GCC49_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc --*_GCC49_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy -+*_GCC49_X64_OBJCOPY_PATH = ENV(GCC49_X64_PREFIX)objcopy -+*_GCC49_X64_CC_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_SLINK_PATH = ENV(GCC49_X64_PREFIX)ar -+*_GCC49_X64_DLINK_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_ASLDLINK_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_ASM_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_PP_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_VFRPP_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_ASLCC_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_ASLPP_PATH = ENV(GCC49_X64_PREFIX)gcc -+*_GCC49_X64_RC_PATH = ENV(GCC49_X64_PREFIX)objcopy - - *_GCC49_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 - *_GCC49_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -@@ -5268,7 +5247,7 @@ RELEASE_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) - #################################################################################### - *_GCC5_*_*_FAMILY = GCC - --*_GCC5_*_MAKE_PATH = DEF(GCC5_IA32_PREFIX)make -+*_GCC5_*_MAKE_PATH = make - *_GCC5_*_*_DLL = ENV(GCC5_DLL) - *_GCC5_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -@@ -5283,17 +5262,17 @@ RELEASE_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) - ################## - # GCC5 IA32 definitions - ################## --*_GCC5_IA32_OBJCOPY_PATH = DEF(GCC5_IA32_PREFIX)objcopy --*_GCC5_IA32_CC_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_SLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc-ar --*_GCC5_IA32_DLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_ASLDLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_ASM_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_PP_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_VFRPP_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_ASLCC_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_ASLPP_PATH = DEF(GCC5_IA32_PREFIX)gcc --*_GCC5_IA32_RC_PATH = DEF(GCC5_IA32_PREFIX)objcopy -+*_GCC5_IA32_OBJCOPY_PATH = ENV(GCC5_IA32_PREFIX)objcopy -+*_GCC5_IA32_CC_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_SLINK_PATH = ENV(GCC5_IA32_PREFIX)gcc-ar -+*_GCC5_IA32_DLINK_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_ASLDLINK_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_ASM_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_PP_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_VFRPP_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_ASLCC_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_ASLPP_PATH = ENV(GCC5_IA32_PREFIX)gcc -+*_GCC5_IA32_RC_PATH = ENV(GCC5_IA32_PREFIX)objcopy - - *_GCC5_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 -fno-lto - *_GCC5_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -@@ -5315,17 +5294,17 @@ RELEASE_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl, - ################## - # GCC5 X64 definitions - ################## --*_GCC5_X64_OBJCOPY_PATH = DEF(GCC5_X64_PREFIX)objcopy --*_GCC5_X64_CC_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_SLINK_PATH = DEF(GCC5_X64_PREFIX)gcc-ar --*_GCC5_X64_DLINK_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_ASLDLINK_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_ASM_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_PP_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_VFRPP_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_ASLCC_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_ASLPP_PATH = DEF(GCC5_X64_PREFIX)gcc --*_GCC5_X64_RC_PATH = DEF(GCC5_X64_PREFIX)objcopy -+*_GCC5_X64_OBJCOPY_PATH = ENV(GCC5_X64_PREFIX)objcopy -+*_GCC5_X64_CC_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_SLINK_PATH = ENV(GCC5_X64_PREFIX)gcc-ar -+*_GCC5_X64_DLINK_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_ASLDLINK_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_ASM_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_PP_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_VFRPP_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_ASLCC_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_ASLPP_PATH = ENV(GCC5_X64_PREFIX)gcc -+*_GCC5_X64_RC_PATH = ENV(GCC5_X64_PREFIX)objcopy - - *_GCC5_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 -fno-lto - *_GCC5_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 --- -2.9.3 - diff --git a/0010-ArmVirtPkg-QemuFwCfgLib-allow-UEFI_DRIVER-client-mod.patch b/0010-ArmVirtPkg-QemuFwCfgLib-allow-UEFI_DRIVER-client-mod.patch new file mode 100644 index 0000000..a29a8bc --- /dev/null +++ b/0010-ArmVirtPkg-QemuFwCfgLib-allow-UEFI_DRIVER-client-mod.patch @@ -0,0 +1,36 @@ +From 92f37a3d72213d9b76bc47c4f194f2ea989a71a1 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Tue, 12 Apr 2016 20:50:25 +0200 +Subject: [PATCH] ArmVirtPkg: QemuFwCfgLib: allow UEFI_DRIVER client modules + (RH only) + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 8e2153358aa2bba2c91faa87a70beadcaae03fd8) +(cherry picked from commit 5af259a93f4bbee5515ae18638068125e170f2cd) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf +index eff4a21650..adf1ff6c6a 100644 +--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf ++++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf +@@ -22,7 +22,7 @@ + FILE_GUID = B271F41F-B841-48A9-BA8D-545B4BC2E2BF + MODULE_TYPE = BASE + VERSION_STRING = 1.0 +- LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER ++ LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER UEFI_DRIVER + + CONSTRUCTOR = QemuFwCfgInitialize + diff --git a/0010-VfrCompile-fix-invalid-comparison-between-pointer-an.patch b/0010-VfrCompile-fix-invalid-comparison-between-pointer-an.patch deleted file mode 100644 index 21a345a..0000000 --- a/0010-VfrCompile-fix-invalid-comparison-between-pointer-an.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 06c3814868bebbe7f2cd9a51c11fbfc407c14349 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini pbonzini@redhat.com -Date: Mon, 13 Feb 2017 13:49:14 +0100 -Subject: [PATCH] VfrCompile: fix invalid comparison between pointer and - integer - -This would be valid C but is not valid C++, so change the comparison -to do what it has always been doing. - -Signed-off-by: Paolo Bonzini pbonzini@redhat.com ---- - BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp -index 3ca57ed..2f97975 100644 ---- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp -+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp -@@ -3372,7 +3372,7 @@ CVfrStringDB::GetVarStoreNameFormStringId ( - UINT8 BlockType; - EFI_HII_STRING_PACKAGE_HDR *PkgHeader; - -- if (mStringFileName == '\0' ) { -+ if (mStringFileName == NULL) { - return NULL; - } - --- -2.9.3 - diff --git a/0011-ArmVirtPkg-take-PcdResizeXterm-from-the-QEMU-command.patch b/0011-ArmVirtPkg-take-PcdResizeXterm-from-the-QEMU-command.patch new file mode 100644 index 0000000..6d7967e --- /dev/null +++ b/0011-ArmVirtPkg-take-PcdResizeXterm-from-the-QEMU-command.patch @@ -0,0 +1,197 @@ +From 6a27daa40698f06a34c209bd90092011d70f7795 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Sun, 26 Jul 2015 08:02:50 +0000 +Subject: [PATCH] ArmVirtPkg: take PcdResizeXterm from the QEMU command line + (RH only) + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- Adapt commit 6b97969096a3 to the fact that upstream has deprecated such + setter functions for dynamic PCDs that don't return a status code (such + as PcdSetBool()). Employ PcdSetBoolS(), and assert that it succeeds -- + there's really no circumstance in this case when it could fail. + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- Refresh downstream-only commit d4564d39dfdb against context changes in + "ArmVirtPkg/ArmVirtQemu.dsc" from upstream commit 7e5f1b673870 + ("ArmVirtPkg/PlatformHasAcpiDtDxe: allow guest level ACPI disable + override", 2017-03-29). + +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit d4564d39dfdbf74e762af43314005a2c026cb262) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + ArmVirtPkg/ArmVirtQemu.dsc | 7 +- + .../TerminalPcdProducerLib.c | 87 +++++++++++++++++++ + .../TerminalPcdProducerLib.inf | 41 +++++++++ + 3 files changed, 134 insertions(+), 1 deletion(-) + create mode 100644 ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.c + create mode 100644 ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.inf + +diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc +index a7a3899560..86d5d5a666 100644 +--- a/ArmVirtPkg/ArmVirtQemu.dsc ++++ b/ArmVirtPkg/ArmVirtQemu.dsc +@@ -206,6 +206,8 @@ + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 + gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE + ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm|FALSE ++ + [PcdsDynamicHii] + gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS + +@@ -282,7 +284,10 @@ + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf +- MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf ++ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf { ++ <LibraryClasses> ++ NULL|ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.inf ++ } + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +diff --git a/ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.c b/ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.c +new file mode 100644 +index 0000000000..814ad48199 +--- /dev/null ++++ b/ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.c +@@ -0,0 +1,87 @@ ++/** @file ++* Plugin library for setting up dynamic PCDs for TerminalDxe, from fw_cfg ++* ++* Copyright (C) 2015-2016, Red Hat, Inc. ++* Copyright (c) 2014, Linaro Ltd. 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 <Library/DebugLib.h> ++#include <Library/PcdLib.h> ++#include <Library/QemuFwCfgLib.h> ++ ++STATIC ++RETURN_STATUS ++GetNamedFwCfgBoolean ( ++ IN CONST CHAR8 *FwCfgFileName, ++ OUT BOOLEAN *Setting ++ ) ++{ ++ RETURN_STATUS Status; ++ FIRMWARE_CONFIG_ITEM FwCfgItem; ++ UINTN FwCfgSize; ++ UINT8 Value[3]; ++ ++ Status = QemuFwCfgFindFile (FwCfgFileName, &FwCfgItem, &FwCfgSize); ++ if (RETURN_ERROR (Status)) { ++ return Status; ++ } ++ if (FwCfgSize > sizeof Value) { ++ return RETURN_BAD_BUFFER_SIZE; ++ } ++ QemuFwCfgSelectItem (FwCfgItem); ++ QemuFwCfgReadBytes (FwCfgSize, Value); ++ ++ if ((FwCfgSize == 1) || ++ (FwCfgSize == 2 && Value[1] == '\n') || ++ (FwCfgSize == 3 && Value[1] == '\r' && Value[2] == '\n')) { ++ switch (Value[0]) { ++ case '0': ++ case 'n': ++ case 'N': ++ *Setting = FALSE; ++ return RETURN_SUCCESS; ++ ++ case '1': ++ case 'y': ++ case 'Y': ++ *Setting = TRUE; ++ return RETURN_SUCCESS; ++ ++ default: ++ break; ++ } ++ } ++ return RETURN_PROTOCOL_ERROR; ++} ++ ++#define UPDATE_BOOLEAN_PCD_FROM_FW_CFG(TokenName) \ ++ do { \ ++ BOOLEAN Setting; \ ++ RETURN_STATUS PcdStatus; \ ++ \ ++ if (!RETURN_ERROR (GetNamedFwCfgBoolean ( \ ++ "opt/org.tianocore.edk2.aavmf/" #TokenName, &Setting))) { \ ++ PcdStatus = PcdSetBoolS (TokenName, Setting); \ ++ ASSERT_RETURN_ERROR (PcdStatus); \ ++ } \ ++ } while (0) ++ ++RETURN_STATUS ++EFIAPI ++TerminalPcdProducerLibConstructor ( ++ VOID ++ ) ++{ ++ UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdResizeXterm); ++ return RETURN_SUCCESS; ++} +diff --git a/ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.inf b/ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.inf +new file mode 100644 +index 0000000000..fecb37bcdf +--- /dev/null ++++ b/ArmVirtPkg/Library/TerminalPcdProducerLib/TerminalPcdProducerLib.inf +@@ -0,0 +1,41 @@ ++## @file ++# Plugin library for setting up dynamic PCDs for TerminalDxe, from fw_cfg ++# ++# Copyright (C) 2015-2016, Red Hat, Inc. ++# Copyright (c) 2014, Linaro Ltd. 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. ++# ++## ++ ++[Defines] ++ INF_VERSION = 0x00010005 ++ BASE_NAME = TerminalPcdProducerLib ++ FILE_GUID = 4a0c5ed7-8c42-4c01-8f4c-7bf258316a96 ++ MODULE_TYPE = BASE ++ VERSION_STRING = 1.0 ++ LIBRARY_CLASS = TerminalPcdProducerLib|DXE_DRIVER ++ CONSTRUCTOR = TerminalPcdProducerLibConstructor ++ ++[Sources] ++ TerminalPcdProducerLib.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ OvmfPkg/OvmfPkg.dec ++ MdeModulePkg/MdeModulePkg.dec ++ ++[LibraryClasses] ++ DebugLib ++ PcdLib ++ QemuFwCfgLib ++ ++[Pcd] ++ gEfiMdeModulePkgTokenSpaceGuid.PcdResizeXterm diff --git a/0012-OvmfPkg-allow-exclusion-of-the-shell-from-the-firmwa.patch b/0012-OvmfPkg-allow-exclusion-of-the-shell-from-the-firmwa.patch new file mode 100644 index 0000000..0a4b6e3 --- /dev/null +++ b/0012-OvmfPkg-allow-exclusion-of-the-shell-from-the-firmwa.patch @@ -0,0 +1,113 @@ +From 84570add9731d2099c6e5be43f96aed508fd4c39 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Tue, 4 Nov 2014 23:02:53 +0100 +Subject: [PATCH] OvmfPkg: allow exclusion of the shell from the firmware image + +When '-D EXCLUDE_SHELL_FROM_FD' is passed to 'build', exclude the shell +binary from the firmware image. + +Peter Jones advised us that firmware vendors for physical systems disable +the memory-mapped, firmware image-contained UEFI shell in +SecureBoot-enabled builds. The reason being that the memory-mapped shell +can always load, it may have direct access to various hardware in the +system, and it can run UEFI shell scripts (which cannot be signed at all). + +Intended use of the new build option: + +- In-tree builds: don't pass '-D EXCLUDE_SHELL_FROM_FD'. The resultant + firmware image will contain a shell binary, independently of SecureBoot + enablement, which is flexible for interactive development. (Ie. no + change for in-tree builds.) + +- RPM builds: pass both '-D SECURE_BOOT_ENABLE' and + '-D EXCLUDE_SHELL_FROM_FD'. The resultant RPM will provide: + + - OVMF_CODE.fd: SecureBoot-enabled firmware, without builtin UEFI shell, + + - OVMF_VARS.fd: variable store template matching OVMF_CODE.fd, + + - UefiShell.iso: a bootable ISO image with the shell on it as default + boot loader. The shell binary will load when SecureBoot is turned off, + and won't load when SecureBoot is turned on (because it is not + signed). + + UefiShell.iso is the reason we're not excluding the shell from the DSC + files as well, only the FDF files -- when '-D EXCLUDE_SHELL_FROM_FD' + is specified, the shell binary needs to be built the same, only it + will be included in UefiShell.iso. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 9c391def70366cabae08e6008814299c3372fafd) +(cherry picked from commit d9dd9ee42937b2611fe37183cc9ec7f62d946933) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + OvmfPkg/OvmfPkgIa32.fdf | 2 ++ + OvmfPkg/OvmfPkgIa32X64.fdf | 2 ++ + OvmfPkg/OvmfPkgX64.fdf | 2 ++ + 3 files changed, 6 insertions(+) + +diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf +index 4177379a23..8c0b6ee1bd 100644 +--- a/OvmfPkg/OvmfPkgIa32.fdf ++++ b/OvmfPkg/OvmfPkgIa32.fdf +@@ -288,12 +288,14 @@ INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResour + INF FatPkg/EnhancedFatDxe/Fat.inf + INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf + ++!ifndef $(EXCLUDE_SHELL_FROM_FD) + !ifndef $(USE_OLD_SHELL) + INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf + INF ShellPkg/Application/Shell/Shell.inf + !else + INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf + !endif ++!endif + + !if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) + INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf +diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf +index 5e57161154..8de20366d2 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.fdf ++++ b/OvmfPkg/OvmfPkgIa32X64.fdf +@@ -289,12 +289,14 @@ INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResour + INF FatPkg/EnhancedFatDxe/Fat.inf + INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf + ++!ifndef $(EXCLUDE_SHELL_FROM_FD) + !ifndef $(USE_OLD_SHELL) + INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf + INF ShellPkg/Application/Shell/Shell.inf + !else + INF RuleOverride = BINARY USE = X64 EdkShellBinPkg/FullShell/FullShell.inf + !endif ++!endif + + !if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) + INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index c81b422517..49ef829a3a 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -289,12 +289,14 @@ INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResour + INF FatPkg/EnhancedFatDxe/Fat.inf + INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf + ++!ifndef $(EXCLUDE_SHELL_FROM_FD) + !ifndef $(USE_OLD_SHELL) + INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf + INF ShellPkg/Application/Shell/Shell.inf + !else + INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf + !endif ++!endif + + !if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(NETWORK_IP6_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) + INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf diff --git a/0013-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch b/0013-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch new file mode 100644 index 0000000..cb60132 --- /dev/null +++ b/0013-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch @@ -0,0 +1,1328 @@ +From 685d43b29b2ac4b19572bda1ebeb989d69d74ebb Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Tue, 4 Nov 2014 23:02:55 +0100 +Subject: [PATCH] OvmfPkg: EnrollDefaultKeys: application for enrolling default + keys + +This application is meant to be invoked by the management layer, after +booting the UEFI shell and getting a shell prompt on the serial console. +The app enrolls a number of certificates (see below), and then reports +status to the serial console as well. The expected output is "info: +success": + +> Shell> EnrollDefaultKeys.efi +> info: SetupMode=1 SecureBoot=0 SecureBootEnable=0 CustomMode=0 VendorKeys=1 +> info: SetupMode=0 SecureBoot=1 SecureBootEnable=1 CustomMode=0 VendorKeys=0 +> info: success +> Shell> + +In case of success, the management layer can force off or reboot the VM +(for example with the "reset -s" or "reset -c" UEFI shell commands, +respectively), and start the guest installation with SecureBoot enabled. + +PK: +- A unique, static, ad-hoc certificate whose private half has been + destroyed (more precisely, never saved) and is therefore unusable for + signing. (The command for creating this certificate is saved in the + source code.) Background: + +On 09/30/14 20:00, Peter Jones wrote: +> We should generate a special key that's not in our normal signing chains +> for PK and KEK. The reason for this is that [in practice] PK gets +> treated as part of DB (*). +> +> [Shipping a key in our normal signing chains] as PK means you can run +> grub directly, in which case it won't have access to the shim protocol. +> When grub is run without the shim protocol registered, it assumes SB is +> disabled and boots without verifying the kernel. We don't want that to +> be a thing you can do, but allowing that is the inevitable result of +> shipping with any of our normal signing chain in PK or KEK. +> +> (* USRT has actually agreed that since you can escalate to this behavior +> if you have the secret half of a key in KEK or PK anyway, and many +> vendors had already shipped it this way, that it is fine and I think +> even *expected* at this point, even though it wasn't formally in the +> UEFI 2.3.1 Spec that introduced Secure Boot. I'll try and make sure the +> language reflects that in an upcoming spec revision.) +> +> So let me get SRT to issue a special key to use for PK and KEK. We can +> use it just for those operations, and make sure it's protected with the +> same processes and controls as our other signing keys. + + Until SRT generates such a key for us, this ad-hoc key should be a good + placeholder. + +KEK: +- same ad-hoc certificate as used for the PK, +- "Microsoft Corporation KEK CA 2011" -- the dbx data in Fedora's dbxtool + package is signed (indirectly, through a chain) with this; enrolling + such a KEK should allow guests to install those updates. + +DB: +- "Microsoft Windows Production PCA 2011" -- to load Windows 8 and Windows + Server 2012 R2, +- "Microsoft Corporation UEFI CA 2011" -- to load Linux and signed PCI + oproms. + +*UPDATE* + +OvmfPkg: EnrollDefaultKeys: pick up official Red Hat PK/KEK (RHEL only) + +Replace the placeholder ExampleCert with a certificate generated and +managed by the Red Hat Security Response Team. + +> Certificate: +> Data: +> Version: 3 (0x2) +> Serial Number: 18371740789028339953 (0xfef588e8f396c0f1) +> Signature Algorithm: sha256WithRSAEncryption +> Issuer: CN=Red Hat Secure Boot (PK/KEK key 1)/emailAddress=secalert@redhat.com +> Validity +> Not Before: Oct 31 11:15:37 2014 GMT +> Not After : Oct 25 11:15:37 2037 GMT +> Subject: CN=Red Hat Secure Boot (PK/KEK key 1)/emailAddress=secalert@redhat.com +> Subject Public Key Info: +> Public Key Algorithm: rsaEncryption +> Public-Key: (2048 bit) +> Modulus: +> 00:90:1f:84:7b:8d:bc:eb:97:26:82:6d:88:ab:8a: +> c9:8c:68:70:f9:df:4b:07:b2:37:83:0b:02:c8:67: +> 68:30:9e:e3:f0:f0:99:4a:b8:59:57:c6:41:f6:38: +> 8b:fe:66:4c:49:e9:37:37:92:2e:98:01:1e:5b:14: +> 50:e6:a8:8d:25:0d:f5:86:e6:ab:30:cb:40:16:ea: +> 8d:8b:16:86:70:43:37:f2:ce:c0:91:df:71:14:8e: +> 99:0e:89:b6:4c:6d:24:1e:8c:e4:2f:4f:25:d0:ba: +> 06:f8:c6:e8:19:18:76:73:1d:81:6d:a8:d8:05:cf: +> 3a:c8:7b:28:c8:36:a3:16:0d:29:8c:99:9a:68:dc: +> ab:c0:4d:8d:bf:5a:bb:2b:a9:39:4b:04:97:1c:f9: +> 36:bb:c5:3a:86:04:ae:af:d4:82:7b:e0:ab:de:49: +> 05:68:fc:f6:ae:68:1a:6c:90:4d:57:19:3c:64:66: +> 03:f6:c7:52:9b:f7:94:cf:93:6a:a1:68:c9:aa:cf: +> 99:6b:bc:aa:5e:08:e7:39:1c:f7:f8:0f:ba:06:7e: +> f1:cb:e8:76:dd:fe:22:da:ad:3a:5e:5b:34:ea:b3: +> c9:e0:4d:04:29:7e:b8:60:b9:05:ef:b5:d9:17:58: +> 56:16:60:b9:30:32:f0:36:4a:c3:f2:79:8d:12:40: +> 70:f3 +> Exponent: 65537 (0x10001) +> X509v3 extensions: +> X509v3 Basic Constraints: +> CA:FALSE +> Netscape Comment: +> OpenSSL Generated Certificate +> X509v3 Subject Key Identifier: +> 3C:E9:60:E3:FF:19:A1:0A:7B:A3:42:F4:8D:42:2E:B4:D5:9C:72:EC +> X509v3 Authority Key Identifier: +> keyid:3C:E9:60:E3:FF:19:A1:0A:7B:A3:42:F4:8D:42:2E:B4:D5:9C:72:EC +> +> Signature Algorithm: sha256WithRSAEncryption +> 5c:4d:92:88:b4:82:5f:1d:ad:8b:11:ec:df:06:a6:7a:a5:2b: +> 9f:37:55:0c:8d:6e:05:00:ad:b7:0c:41:89:69:cf:d6:65:06: +> 9b:51:78:d2:ad:c7:bf:9c:dc:05:73:7f:e7:1e:39:13:b4:ea: +> b6:30:7d:40:75:ab:9c:43:0b:df:b0:c2:1b:bf:30:e0:f4:fe: +> c0:db:62:21:98:f6:c5:af:de:3b:4f:49:0a:e6:1e:f9:86:b0: +> 3f:0d:d6:d4:46:37:db:54:74:5e:ff:11:c2:60:c6:70:58:c5: +> 1c:6f:ec:b2:d8:6e:6f:c3:bc:33:87:38:a4:f3:44:64:9c:34: +> 3b:28:94:26:78:27:9f:16:17:e8:3b:69:0a:25:a9:73:36:7e: +> 9e:37:5c:ec:e8:3f:db:91:f9:12:b3:3d:ce:e7:dd:15:c3:ae: +> 8c:05:20:61:9b:95:de:9b:af:fa:b1:5c:1c:e5:97:e7:c3:34: +> 11:85:f5:8a:27:26:a4:70:36:ec:0c:f6:83:3d:90:f7:36:f3: +> f9:f3:15:d4:90:62:be:53:b4:af:d3:49:af:ef:f4:73:e8:7b: +> 76:e4:44:2a:37:ba:81:a4:99:0c:3a:31:24:71:a0:e4:e4:b7: +> 1a:cb:47:e4:aa:22:cf:ef:75:61:80:e3:43:b7:48:57:73:11: +> 3d:78:9b:69 +> -----BEGIN CERTIFICATE----- +> MIIDoDCCAoigAwIBAgIJAP71iOjzlsDxMA0GCSqGSIb3DQEBCwUAMFExKzApBgNV +> BAMTIlJlZCBIYXQgU2VjdXJlIEJvb3QgKFBLL0tFSyBrZXkgMSkxIjAgBgkqhkiG +> 9w0BCQEWE3NlY2FsZXJ0QHJlZGhhdC5jb20wHhcNMTQxMDMxMTExNTM3WhcNMzcx +> MDI1MTExNTM3WjBRMSswKQYDVQQDEyJSZWQgSGF0IFNlY3VyZSBCb290IChQSy9L +> RUsga2V5IDEpMSIwIAYJKoZIhvcNAQkBFhNzZWNhbGVydEByZWRoYXQuY29tMIIB +> IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkB+Ee42865cmgm2Iq4rJjGhw +> +d9LB7I3gwsCyGdoMJ7j8PCZSrhZV8ZB9jiL/mZMSek3N5IumAEeWxRQ5qiNJQ31 +> huarMMtAFuqNixaGcEM38s7Akd9xFI6ZDom2TG0kHozkL08l0LoG+MboGRh2cx2B +> bajYBc86yHsoyDajFg0pjJmaaNyrwE2Nv1q7K6k5SwSXHPk2u8U6hgSur9SCe+Cr +> 3kkFaPz2rmgabJBNVxk8ZGYD9sdSm/eUz5NqoWjJqs+Za7yqXgjnORz3+A+6Bn7x +> y+h23f4i2q06Xls06rPJ4E0EKX64YLkF77XZF1hWFmC5MDLwNkrD8nmNEkBw8wID +> AQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy +> YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUPOlg4/8ZoQp7o0L0jUIutNWccuww +> HwYDVR0jBBgwFoAUPOlg4/8ZoQp7o0L0jUIutNWccuwwDQYJKoZIhvcNAQELBQAD +> ggEBAFxNkoi0gl8drYsR7N8GpnqlK583VQyNbgUArbcMQYlpz9ZlBptReNKtx7+c +> 3AVzf+ceORO06rYwfUB1q5xDC9+wwhu/MOD0/sDbYiGY9sWv3jtPSQrmHvmGsD8N +> 1tRGN9tUdF7/EcJgxnBYxRxv7LLYbm/DvDOHOKTzRGScNDsolCZ4J58WF+g7aQol +> qXM2fp43XOzoP9uR+RKzPc7n3RXDrowFIGGbld6br/qxXBzll+fDNBGF9YonJqRw +> NuwM9oM9kPc28/nzFdSQYr5TtK/TSa/v9HPoe3bkRCo3uoGkmQw6MSRxoOTktxrL +> R+SqIs/vdWGA40O3SFdzET14m2k= +> -----END CERTIFICATE----- + +Notes about the 9ece15a -> c9e5618 rebase: +- resolved conflicts in: + OvmfPkg/OvmfPkgIa32.dsc + OvmfPkg/OvmfPkgIa32X64.dsc + OvmfPkg/OvmfPkgX64.dsc + due to OvmfPkg/SecureBootConfigDxe/SecureBootConfigDxe.inf having + disappeared in upstream (commit 57446bb9). + +Notes about the c9e5618 -> b9ffeab rebase: +- Guid/VariableFormat.h now lives under MdeModulePkg. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- This patch now squashes the following commits: + - 014f459c197b OvmfPkg: EnrollDefaultKeys: application for enrolling + default keys (RH only) + - 18422a18d0e9 OvmfPkg/EnrollDefaultKeys: assign Status before reading + it (RH only) + - ddb90568e874 OvmfPkg/EnrollDefaultKeys: silence VS2015x86 warning (RH + only) + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- This patch now squashes the following commits: + - c0b2615a9c0b OvmfPkg: EnrollDefaultKeys: application for enrolling + default keys (RH only) + - 22f4d33d0168 OvmfPkg/EnrollDefaultKeys: update SignatureOwner GUID for + Windows HCK (RH) + - ff7f2c1d870d OvmfPkg/EnrollDefaultKeys: expose CertType parameter of + EnrollListOfCerts (RH) + - aee7b5ba60b4 OvmfPkg/EnrollDefaultKeys: blacklist empty file in dbx + for Windows HCK (RH) + +- Consequently, OvmfPkg/EnrollDefaultKeys/ is identical to the same + directory at the "RHEL-7.4" tag (49d06d386736). + +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit c0b2615a9c0b4a4be1bffe45681a32915449279d) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c | 1015 +++++++++++++++++ + .../EnrollDefaultKeys/EnrollDefaultKeys.inf | 52 + + OvmfPkg/OvmfPkgIa32.dsc | 4 + + OvmfPkg/OvmfPkgIa32X64.dsc | 4 + + OvmfPkg/OvmfPkgX64.dsc | 4 + + 5 files changed, 1079 insertions(+) + create mode 100644 OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c + create mode 100644 OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf + +diff --git a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c +new file mode 100644 +index 0000000000..dd413df12d +--- /dev/null ++++ b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c +@@ -0,0 +1,1015 @@ ++/** @file ++ Enroll default PK, KEK, DB. ++ ++ Copyright (C) 2014, Red Hat, Inc. ++ ++ 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. ++ ++ 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 <Guid/AuthenticatedVariableFormat.h> // gEfiCustomModeEnableGuid ++#include <Guid/GlobalVariable.h> // EFI_SETUP_MODE_NAME ++#include <Guid/ImageAuthentication.h> // EFI_IMAGE_SECURITY_DATABASE ++#include <Library/BaseMemoryLib.h> // CopyGuid() ++#include <Library/DebugLib.h> // ASSERT() ++#include <Library/MemoryAllocationLib.h> // FreePool() ++#include <Library/ShellCEntryLib.h> // ShellAppMain() ++#include <Library/UefiLib.h> // AsciiPrint() ++#include <Library/UefiRuntimeServicesTableLib.h> // gRT ++ ++// ++// We'll use the certificate below as both Platform Key and as first Key ++// Exchange Key. ++// ++// "Red Hat Secure Boot (PK/KEK key 1)/emailAddress=secalert@redhat.com" ++// SHA1: fd:fc:7f:3c:7e:f3:e0:57:76:ad:d7:98:78:21:6c:9b:e0:e1:95:97 ++// ++STATIC CONST UINT8 RedHatPkKek1[] = { ++ 0x30, 0x82, 0x03, 0xa0, 0x30, 0x82, 0x02, 0x88, 0xa0, 0x03, 0x02, 0x01, 0x02, ++ 0x02, 0x09, 0x00, 0xfe, 0xf5, 0x88, 0xe8, 0xf3, 0x96, 0xc0, 0xf1, 0x30, 0x0d, ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, ++ 0x30, 0x51, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, ++ 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, ++ 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, 0x28, 0x50, 0x4b, 0x2f, 0x4b, 0x45, ++ 0x4b, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x31, 0x29, 0x31, 0x22, 0x30, 0x20, 0x06, ++ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x73, ++ 0x65, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, 0x64, 0x68, 0x61, ++ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, ++ 0x33, 0x31, 0x31, 0x31, 0x31, 0x35, 0x33, 0x37, 0x5a, 0x17, 0x0d, 0x33, 0x37, ++ 0x31, 0x30, 0x32, 0x35, 0x31, 0x31, 0x31, 0x35, 0x33, 0x37, 0x5a, 0x30, 0x51, ++ 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x52, 0x65, ++ 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, ++ 0x42, 0x6f, 0x6f, 0x74, 0x20, 0x28, 0x50, 0x4b, 0x2f, 0x4b, 0x45, 0x4b, 0x20, ++ 0x6b, 0x65, 0x79, 0x20, 0x31, 0x29, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09, 0x2a, ++ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x73, 0x65, 0x63, ++ 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, 0x64, 0x68, 0x61, 0x74, 0x2e, ++ 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, ++ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, ++ 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x90, 0x1f, 0x84, ++ 0x7b, 0x8d, 0xbc, 0xeb, 0x97, 0x26, 0x82, 0x6d, 0x88, 0xab, 0x8a, 0xc9, 0x8c, ++ 0x68, 0x70, 0xf9, 0xdf, 0x4b, 0x07, 0xb2, 0x37, 0x83, 0x0b, 0x02, 0xc8, 0x67, ++ 0x68, 0x30, 0x9e, 0xe3, 0xf0, 0xf0, 0x99, 0x4a, 0xb8, 0x59, 0x57, 0xc6, 0x41, ++ 0xf6, 0x38, 0x8b, 0xfe, 0x66, 0x4c, 0x49, 0xe9, 0x37, 0x37, 0x92, 0x2e, 0x98, ++ 0x01, 0x1e, 0x5b, 0x14, 0x50, 0xe6, 0xa8, 0x8d, 0x25, 0x0d, 0xf5, 0x86, 0xe6, ++ 0xab, 0x30, 0xcb, 0x40, 0x16, 0xea, 0x8d, 0x8b, 0x16, 0x86, 0x70, 0x43, 0x37, ++ 0xf2, 0xce, 0xc0, 0x91, 0xdf, 0x71, 0x14, 0x8e, 0x99, 0x0e, 0x89, 0xb6, 0x4c, ++ 0x6d, 0x24, 0x1e, 0x8c, 0xe4, 0x2f, 0x4f, 0x25, 0xd0, 0xba, 0x06, 0xf8, 0xc6, ++ 0xe8, 0x19, 0x18, 0x76, 0x73, 0x1d, 0x81, 0x6d, 0xa8, 0xd8, 0x05, 0xcf, 0x3a, ++ 0xc8, 0x7b, 0x28, 0xc8, 0x36, 0xa3, 0x16, 0x0d, 0x29, 0x8c, 0x99, 0x9a, 0x68, ++ 0xdc, 0xab, 0xc0, 0x4d, 0x8d, 0xbf, 0x5a, 0xbb, 0x2b, 0xa9, 0x39, 0x4b, 0x04, ++ 0x97, 0x1c, 0xf9, 0x36, 0xbb, 0xc5, 0x3a, 0x86, 0x04, 0xae, 0xaf, 0xd4, 0x82, ++ 0x7b, 0xe0, 0xab, 0xde, 0x49, 0x05, 0x68, 0xfc, 0xf6, 0xae, 0x68, 0x1a, 0x6c, ++ 0x90, 0x4d, 0x57, 0x19, 0x3c, 0x64, 0x66, 0x03, 0xf6, 0xc7, 0x52, 0x9b, 0xf7, ++ 0x94, 0xcf, 0x93, 0x6a, 0xa1, 0x68, 0xc9, 0xaa, 0xcf, 0x99, 0x6b, 0xbc, 0xaa, ++ 0x5e, 0x08, 0xe7, 0x39, 0x1c, 0xf7, 0xf8, 0x0f, 0xba, 0x06, 0x7e, 0xf1, 0xcb, ++ 0xe8, 0x76, 0xdd, 0xfe, 0x22, 0xda, 0xad, 0x3a, 0x5e, 0x5b, 0x34, 0xea, 0xb3, ++ 0xc9, 0xe0, 0x4d, 0x04, 0x29, 0x7e, 0xb8, 0x60, 0xb9, 0x05, 0xef, 0xb5, 0xd9, ++ 0x17, 0x58, 0x56, 0x16, 0x60, 0xb9, 0x30, 0x32, 0xf0, 0x36, 0x4a, 0xc3, 0xf2, ++ 0x79, 0x8d, 0x12, 0x40, 0x70, 0xf3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7b, ++ 0x30, 0x79, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, ++ 0x30, 0x2c, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, ++ 0x04, 0x1f, 0x16, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, 0x4c, 0x20, 0x47, ++ 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, ++ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, ++ 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3c, 0xe9, 0x60, 0xe3, 0xff, 0x19, 0xa1, 0x0a, ++ 0x7b, 0xa3, 0x42, 0xf4, 0x8d, 0x42, 0x2e, 0xb4, 0xd5, 0x9c, 0x72, 0xec, 0x30, ++ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x3c, ++ 0xe9, 0x60, 0xe3, 0xff, 0x19, 0xa1, 0x0a, 0x7b, 0xa3, 0x42, 0xf4, 0x8d, 0x42, ++ 0x2e, 0xb4, 0xd5, 0x9c, 0x72, 0xec, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, ++ 0x5c, 0x4d, 0x92, 0x88, 0xb4, 0x82, 0x5f, 0x1d, 0xad, 0x8b, 0x11, 0xec, 0xdf, ++ 0x06, 0xa6, 0x7a, 0xa5, 0x2b, 0x9f, 0x37, 0x55, 0x0c, 0x8d, 0x6e, 0x05, 0x00, ++ 0xad, 0xb7, 0x0c, 0x41, 0x89, 0x69, 0xcf, 0xd6, 0x65, 0x06, 0x9b, 0x51, 0x78, ++ 0xd2, 0xad, 0xc7, 0xbf, 0x9c, 0xdc, 0x05, 0x73, 0x7f, 0xe7, 0x1e, 0x39, 0x13, ++ 0xb4, 0xea, 0xb6, 0x30, 0x7d, 0x40, 0x75, 0xab, 0x9c, 0x43, 0x0b, 0xdf, 0xb0, ++ 0xc2, 0x1b, 0xbf, 0x30, 0xe0, 0xf4, 0xfe, 0xc0, 0xdb, 0x62, 0x21, 0x98, 0xf6, ++ 0xc5, 0xaf, 0xde, 0x3b, 0x4f, 0x49, 0x0a, 0xe6, 0x1e, 0xf9, 0x86, 0xb0, 0x3f, ++ 0x0d, 0xd6, 0xd4, 0x46, 0x37, 0xdb, 0x54, 0x74, 0x5e, 0xff, 0x11, 0xc2, 0x60, ++ 0xc6, 0x70, 0x58, 0xc5, 0x1c, 0x6f, 0xec, 0xb2, 0xd8, 0x6e, 0x6f, 0xc3, 0xbc, ++ 0x33, 0x87, 0x38, 0xa4, 0xf3, 0x44, 0x64, 0x9c, 0x34, 0x3b, 0x28, 0x94, 0x26, ++ 0x78, 0x27, 0x9f, 0x16, 0x17, 0xe8, 0x3b, 0x69, 0x0a, 0x25, 0xa9, 0x73, 0x36, ++ 0x7e, 0x9e, 0x37, 0x5c, 0xec, 0xe8, 0x3f, 0xdb, 0x91, 0xf9, 0x12, 0xb3, 0x3d, ++ 0xce, 0xe7, 0xdd, 0x15, 0xc3, 0xae, 0x8c, 0x05, 0x20, 0x61, 0x9b, 0x95, 0xde, ++ 0x9b, 0xaf, 0xfa, 0xb1, 0x5c, 0x1c, 0xe5, 0x97, 0xe7, 0xc3, 0x34, 0x11, 0x85, ++ 0xf5, 0x8a, 0x27, 0x26, 0xa4, 0x70, 0x36, 0xec, 0x0c, 0xf6, 0x83, 0x3d, 0x90, ++ 0xf7, 0x36, 0xf3, 0xf9, 0xf3, 0x15, 0xd4, 0x90, 0x62, 0xbe, 0x53, 0xb4, 0xaf, ++ 0xd3, 0x49, 0xaf, 0xef, 0xf4, 0x73, 0xe8, 0x7b, 0x76, 0xe4, 0x44, 0x2a, 0x37, ++ 0xba, 0x81, 0xa4, 0x99, 0x0c, 0x3a, 0x31, 0x24, 0x71, 0xa0, 0xe4, 0xe4, 0xb7, ++ 0x1a, 0xcb, 0x47, 0xe4, 0xaa, 0x22, 0xcf, 0xef, 0x75, 0x61, 0x80, 0xe3, 0x43, ++ 0xb7, 0x48, 0x57, 0x73, 0x11, 0x3d, 0x78, 0x9b, 0x69 ++}; ++ ++// ++// Second KEK: "Microsoft Corporation KEK CA 2011". ++// SHA1: 31:59:0b:fd:89:c9:d7:4e:d0:87:df:ac:66:33:4b:39:31:25:4b:30 ++// ++// "dbx" updates in "dbxtool" are signed with a key derived from this KEK. ++// ++STATIC CONST UINT8 MicrosoftKEK[] = { ++ 0x30, 0x82, 0x05, 0xe8, 0x30, 0x82, 0x03, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02, ++ 0x02, 0x0a, 0x61, 0x0a, 0xd1, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, ++ 0x00, 0x30, 0x81, 0x91, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, ++ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, ++ 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, ++ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, ++ 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, ++ 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, ++ 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x3b, 0x30, ++ 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x4d, 0x69, 0x63, 0x72, 0x6f, ++ 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, ++ 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x50, 0x61, 0x72, ++ 0x74, 0x79, 0x20, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x70, 0x6c, 0x61, 0x63, ++ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, ++ 0x36, 0x32, 0x34, 0x32, 0x30, 0x34, 0x31, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x32, ++ 0x36, 0x30, 0x36, 0x32, 0x34, 0x32, 0x30, 0x35, 0x31, 0x32, 0x39, 0x5a, 0x30, ++ 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, ++ 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, ++ 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, ++ 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, ++ 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, ++ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, ++ 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x2a, 0x30, 0x28, 0x06, ++ 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, ++ 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, ++ 0x6e, 0x20, 0x4b, 0x45, 0x4b, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x31, ++ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, ++ 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, ++ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xe8, 0xb5, 0x8a, 0xbf, 0xad, ++ 0x57, 0x26, 0xb0, 0x26, 0xc3, 0xea, 0xe7, 0xfb, 0x57, 0x7a, 0x44, 0x02, 0x5d, ++ 0x07, 0x0d, 0xda, 0x4a, 0xe5, 0x74, 0x2a, 0xe6, 0xb0, 0x0f, 0xec, 0x6d, 0xeb, ++ 0xec, 0x7f, 0xb9, 0xe3, 0x5a, 0x63, 0x32, 0x7c, 0x11, 0x17, 0x4f, 0x0e, 0xe3, ++ 0x0b, 0xa7, 0x38, 0x15, 0x93, 0x8e, 0xc6, 0xf5, 0xe0, 0x84, 0xb1, 0x9a, 0x9b, ++ 0x2c, 0xe7, 0xf5, 0xb7, 0x91, 0xd6, 0x09, 0xe1, 0xe2, 0xc0, 0x04, 0xa8, 0xac, ++ 0x30, 0x1c, 0xdf, 0x48, 0xf3, 0x06, 0x50, 0x9a, 0x64, 0xa7, 0x51, 0x7f, 0xc8, ++ 0x85, 0x4f, 0x8f, 0x20, 0x86, 0xce, 0xfe, 0x2f, 0xe1, 0x9f, 0xff, 0x82, 0xc0, ++ 0xed, 0xe9, 0xcd, 0xce, 0xf4, 0x53, 0x6a, 0x62, 0x3a, 0x0b, 0x43, 0xb9, 0xe2, ++ 0x25, 0xfd, 0xfe, 0x05, 0xf9, 0xd4, 0xc4, 0x14, 0xab, 0x11, 0xe2, 0x23, 0x89, ++ 0x8d, 0x70, 0xb7, 0xa4, 0x1d, 0x4d, 0xec, 0xae, 0xe5, 0x9c, 0xfa, 0x16, 0xc2, ++ 0xd7, 0xc1, 0xcb, 0xd4, 0xe8, 0xc4, 0x2f, 0xe5, 0x99, 0xee, 0x24, 0x8b, 0x03, ++ 0xec, 0x8d, 0xf2, 0x8b, 0xea, 0xc3, 0x4a, 0xfb, 0x43, 0x11, 0x12, 0x0b, 0x7e, ++ 0xb5, 0x47, 0x92, 0x6c, 0xdc, 0xe6, 0x04, 0x89, 0xeb, 0xf5, 0x33, 0x04, 0xeb, ++ 0x10, 0x01, 0x2a, 0x71, 0xe5, 0xf9, 0x83, 0x13, 0x3c, 0xff, 0x25, 0x09, 0x2f, ++ 0x68, 0x76, 0x46, 0xff, 0xba, 0x4f, 0xbe, 0xdc, 0xad, 0x71, 0x2a, 0x58, 0xaa, ++ 0xfb, 0x0e, 0xd2, 0x79, 0x3d, 0xe4, 0x9b, 0x65, 0x3b, 0xcc, 0x29, 0x2a, 0x9f, ++ 0xfc, 0x72, 0x59, 0xa2, 0xeb, 0xae, 0x92, 0xef, 0xf6, 0x35, 0x13, 0x80, 0xc6, ++ 0x02, 0xec, 0xe4, 0x5f, 0xcc, 0x9d, 0x76, 0xcd, 0xef, 0x63, 0x92, 0xc1, 0xaf, ++ 0x79, 0x40, 0x84, 0x79, 0x87, 0x7f, 0xe3, 0x52, 0xa8, 0xe8, 0x9d, 0x7b, 0x07, ++ 0x69, 0x8f, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4f, 0x30, ++ 0x82, 0x01, 0x4b, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, ++ 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, ++ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x62, 0xfc, 0x43, 0xcd, 0xa0, 0x3e, 0xa4, ++ 0xcb, 0x67, 0x12, 0xd2, 0x5b, 0xd9, 0x55, 0xac, 0x7b, 0xcc, 0xb6, 0x8a, 0x5f, ++ 0x30, 0x19, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, ++ 0x04, 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, ++ 0x41, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, ++ 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, ++ 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, ++ 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0x66, 0x52, 0x43, 0xe1, 0x7e, 0x58, 0x11, ++ 0xbf, 0xd6, 0x4e, 0x9e, 0x23, 0x55, 0x08, 0x3b, 0x3a, 0x22, 0x6a, 0xa8, 0x30, ++ 0x5c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x55, 0x30, 0x53, 0x30, 0x51, 0xa0, ++ 0x4f, 0xa0, 0x4d, 0x86, 0x4b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, ++ 0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, ++ 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x70, ++ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, ++ 0x72, 0x54, 0x68, 0x69, 0x50, 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, ++ 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, ++ 0x72, 0x6c, 0x30, 0x60, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, ++ 0x01, 0x04, 0x54, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, ++ 0x05, 0x07, 0x30, 0x02, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, ++ 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, ++ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, 0x72, 0x74, ++ 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, 0x61, ++ 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, ++ 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, ++ 0x02, 0x01, 0x00, 0xd4, 0x84, 0x88, 0xf5, 0x14, 0x94, 0x18, 0x02, 0xca, 0x2a, ++ 0x3c, 0xfb, 0x2a, 0x92, 0x1c, 0x0c, 0xd7, 0xa0, 0xd1, 0xf1, 0xe8, 0x52, 0x66, ++ 0xa8, 0xee, 0xa2, 0xb5, 0x75, 0x7a, 0x90, 0x00, 0xaa, 0x2d, 0xa4, 0x76, 0x5a, ++ 0xea, 0x79, 0xb7, 0xb9, 0x37, 0x6a, 0x51, 0x7b, 0x10, 0x64, 0xf6, 0xe1, 0x64, ++ 0xf2, 0x02, 0x67, 0xbe, 0xf7, 0xa8, 0x1b, 0x78, 0xbd, 0xba, 0xce, 0x88, 0x58, ++ 0x64, 0x0c, 0xd6, 0x57, 0xc8, 0x19, 0xa3, 0x5f, 0x05, 0xd6, 0xdb, 0xc6, 0xd0, ++ 0x69, 0xce, 0x48, 0x4b, 0x32, 0xb7, 0xeb, 0x5d, 0xd2, 0x30, 0xf5, 0xc0, 0xf5, ++ 0xb8, 0xba, 0x78, 0x07, 0xa3, 0x2b, 0xfe, 0x9b, 0xdb, 0x34, 0x56, 0x84, 0xec, ++ 0x82, 0xca, 0xae, 0x41, 0x25, 0x70, 0x9c, 0x6b, 0xe9, 0xfe, 0x90, 0x0f, 0xd7, ++ 0x96, 0x1f, 0xe5, 0xe7, 0x94, 0x1f, 0xb2, 0x2a, 0x0c, 0x8d, 0x4b, 0xff, 0x28, ++ 0x29, 0x10, 0x7b, 0xf7, 0xd7, 0x7c, 0xa5, 0xd1, 0x76, 0xb9, 0x05, 0xc8, 0x79, ++ 0xed, 0x0f, 0x90, 0x92, 0x9c, 0xc2, 0xfe, 0xdf, 0x6f, 0x7e, 0x6c, 0x0f, 0x7b, ++ 0xd4, 0xc1, 0x45, 0xdd, 0x34, 0x51, 0x96, 0x39, 0x0f, 0xe5, 0x5e, 0x56, 0xd8, ++ 0x18, 0x05, 0x96, 0xf4, 0x07, 0xa6, 0x42, 0xb3, 0xa0, 0x77, 0xfd, 0x08, 0x19, ++ 0xf2, 0x71, 0x56, 0xcc, 0x9f, 0x86, 0x23, 0xa4, 0x87, 0xcb, 0xa6, 0xfd, 0x58, ++ 0x7e, 0xd4, 0x69, 0x67, 0x15, 0x91, 0x7e, 0x81, 0xf2, 0x7f, 0x13, 0xe5, 0x0d, ++ 0x8b, 0x8a, 0x3c, 0x87, 0x84, 0xeb, 0xe3, 0xce, 0xbd, 0x43, 0xe5, 0xad, 0x2d, ++ 0x84, 0x93, 0x8e, 0x6a, 0x2b, 0x5a, 0x7c, 0x44, 0xfa, 0x52, 0xaa, 0x81, 0xc8, ++ 0x2d, 0x1c, 0xbb, 0xe0, 0x52, 0xdf, 0x00, 0x11, 0xf8, 0x9a, 0x3d, 0xc1, 0x60, ++ 0xb0, 0xe1, 0x33, 0xb5, 0xa3, 0x88, 0xd1, 0x65, 0x19, 0x0a, 0x1a, 0xe7, 0xac, ++ 0x7c, 0xa4, 0xc1, 0x82, 0x87, 0x4e, 0x38, 0xb1, 0x2f, 0x0d, 0xc5, 0x14, 0x87, ++ 0x6f, 0xfd, 0x8d, 0x2e, 0xbc, 0x39, 0xb6, 0xe7, 0xe6, 0xc3, 0xe0, 0xe4, 0xcd, ++ 0x27, 0x84, 0xef, 0x94, 0x42, 0xef, 0x29, 0x8b, 0x90, 0x46, 0x41, 0x3b, 0x81, ++ 0x1b, 0x67, 0xd8, 0xf9, 0x43, 0x59, 0x65, 0xcb, 0x0d, 0xbc, 0xfd, 0x00, 0x92, ++ 0x4f, 0xf4, 0x75, 0x3b, 0xa7, 0xa9, 0x24, 0xfc, 0x50, 0x41, 0x40, 0x79, 0xe0, ++ 0x2d, 0x4f, 0x0a, 0x6a, 0x27, 0x76, 0x6e, 0x52, 0xed, 0x96, 0x69, 0x7b, 0xaf, ++ 0x0f, 0xf7, 0x87, 0x05, 0xd0, 0x45, 0xc2, 0xad, 0x53, 0x14, 0x81, 0x1f, 0xfb, ++ 0x30, 0x04, 0xaa, 0x37, 0x36, 0x61, 0xda, 0x4a, 0x69, 0x1b, 0x34, 0xd8, 0x68, ++ 0xed, 0xd6, 0x02, 0xcf, 0x6c, 0x94, 0x0c, 0xd3, 0xcf, 0x6c, 0x22, 0x79, 0xad, ++ 0xb1, 0xf0, 0xbc, 0x03, 0xa2, 0x46, 0x60, 0xa9, 0xc4, 0x07, 0xc2, 0x21, 0x82, ++ 0xf1, 0xfd, 0xf2, 0xe8, 0x79, 0x32, 0x60, 0xbf, 0xd8, 0xac, 0xa5, 0x22, 0x14, ++ 0x4b, 0xca, 0xc1, 0xd8, 0x4b, 0xeb, 0x7d, 0x3f, 0x57, 0x35, 0xb2, 0xe6, 0x4f, ++ 0x75, 0xb4, 0xb0, 0x60, 0x03, 0x22, 0x53, 0xae, 0x91, 0x79, 0x1d, 0xd6, 0x9b, ++ 0x41, 0x1f, 0x15, 0x86, 0x54, 0x70, 0xb2, 0xde, 0x0d, 0x35, 0x0f, 0x7c, 0xb0, ++ 0x34, 0x72, 0xba, 0x97, 0x60, 0x3b, 0xf0, 0x79, 0xeb, 0xa2, 0xb2, 0x1c, 0x5d, ++ 0xa2, 0x16, 0xb8, 0x87, 0xc5, 0xe9, 0x1b, 0xf6, 0xb5, 0x97, 0x25, 0x6f, 0x38, ++ 0x9f, 0xe3, 0x91, 0xfa, 0x8a, 0x79, 0x98, 0xc3, 0x69, 0x0e, 0xb7, 0xa3, 0x1c, ++ 0x20, 0x05, 0x97, 0xf8, 0xca, 0x14, 0xae, 0x00, 0xd7, 0xc4, 0xf3, 0xc0, 0x14, ++ 0x10, 0x75, 0x6b, 0x34, 0xa0, 0x1b, 0xb5, 0x99, 0x60, 0xf3, 0x5c, 0xb0, 0xc5, ++ 0x57, 0x4e, 0x36, 0xd2, 0x32, 0x84, 0xbf, 0x9e ++}; ++ ++// ++// First DB entry: "Microsoft Windows Production PCA 2011" ++// SHA1: 58:0a:6f:4c:c4:e4:b6:69:b9:eb:dc:1b:2b:3e:08:7b:80:d0:67:8d ++// ++// Windows 8 and Windows Server 2012 R2 boot loaders are signed with a chain ++// rooted in this certificate. ++// ++STATIC CONST UINT8 MicrosoftPCA[] = { ++ 0x30, 0x82, 0x05, 0xd7, 0x30, 0x82, 0x03, 0xbf, 0xa0, 0x03, 0x02, 0x01, 0x02, ++ 0x02, 0x0a, 0x61, 0x07, 0x76, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, ++ 0x00, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, ++ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, ++ 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, ++ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, ++ 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, ++ 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, ++ 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x32, 0x30, ++ 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x4d, 0x69, 0x63, 0x72, 0x6f, ++ 0x73, 0x6f, 0x66, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, ++ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, ++ 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x30, 0x30, 0x1e, 0x17, ++ 0x0d, 0x31, 0x31, 0x31, 0x30, 0x31, 0x39, 0x31, 0x38, 0x34, 0x31, 0x34, 0x32, ++ 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x30, 0x31, 0x39, 0x31, 0x38, 0x35, 0x31, ++ 0x34, 0x32, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, ++ 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, ++ 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, ++ 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, ++ 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, ++ 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, ++ 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, ++ 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x4d, 0x69, 0x63, ++ 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, ++ 0x73, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, ++ 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, ++ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, ++ 0x01, 0x00, 0xdd, 0x0c, 0xbb, 0xa2, 0xe4, 0x2e, 0x09, 0xe3, 0xe7, 0xc5, 0xf7, ++ 0x96, 0x69, 0xbc, 0x00, 0x21, 0xbd, 0x69, 0x33, 0x33, 0xef, 0xad, 0x04, 0xcb, ++ 0x54, 0x80, 0xee, 0x06, 0x83, 0xbb, 0xc5, 0x20, 0x84, 0xd9, 0xf7, 0xd2, 0x8b, ++ 0xf3, 0x38, 0xb0, 0xab, 0xa4, 0xad, 0x2d, 0x7c, 0x62, 0x79, 0x05, 0xff, 0xe3, ++ 0x4a, 0x3f, 0x04, 0x35, 0x20, 0x70, 0xe3, 0xc4, 0xe7, 0x6b, 0xe0, 0x9c, 0xc0, ++ 0x36, 0x75, 0xe9, 0x8a, 0x31, 0xdd, 0x8d, 0x70, 0xe5, 0xdc, 0x37, 0xb5, 0x74, ++ 0x46, 0x96, 0x28, 0x5b, 0x87, 0x60, 0x23, 0x2c, 0xbf, 0xdc, 0x47, 0xa5, 0x67, ++ 0xf7, 0x51, 0x27, 0x9e, 0x72, 0xeb, 0x07, 0xa6, 0xc9, 0xb9, 0x1e, 0x3b, 0x53, ++ 0x35, 0x7c, 0xe5, 0xd3, 0xec, 0x27, 0xb9, 0x87, 0x1c, 0xfe, 0xb9, 0xc9, 0x23, ++ 0x09, 0x6f, 0xa8, 0x46, 0x91, 0xc1, 0x6e, 0x96, 0x3c, 0x41, 0xd3, 0xcb, 0xa3, ++ 0x3f, 0x5d, 0x02, 0x6a, 0x4d, 0xec, 0x69, 0x1f, 0x25, 0x28, 0x5c, 0x36, 0xff, ++ 0xfd, 0x43, 0x15, 0x0a, 0x94, 0xe0, 0x19, 0xb4, 0xcf, 0xdf, 0xc2, 0x12, 0xe2, ++ 0xc2, 0x5b, 0x27, 0xee, 0x27, 0x78, 0x30, 0x8b, 0x5b, 0x2a, 0x09, 0x6b, 0x22, ++ 0x89, 0x53, 0x60, 0x16, 0x2c, 0xc0, 0x68, 0x1d, 0x53, 0xba, 0xec, 0x49, 0xf3, ++ 0x9d, 0x61, 0x8c, 0x85, 0x68, 0x09, 0x73, 0x44, 0x5d, 0x7d, 0xa2, 0x54, 0x2b, ++ 0xdd, 0x79, 0xf7, 0x15, 0xcf, 0x35, 0x5d, 0x6c, 0x1c, 0x2b, 0x5c, 0xce, 0xbc, ++ 0x9c, 0x23, 0x8b, 0x6f, 0x6e, 0xb5, 0x26, 0xd9, 0x36, 0x13, 0xc3, 0x4f, 0xd6, ++ 0x27, 0xae, 0xb9, 0x32, 0x3b, 0x41, 0x92, 0x2c, 0xe1, 0xc7, 0xcd, 0x77, 0xe8, ++ 0xaa, 0x54, 0x4e, 0xf7, 0x5c, 0x0b, 0x04, 0x87, 0x65, 0xb4, 0x43, 0x18, 0xa8, ++ 0xb2, 0xe0, 0x6d, 0x19, 0x77, 0xec, 0x5a, 0x24, 0xfa, 0x48, 0x03, 0x02, 0x03, ++ 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x43, 0x30, 0x82, 0x01, 0x3f, 0x30, 0x10, ++ 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, ++ 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, ++ 0x14, 0xa9, 0x29, 0x02, 0x39, 0x8e, 0x16, 0xc4, 0x97, 0x78, 0xcd, 0x90, 0xf9, ++ 0x9e, 0x4f, 0x9a, 0xe1, 0x7c, 0x55, 0xaf, 0x53, 0x30, 0x19, 0x06, 0x09, 0x2b, ++ 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0c, 0x1e, 0x0a, 0x00, ++ 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0b, 0x06, 0x03, ++ 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, ++ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, ++ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, ++ 0xd5, 0xf6, 0x56, 0xcb, 0x8f, 0xe8, 0xa2, 0x5c, 0x62, 0x68, 0xd1, 0x3d, 0x94, ++ 0x90, 0x5b, 0xd7, 0xce, 0x9a, 0x18, 0xc4, 0x30, 0x56, 0x06, 0x03, 0x55, 0x1d, ++ 0x1f, 0x04, 0x4f, 0x30, 0x4d, 0x30, 0x4b, 0xa0, 0x49, 0xa0, 0x47, 0x86, 0x45, ++ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x6d, 0x69, ++ 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, ++ 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, ++ 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x52, 0x6f, 0x6f, 0x43, 0x65, 0x72, 0x41, ++ 0x75, 0x74, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x33, ++ 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x5a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, ++ 0x07, 0x01, 0x01, 0x04, 0x4e, 0x30, 0x4c, 0x30, 0x4a, 0x06, 0x08, 0x2b, 0x06, ++ 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x3e, 0x68, 0x74, 0x74, 0x70, 0x3a, ++ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, ++ 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, ++ 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x52, 0x6f, 0x6f, 0x43, 0x65, 0x72, ++ 0x41, 0x75, 0x74, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x36, 0x2d, 0x32, ++ 0x33, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, ++ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x14, ++ 0xfc, 0x7c, 0x71, 0x51, 0xa5, 0x79, 0xc2, 0x6e, 0xb2, 0xef, 0x39, 0x3e, 0xbc, ++ 0x3c, 0x52, 0x0f, 0x6e, 0x2b, 0x3f, 0x10, 0x13, 0x73, 0xfe, 0xa8, 0x68, 0xd0, ++ 0x48, 0xa6, 0x34, 0x4d, 0x8a, 0x96, 0x05, 0x26, 0xee, 0x31, 0x46, 0x90, 0x61, ++ 0x79, 0xd6, 0xff, 0x38, 0x2e, 0x45, 0x6b, 0xf4, 0xc0, 0xe5, 0x28, 0xb8, 0xda, ++ 0x1d, 0x8f, 0x8a, 0xdb, 0x09, 0xd7, 0x1a, 0xc7, 0x4c, 0x0a, 0x36, 0x66, 0x6a, ++ 0x8c, 0xec, 0x1b, 0xd7, 0x04, 0x90, 0xa8, 0x18, 0x17, 0xa4, 0x9b, 0xb9, 0xe2, ++ 0x40, 0x32, 0x36, 0x76, 0xc4, 0xc1, 0x5a, 0xc6, 0xbf, 0xe4, 0x04, 0xc0, 0xea, ++ 0x16, 0xd3, 0xac, 0xc3, 0x68, 0xef, 0x62, 0xac, 0xdd, 0x54, 0x6c, 0x50, 0x30, ++ 0x58, 0xa6, 0xeb, 0x7c, 0xfe, 0x94, 0xa7, 0x4e, 0x8e, 0xf4, 0xec, 0x7c, 0x86, ++ 0x73, 0x57, 0xc2, 0x52, 0x21, 0x73, 0x34, 0x5a, 0xf3, 0xa3, 0x8a, 0x56, 0xc8, ++ 0x04, 0xda, 0x07, 0x09, 0xed, 0xf8, 0x8b, 0xe3, 0xce, 0xf4, 0x7e, 0x8e, 0xae, ++ 0xf0, 0xf6, 0x0b, 0x8a, 0x08, 0xfb, 0x3f, 0xc9, 0x1d, 0x72, 0x7f, 0x53, 0xb8, ++ 0xeb, 0xbe, 0x63, 0xe0, 0xe3, 0x3d, 0x31, 0x65, 0xb0, 0x81, 0xe5, 0xf2, 0xac, ++ 0xcd, 0x16, 0xa4, 0x9f, 0x3d, 0xa8, 0xb1, 0x9b, 0xc2, 0x42, 0xd0, 0x90, 0x84, ++ 0x5f, 0x54, 0x1d, 0xff, 0x89, 0xea, 0xba, 0x1d, 0x47, 0x90, 0x6f, 0xb0, 0x73, ++ 0x4e, 0x41, 0x9f, 0x40, 0x9f, 0x5f, 0xe5, 0xa1, 0x2a, 0xb2, 0x11, 0x91, 0x73, ++ 0x8a, 0x21, 0x28, 0xf0, 0xce, 0xde, 0x73, 0x39, 0x5f, 0x3e, 0xab, 0x5c, 0x60, ++ 0xec, 0xdf, 0x03, 0x10, 0xa8, 0xd3, 0x09, 0xe9, 0xf4, 0xf6, 0x96, 0x85, 0xb6, ++ 0x7f, 0x51, 0x88, 0x66, 0x47, 0x19, 0x8d, 0xa2, 0xb0, 0x12, 0x3d, 0x81, 0x2a, ++ 0x68, 0x05, 0x77, 0xbb, 0x91, 0x4c, 0x62, 0x7b, 0xb6, 0xc1, 0x07, 0xc7, 0xba, ++ 0x7a, 0x87, 0x34, 0x03, 0x0e, 0x4b, 0x62, 0x7a, 0x99, 0xe9, 0xca, 0xfc, 0xce, ++ 0x4a, 0x37, 0xc9, 0x2d, 0xa4, 0x57, 0x7c, 0x1c, 0xfe, 0x3d, 0xdc, 0xb8, 0x0f, ++ 0x5a, 0xfa, 0xd6, 0xc4, 0xb3, 0x02, 0x85, 0x02, 0x3a, 0xea, 0xb3, 0xd9, 0x6e, ++ 0xe4, 0x69, 0x21, 0x37, 0xde, 0x81, 0xd1, 0xf6, 0x75, 0x19, 0x05, 0x67, 0xd3, ++ 0x93, 0x57, 0x5e, 0x29, 0x1b, 0x39, 0xc8, 0xee, 0x2d, 0xe1, 0xcd, 0xe4, 0x45, ++ 0x73, 0x5b, 0xd0, 0xd2, 0xce, 0x7a, 0xab, 0x16, 0x19, 0x82, 0x46, 0x58, 0xd0, ++ 0x5e, 0x9d, 0x81, 0xb3, 0x67, 0xaf, 0x6c, 0x35, 0xf2, 0xbc, 0xe5, 0x3f, 0x24, ++ 0xe2, 0x35, 0xa2, 0x0a, 0x75, 0x06, 0xf6, 0x18, 0x56, 0x99, 0xd4, 0x78, 0x2c, ++ 0xd1, 0x05, 0x1b, 0xeb, 0xd0, 0x88, 0x01, 0x9d, 0xaa, 0x10, 0xf1, 0x05, 0xdf, ++ 0xba, 0x7e, 0x2c, 0x63, 0xb7, 0x06, 0x9b, 0x23, 0x21, 0xc4, 0xf9, 0x78, 0x6c, ++ 0xe2, 0x58, 0x17, 0x06, 0x36, 0x2b, 0x91, 0x12, 0x03, 0xcc, 0xa4, 0xd9, 0xf2, ++ 0x2d, 0xba, 0xf9, 0x94, 0x9d, 0x40, 0xed, 0x18, 0x45, 0xf1, 0xce, 0x8a, 0x5c, ++ 0x6b, 0x3e, 0xab, 0x03, 0xd3, 0x70, 0x18, 0x2a, 0x0a, 0x6a, 0xe0, 0x5f, 0x47, ++ 0xd1, 0xd5, 0x63, 0x0a, 0x32, 0xf2, 0xaf, 0xd7, 0x36, 0x1f, 0x2a, 0x70, 0x5a, ++ 0xe5, 0x42, 0x59, 0x08, 0x71, 0x4b, 0x57, 0xba, 0x7e, 0x83, 0x81, 0xf0, 0x21, ++ 0x3c, 0xf4, 0x1c, 0xc1, 0xc5, 0xb9, 0x90, 0x93, 0x0e, 0x88, 0x45, 0x93, 0x86, ++ 0xe9, 0xb1, 0x20, 0x99, 0xbe, 0x98, 0xcb, 0xc5, 0x95, 0xa4, 0x5d, 0x62, 0xd6, ++ 0xa0, 0x63, 0x08, 0x20, 0xbd, 0x75, 0x10, 0x77, 0x7d, 0x3d, 0xf3, 0x45, 0xb9, ++ 0x9f, 0x97, 0x9f, 0xcb, 0x57, 0x80, 0x6f, 0x33, 0xa9, 0x04, 0xcf, 0x77, 0xa4, ++ 0x62, 0x1c, 0x59, 0x7e ++}; ++ ++// ++// Second DB entry: "Microsoft Corporation UEFI CA 2011" ++// SHA1: 46:de:f6:3b:5c:e6:1c:f8:ba:0d:e2:e6:63:9c:10:19:d0:ed:14:f3 ++// ++// To verify the "shim" binary and PCI expansion ROMs with. ++// ++STATIC CONST UINT8 MicrosoftUefiCA[] = { ++ 0x30, 0x82, 0x06, 0x10, 0x30, 0x82, 0x03, 0xf8, 0xa0, 0x03, 0x02, 0x01, 0x02, ++ 0x02, 0x0a, 0x61, 0x08, 0xd3, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, ++ 0x00, 0x30, 0x81, 0x91, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, ++ 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, ++ 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, ++ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, ++ 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, ++ 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, ++ 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x3b, 0x30, ++ 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x4d, 0x69, 0x63, 0x72, 0x6f, ++ 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, ++ 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x50, 0x61, 0x72, ++ 0x74, 0x79, 0x20, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x70, 0x6c, 0x61, 0x63, ++ 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, ++ 0x36, 0x32, 0x37, 0x32, 0x31, 0x32, 0x32, 0x34, 0x35, 0x5a, 0x17, 0x0d, 0x32, ++ 0x36, 0x30, 0x36, 0x32, 0x37, 0x32, 0x31, 0x33, 0x32, 0x34, 0x35, 0x5a, 0x30, ++ 0x81, 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, ++ 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, ++ 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, ++ 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, ++ 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, ++ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, ++ 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x2b, 0x30, 0x29, 0x06, ++ 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, ++ 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, ++ 0x6e, 0x20, 0x55, 0x45, 0x46, 0x49, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, ++ 0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, ++ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, ++ 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x08, 0x6c, 0x4c, 0xc7, ++ 0x45, 0x09, 0x6a, 0x4b, 0x0c, 0xa4, 0xc0, 0x87, 0x7f, 0x06, 0x75, 0x0c, 0x43, ++ 0x01, 0x54, 0x64, 0xe0, 0x16, 0x7f, 0x07, 0xed, 0x92, 0x7d, 0x0b, 0xb2, 0x73, ++ 0xbf, 0x0c, 0x0a, 0xc6, 0x4a, 0x45, 0x61, 0xa0, 0xc5, 0x16, 0x2d, 0x96, 0xd3, ++ 0xf5, 0x2b, 0xa0, 0xfb, 0x4d, 0x49, 0x9b, 0x41, 0x80, 0x90, 0x3c, 0xb9, 0x54, ++ 0xfd, 0xe6, 0xbc, 0xd1, 0x9d, 0xc4, 0xa4, 0x18, 0x8a, 0x7f, 0x41, 0x8a, 0x5c, ++ 0x59, 0x83, 0x68, 0x32, 0xbb, 0x8c, 0x47, 0xc9, 0xee, 0x71, 0xbc, 0x21, 0x4f, ++ 0x9a, 0x8a, 0x7c, 0xff, 0x44, 0x3f, 0x8d, 0x8f, 0x32, 0xb2, 0x26, 0x48, 0xae, ++ 0x75, 0xb5, 0xee, 0xc9, 0x4c, 0x1e, 0x4a, 0x19, 0x7e, 0xe4, 0x82, 0x9a, 0x1d, ++ 0x78, 0x77, 0x4d, 0x0c, 0xb0, 0xbd, 0xf6, 0x0f, 0xd3, 0x16, 0xd3, 0xbc, 0xfa, ++ 0x2b, 0xa5, 0x51, 0x38, 0x5d, 0xf5, 0xfb, 0xba, 0xdb, 0x78, 0x02, 0xdb, 0xff, ++ 0xec, 0x0a, 0x1b, 0x96, 0xd5, 0x83, 0xb8, 0x19, 0x13, 0xe9, 0xb6, 0xc0, 0x7b, ++ 0x40, 0x7b, 0xe1, 0x1f, 0x28, 0x27, 0xc9, 0xfa, 0xef, 0x56, 0x5e, 0x1c, 0xe6, ++ 0x7e, 0x94, 0x7e, 0xc0, 0xf0, 0x44, 0xb2, 0x79, 0x39, 0xe5, 0xda, 0xb2, 0x62, ++ 0x8b, 0x4d, 0xbf, 0x38, 0x70, 0xe2, 0x68, 0x24, 0x14, 0xc9, 0x33, 0xa4, 0x08, ++ 0x37, 0xd5, 0x58, 0x69, 0x5e, 0xd3, 0x7c, 0xed, 0xc1, 0x04, 0x53, 0x08, 0xe7, ++ 0x4e, 0xb0, 0x2a, 0x87, 0x63, 0x08, 0x61, 0x6f, 0x63, 0x15, 0x59, 0xea, 0xb2, ++ 0x2b, 0x79, 0xd7, 0x0c, 0x61, 0x67, 0x8a, 0x5b, 0xfd, 0x5e, 0xad, 0x87, 0x7f, ++ 0xba, 0x86, 0x67, 0x4f, 0x71, 0x58, 0x12, 0x22, 0x04, 0x22, 0x22, 0xce, 0x8b, ++ 0xef, 0x54, 0x71, 0x00, 0xce, 0x50, 0x35, 0x58, 0x76, 0x95, 0x08, 0xee, 0x6a, ++ 0xb1, 0xa2, 0x01, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x76, ++ 0x30, 0x82, 0x01, 0x72, 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, ++ 0x82, 0x37, 0x15, 0x01, 0x04, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x23, ++ 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x02, 0x04, 0x16, ++ 0x04, 0x14, 0xf8, 0xc1, 0x6b, 0xb7, 0x7f, 0x77, 0x53, 0x4a, 0xf3, 0x25, 0x37, ++ 0x1d, 0x4e, 0xa1, 0x26, 0x7b, 0x0f, 0x20, 0x70, 0x80, 0x30, 0x1d, 0x06, 0x03, ++ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x13, 0xad, 0xbf, 0x43, 0x09, 0xbd, ++ 0x82, 0x70, 0x9c, 0x8c, 0xd5, 0x4f, 0x31, 0x6e, 0xd5, 0x22, 0x98, 0x8a, 0x1b, ++ 0xd4, 0x30, 0x19, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, ++ 0x02, 0x04, 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, ++ 0x00, 0x41, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, ++ 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, ++ 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, ++ 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0x66, 0x52, 0x43, 0xe1, 0x7e, 0x58, ++ 0x11, 0xbf, 0xd6, 0x4e, 0x9e, 0x23, 0x55, 0x08, 0x3b, 0x3a, 0x22, 0x6a, 0xa8, ++ 0x30, 0x5c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x55, 0x30, 0x53, 0x30, 0x51, ++ 0xa0, 0x4f, 0xa0, 0x4d, 0x86, 0x4b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, ++ 0x63, 0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, ++ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x72, 0x6c, 0x2f, ++ 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, ++ 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, ++ 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, ++ 0x63, 0x72, 0x6c, 0x30, 0x60, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, ++ 0x01, 0x01, 0x04, 0x54, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01, ++ 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, ++ 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, ++ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x63, 0x65, 0x72, ++ 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x43, 0x6f, 0x72, 0x54, 0x68, 0x69, 0x50, ++ 0x61, 0x72, 0x4d, 0x61, 0x72, 0x52, 0x6f, 0x6f, 0x5f, 0x32, 0x30, 0x31, 0x30, ++ 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, ++ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, ++ 0x82, 0x02, 0x01, 0x00, 0x35, 0x08, 0x42, 0xff, 0x30, 0xcc, 0xce, 0xf7, 0x76, ++ 0x0c, 0xad, 0x10, 0x68, 0x58, 0x35, 0x29, 0x46, 0x32, 0x76, 0x27, 0x7c, 0xef, ++ 0x12, 0x41, 0x27, 0x42, 0x1b, 0x4a, 0xaa, 0x6d, 0x81, 0x38, 0x48, 0x59, 0x13, ++ 0x55, 0xf3, 0xe9, 0x58, 0x34, 0xa6, 0x16, 0x0b, 0x82, 0xaa, 0x5d, 0xad, 0x82, ++ 0xda, 0x80, 0x83, 0x41, 0x06, 0x8f, 0xb4, 0x1d, 0xf2, 0x03, 0xb9, 0xf3, 0x1a, ++ 0x5d, 0x1b, 0xf1, 0x50, 0x90, 0xf9, 0xb3, 0x55, 0x84, 0x42, 0x28, 0x1c, 0x20, ++ 0xbd, 0xb2, 0xae, 0x51, 0x14, 0xc5, 0xc0, 0xac, 0x97, 0x95, 0x21, 0x1c, 0x90, ++ 0xdb, 0x0f, 0xfc, 0x77, 0x9e, 0x95, 0x73, 0x91, 0x88, 0xca, 0xbd, 0xbd, 0x52, ++ 0xb9, 0x05, 0x50, 0x0d, 0xdf, 0x57, 0x9e, 0xa0, 0x61, 0xed, 0x0d, 0xe5, 0x6d, ++ 0x25, 0xd9, 0x40, 0x0f, 0x17, 0x40, 0xc8, 0xce, 0xa3, 0x4a, 0xc2, 0x4d, 0xaf, ++ 0x9a, 0x12, 0x1d, 0x08, 0x54, 0x8f, 0xbd, 0xc7, 0xbc, 0xb9, 0x2b, 0x3d, 0x49, ++ 0x2b, 0x1f, 0x32, 0xfc, 0x6a, 0x21, 0x69, 0x4f, 0x9b, 0xc8, 0x7e, 0x42, 0x34, ++ 0xfc, 0x36, 0x06, 0x17, 0x8b, 0x8f, 0x20, 0x40, 0xc0, 0xb3, 0x9a, 0x25, 0x75, ++ 0x27, 0xcd, 0xc9, 0x03, 0xa3, 0xf6, 0x5d, 0xd1, 0xe7, 0x36, 0x54, 0x7a, 0xb9, ++ 0x50, 0xb5, 0xd3, 0x12, 0xd1, 0x07, 0xbf, 0xbb, 0x74, 0xdf, 0xdc, 0x1e, 0x8f, ++ 0x80, 0xd5, 0xed, 0x18, 0xf4, 0x2f, 0x14, 0x16, 0x6b, 0x2f, 0xde, 0x66, 0x8c, ++ 0xb0, 0x23, 0xe5, 0xc7, 0x84, 0xd8, 0xed, 0xea, 0xc1, 0x33, 0x82, 0xad, 0x56, ++ 0x4b, 0x18, 0x2d, 0xf1, 0x68, 0x95, 0x07, 0xcd, 0xcf, 0xf0, 0x72, 0xf0, 0xae, ++ 0xbb, 0xdd, 0x86, 0x85, 0x98, 0x2c, 0x21, 0x4c, 0x33, 0x2b, 0xf0, 0x0f, 0x4a, ++ 0xf0, 0x68, 0x87, 0xb5, 0x92, 0x55, 0x32, 0x75, 0xa1, 0x6a, 0x82, 0x6a, 0x3c, ++ 0xa3, 0x25, 0x11, 0xa4, 0xed, 0xad, 0xd7, 0x04, 0xae, 0xcb, 0xd8, 0x40, 0x59, ++ 0xa0, 0x84, 0xd1, 0x95, 0x4c, 0x62, 0x91, 0x22, 0x1a, 0x74, 0x1d, 0x8c, 0x3d, ++ 0x47, 0x0e, 0x44, 0xa6, 0xe4, 0xb0, 0x9b, 0x34, 0x35, 0xb1, 0xfa, 0xb6, 0x53, ++ 0xa8, 0x2c, 0x81, 0xec, 0xa4, 0x05, 0x71, 0xc8, 0x9d, 0xb8, 0xba, 0xe8, 0x1b, ++ 0x44, 0x66, 0xe4, 0x47, 0x54, 0x0e, 0x8e, 0x56, 0x7f, 0xb3, 0x9f, 0x16, 0x98, ++ 0xb2, 0x86, 0xd0, 0x68, 0x3e, 0x90, 0x23, 0xb5, 0x2f, 0x5e, 0x8f, 0x50, 0x85, ++ 0x8d, 0xc6, 0x8d, 0x82, 0x5f, 0x41, 0xa1, 0xf4, 0x2e, 0x0d, 0xe0, 0x99, 0xd2, ++ 0x6c, 0x75, 0xe4, 0xb6, 0x69, 0xb5, 0x21, 0x86, 0xfa, 0x07, 0xd1, 0xf6, 0xe2, ++ 0x4d, 0xd1, 0xda, 0xad, 0x2c, 0x77, 0x53, 0x1e, 0x25, 0x32, 0x37, 0xc7, 0x6c, ++ 0x52, 0x72, 0x95, 0x86, 0xb0, 0xf1, 0x35, 0x61, 0x6a, 0x19, 0xf5, 0xb2, 0x3b, ++ 0x81, 0x50, 0x56, 0xa6, 0x32, 0x2d, 0xfe, 0xa2, 0x89, 0xf9, 0x42, 0x86, 0x27, ++ 0x18, 0x55, 0xa1, 0x82, 0xca, 0x5a, 0x9b, 0xf8, 0x30, 0x98, 0x54, 0x14, 0xa6, ++ 0x47, 0x96, 0x25, 0x2f, 0xc8, 0x26, 0xe4, 0x41, 0x94, 0x1a, 0x5c, 0x02, 0x3f, ++ 0xe5, 0x96, 0xe3, 0x85, 0x5b, 0x3c, 0x3e, 0x3f, 0xbb, 0x47, 0x16, 0x72, 0x55, ++ 0xe2, 0x25, 0x22, 0xb1, 0xd9, 0x7b, 0xe7, 0x03, 0x06, 0x2a, 0xa3, 0xf7, 0x1e, ++ 0x90, 0x46, 0xc3, 0x00, 0x0d, 0xd6, 0x19, 0x89, 0xe3, 0x0e, 0x35, 0x27, 0x62, ++ 0x03, 0x71, 0x15, 0xa6, 0xef, 0xd0, 0x27, 0xa0, 0xa0, 0x59, 0x37, 0x60, 0xf8, ++ 0x38, 0x94, 0xb8, 0xe0, 0x78, 0x70, 0xf8, 0xba, 0x4c, 0x86, 0x87, 0x94, 0xf6, ++ 0xe0, 0xae, 0x02, 0x45, 0xee, 0x65, 0xc2, 0xb6, 0xa3, 0x7e, 0x69, 0x16, 0x75, ++ 0x07, 0x92, 0x9b, 0xf5, 0xa6, 0xbc, 0x59, 0x83, 0x58 ++}; ++ ++// ++// The Microsoft.UefiSecureBootLogo.Tests.OutOfBoxConfirmDBXisPresent test case ++// of the Secure Boot Logo Test in the Microsoft Hardware Certification Kit ++// expects that the "dbx" variable exist. ++// ++// The article at https://technet.microsoft.com/en-us/library/dn747883.aspx ++// writes (excerpt): ++// ++// Windows 8.1 Secure Boot Key Creation and Management Guidance ++// 1. Secure Boot, Windows 8.1 and Key Management ++// 1.4 Signature Databases (Db and Dbx) ++// 1.4.3 Forbidden Signature Database (dbx) ++// ++// The contents of EFI_IMAGE_SIGNATURE_DATABASE1 dbx must be checked when ++// verifying images before checking db and any matches must prevent the ++// image from executing. The database may contain multiple certificates, ++// keys, and hashes in order to identify forbidden images. The Windows ++// Hardware Certification Requirements state that a dbx must be present, so ++// any dummy value, such as the SHA-256 hash of 0, may be used as a safe ++// placeholder until such time as Microsoft begins delivering dbx updates. ++// ++// The byte array below captures the SHA256 checksum of the empty file, ++// blacklisting it for loading & execution. This qualifies as a dummy, since ++// the empty file is not a valid UEFI binary anyway. ++// ++// Technically speaking, we could also capture an official (although soon to be ++// obsolete) dbx update from http://www.uefi.org/revocationlistfile. However, ++// the terms and conditions on distributing that binary aren't exactly light ++// reading, so let's best steer clear of it, and follow the "dummy entry" ++// practice recommended -- in natural English langauge -- in the ++// above-referenced TechNet article. ++// ++STATIC CONST UINT8 mSha256OfDevNull[] = { ++ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, ++ 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, ++ 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 ++}; ++ ++// ++// The following test cases of the Secure Boot Logo Test in the Microsoft ++// Hardware Certification Kit: ++// ++// - Microsoft.UefiSecureBootLogo.Tests.OutOfBoxVerifyMicrosoftKEKpresent ++// - Microsoft.UefiSecureBootLogo.Tests.OutOfBoxConfirmMicrosoftSignatureInDB ++// ++// expect the EFI_SIGNATURE_DATA.SignatureOwner GUID to be ++// 77FA9ABD-0359-4D32-BD60-28F4E78F784B, when the ++// EFI_SIGNATURE_DATA.SignatureData field carries any of the following X509 ++// certificates: ++// ++// - "Microsoft Corporation KEK CA 2011" (in KEK) ++// - "Microsoft Windows Production PCA 2011" (in db) ++// - "Microsoft Corporation UEFI CA 2011" (in db) ++// ++// This is despite the fact that the UEFI specification requires ++// EFI_SIGNATURE_DATA.SignatureOwner to reflect the agent (i.e., OS, ++// application or driver) that enrolled and therefore owns ++// EFI_SIGNATURE_DATA.SignatureData, and not the organization that issued ++// EFI_SIGNATURE_DATA.SignatureData. ++// ++STATIC CONST EFI_GUID mMicrosoftOwnerGuid = { ++ 0x77fa9abd, 0x0359, 0x4d32, ++ { 0xbd, 0x60, 0x28, 0xf4, 0xe7, 0x8f, 0x78, 0x4b }, ++}; ++ ++// ++// The most important thing about the variable payload is that it is a list of ++// lists, where the element size of any given *inner* list is constant. ++// ++// Since X509 certificates vary in size, each of our *inner* lists will contain ++// one element only (one X.509 certificate). This is explicitly mentioned in ++// the UEFI specification, in "28.4.1 Signature Database", in a Note. ++// ++// The list structure looks as follows: ++// ++// struct EFI_VARIABLE_AUTHENTICATION_2 { | ++// struct EFI_TIME { | ++// UINT16 Year; | ++// UINT8 Month; | ++// UINT8 Day; | ++// UINT8 Hour; | ++// UINT8 Minute; | ++// UINT8 Second; | ++// UINT8 Pad1; | ++// UINT32 Nanosecond; | ++// INT16 TimeZone; | ++// UINT8 Daylight; | ++// UINT8 Pad2; | ++// } TimeStamp; | ++// | ++// struct WIN_CERTIFICATE_UEFI_GUID { | | ++// struct WIN_CERTIFICATE { | | ++// UINT32 dwLength; ----------------------------------------+ | ++// UINT16 wRevision; | | ++// UINT16 wCertificateType; | | ++// } Hdr; | +- DataSize ++// | | ++// EFI_GUID CertType; | | ++// UINT8 CertData[1] = { <--- "struct hack" | | ++// struct EFI_SIGNATURE_LIST { | | | ++// EFI_GUID SignatureType; | | | ++// UINT32 SignatureListSize; -------------------------+ | | ++// UINT32 SignatureHeaderSize; | | | ++// UINT32 SignatureSize; ---------------------------+ | | | ++// UINT8 SignatureHeader[SignatureHeaderSize]; | | | | ++// v | | | ++// struct EFI_SIGNATURE_DATA { | | | | ++// EFI_GUID SignatureOwner; | | | | ++// UINT8 SignatureData[1] = { <--- "struct hack" | | | | ++// X.509 payload | | | | ++// } | | | | ++// } Signatures[]; | | | ++// } SigLists[]; | | ++// }; | | ++// } AuthInfo; | | ++// }; | ++// ++// Given that the "struct hack" invokes undefined behavior (which is why C99 ++// introduced the flexible array member), and because subtracting those pesky ++// sizes of 1 is annoying, and because the format is fully specified in the ++// UEFI specification, we'll introduce two matching convenience structures that ++// are customized for our X.509 purposes. ++// ++#pragma pack(1) ++typedef struct { ++ EFI_TIME TimeStamp; ++ ++ // ++ // dwLength covers data below ++ // ++ UINT32 dwLength; ++ UINT16 wRevision; ++ UINT16 wCertificateType; ++ EFI_GUID CertType; ++} SINGLE_HEADER; ++ ++typedef struct { ++ // ++ // SignatureListSize covers data below ++ // ++ EFI_GUID SignatureType; ++ UINT32 SignatureListSize; ++ UINT32 SignatureHeaderSize; // constant 0 ++ UINT32 SignatureSize; ++ ++ // ++ // SignatureSize covers data below ++ // ++ EFI_GUID SignatureOwner; ++ ++ // ++ // X.509 certificate follows ++ // ++} REPEATING_HEADER; ++#pragma pack() ++ ++/** ++ Enroll a set of certificates in a global variable, overwriting it. ++ ++ The variable will be rewritten with NV+BS+RT+AT attributes. ++ ++ @param[in] VariableName The name of the variable to overwrite. ++ ++ @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable to ++ overwrite. ++ ++ @param[in] CertType The GUID determining the type of all the ++ certificates in the set that is passed in. For ++ example, gEfiCertX509Guid stands for DER-encoded ++ X.509 certificates, while gEfiCertSha256Guid stands ++ for SHA256 image hashes. ++ ++ @param[in] ... A list of ++ ++ IN CONST UINT8 *Cert, ++ IN UINTN CertSize, ++ IN CONST EFI_GUID *OwnerGuid ++ ++ triplets. If the first component of a triplet is ++ NULL, then the other two components are not ++ accessed, and processing is terminated. The list of ++ certificates is enrolled in the variable specified, ++ overwriting it. The OwnerGuid component identifies ++ the agent installing the certificate. ++ ++ @retval EFI_INVALID_PARAMETER The triplet list is empty (ie. the first Cert ++ value is NULL), or one of the CertSize values ++ is 0, or one of the CertSize values would ++ overflow the accumulated UINT32 data size. ++ ++ @retval EFI_OUT_OF_RESOURCES Out of memory while formatting variable ++ payload. ++ ++ @retval EFI_SUCCESS Enrollment successful; the variable has been ++ overwritten (or created). ++ ++ @return Error codes from gRT->GetTime() and ++ gRT->SetVariable(). ++**/ ++STATIC ++EFI_STATUS ++EFIAPI ++EnrollListOfCerts ( ++ IN CHAR16 *VariableName, ++ IN EFI_GUID *VendorGuid, ++ IN EFI_GUID *CertType, ++ ... ++ ) ++{ ++ UINTN DataSize; ++ SINGLE_HEADER *SingleHeader; ++ REPEATING_HEADER *RepeatingHeader; ++ VA_LIST Marker; ++ CONST UINT8 *Cert; ++ EFI_STATUS Status; ++ UINT8 *Data; ++ UINT8 *Position; ++ ++ Status = EFI_SUCCESS; ++ ++ // ++ // compute total size first, for UINT32 range check, and allocation ++ // ++ DataSize = sizeof *SingleHeader; ++ VA_START (Marker, CertType); ++ for (Cert = VA_ARG (Marker, CONST UINT8 *); ++ Cert != NULL; ++ Cert = VA_ARG (Marker, CONST UINT8 *)) { ++ UINTN CertSize; ++ ++ CertSize = VA_ARG (Marker, UINTN); ++ (VOID)VA_ARG (Marker, CONST EFI_GUID *); ++ ++ if (CertSize == 0 || ++ CertSize > MAX_UINT32 - sizeof *RepeatingHeader || ++ DataSize > MAX_UINT32 - sizeof *RepeatingHeader - CertSize) { ++ Status = EFI_INVALID_PARAMETER; ++ break; ++ } ++ DataSize += sizeof *RepeatingHeader + CertSize; ++ } ++ VA_END (Marker); ++ ++ if (DataSize == sizeof *SingleHeader) { ++ Status = EFI_INVALID_PARAMETER; ++ } ++ if (EFI_ERROR (Status)) { ++ goto Out; ++ } ++ ++ Data = AllocatePool (DataSize); ++ if (Data == NULL) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto Out; ++ } ++ ++ Position = Data; ++ ++ SingleHeader = (SINGLE_HEADER *)Position; ++ Status = gRT->GetTime (&SingleHeader->TimeStamp, NULL); ++ if (EFI_ERROR (Status)) { ++ goto FreeData; ++ } ++ SingleHeader->TimeStamp.Pad1 = 0; ++ SingleHeader->TimeStamp.Nanosecond = 0; ++ SingleHeader->TimeStamp.TimeZone = 0; ++ SingleHeader->TimeStamp.Daylight = 0; ++ SingleHeader->TimeStamp.Pad2 = 0; ++#if 0 ++ SingleHeader->dwLength = DataSize - sizeof SingleHeader->TimeStamp; ++#else ++ // ++ // This looks like a bug in edk2. According to the UEFI specification, ++ // dwLength is "The length of the entire certificate, including the length of ++ // the header, in bytes". That shouldn't stop right after CertType -- it ++ // should include everything below it. ++ // ++ SingleHeader->dwLength = sizeof *SingleHeader ++ - sizeof SingleHeader->TimeStamp; ++#endif ++ SingleHeader->wRevision = 0x0200; ++ SingleHeader->wCertificateType = WIN_CERT_TYPE_EFI_GUID; ++ CopyGuid (&SingleHeader->CertType, &gEfiCertPkcs7Guid); ++ Position += sizeof *SingleHeader; ++ ++ VA_START (Marker, CertType); ++ for (Cert = VA_ARG (Marker, CONST UINT8 *); ++ Cert != NULL; ++ Cert = VA_ARG (Marker, CONST UINT8 *)) { ++ UINTN CertSize; ++ CONST EFI_GUID *OwnerGuid; ++ ++ CertSize = VA_ARG (Marker, UINTN); ++ OwnerGuid = VA_ARG (Marker, CONST EFI_GUID *); ++ ++ RepeatingHeader = (REPEATING_HEADER *)Position; ++ CopyGuid (&RepeatingHeader->SignatureType, CertType); ++ RepeatingHeader->SignatureListSize = ++ (UINT32)(sizeof *RepeatingHeader + CertSize); ++ RepeatingHeader->SignatureHeaderSize = 0; ++ RepeatingHeader->SignatureSize = ++ (UINT32)(sizeof RepeatingHeader->SignatureOwner + CertSize); ++ CopyGuid (&RepeatingHeader->SignatureOwner, OwnerGuid); ++ Position += sizeof *RepeatingHeader; ++ ++ CopyMem (Position, Cert, CertSize); ++ Position += CertSize; ++ } ++ VA_END (Marker); ++ ++ ASSERT (Data + DataSize == Position); ++ ++ Status = gRT->SetVariable (VariableName, VendorGuid, ++ (EFI_VARIABLE_NON_VOLATILE | ++ EFI_VARIABLE_BOOTSERVICE_ACCESS | ++ EFI_VARIABLE_RUNTIME_ACCESS | ++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS), ++ DataSize, Data); ++ ++FreeData: ++ FreePool (Data); ++ ++Out: ++ if (EFI_ERROR (Status)) { ++ AsciiPrint ("error: %a("%s", %g): %r\n", __FUNCTION__, VariableName, ++ VendorGuid, Status); ++ } ++ return Status; ++} ++ ++ ++STATIC ++EFI_STATUS ++EFIAPI ++GetExact ( ++ IN CHAR16 *VariableName, ++ IN EFI_GUID *VendorGuid, ++ OUT VOID *Data, ++ IN UINTN DataSize, ++ IN BOOLEAN AllowMissing ++ ) ++{ ++ UINTN Size; ++ EFI_STATUS Status; ++ ++ Size = DataSize; ++ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &Size, Data); ++ if (EFI_ERROR (Status)) { ++ if (Status == EFI_NOT_FOUND && AllowMissing) { ++ ZeroMem (Data, DataSize); ++ return EFI_SUCCESS; ++ } ++ ++ AsciiPrint ("error: GetVariable("%s", %g): %r\n", VariableName, ++ VendorGuid, Status); ++ return Status; ++ } ++ ++ if (Size != DataSize) { ++ AsciiPrint ("error: GetVariable("%s", %g): expected size 0x%Lx, " ++ "got 0x%Lx\n", VariableName, VendorGuid, (UINT64)DataSize, (UINT64)Size); ++ return EFI_PROTOCOL_ERROR; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++typedef struct { ++ UINT8 SetupMode; ++ UINT8 SecureBoot; ++ UINT8 SecureBootEnable; ++ UINT8 CustomMode; ++ UINT8 VendorKeys; ++} SETTINGS; ++ ++STATIC ++EFI_STATUS ++EFIAPI ++GetSettings ( ++ OUT SETTINGS *Settings ++ ) ++{ ++ EFI_STATUS Status; ++ ++ Status = GetExact (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, ++ &Settings->SetupMode, sizeof Settings->SetupMode, FALSE); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ Status = GetExact (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, ++ &Settings->SecureBoot, sizeof Settings->SecureBoot, FALSE); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ Status = GetExact (EFI_SECURE_BOOT_ENABLE_NAME, ++ &gEfiSecureBootEnableDisableGuid, &Settings->SecureBootEnable, ++ sizeof Settings->SecureBootEnable, TRUE); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ Status = GetExact (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, ++ &Settings->CustomMode, sizeof Settings->CustomMode, FALSE); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ Status = GetExact (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid, ++ &Settings->VendorKeys, sizeof Settings->VendorKeys, FALSE); ++ return Status; ++} ++ ++STATIC ++VOID ++EFIAPI ++PrintSettings ( ++ IN CONST SETTINGS *Settings ++ ) ++{ ++ AsciiPrint ("info: SetupMode=%d SecureBoot=%d SecureBootEnable=%d " ++ "CustomMode=%d VendorKeys=%d\n", Settings->SetupMode, Settings->SecureBoot, ++ Settings->SecureBootEnable, Settings->CustomMode, Settings->VendorKeys); ++} ++ ++ ++INTN ++EFIAPI ++ShellAppMain ( ++ IN UINTN Argc, ++ IN CHAR16 **Argv ++ ) ++{ ++ EFI_STATUS Status; ++ SETTINGS Settings; ++ ++ Status = GetSettings (&Settings); ++ if (EFI_ERROR (Status)) { ++ return 1; ++ } ++ PrintSettings (&Settings); ++ ++ if (Settings.SetupMode != 1) { ++ AsciiPrint ("error: already in User Mode\n"); ++ return 1; ++ } ++ ++ if (Settings.CustomMode != CUSTOM_SECURE_BOOT_MODE) { ++ Settings.CustomMode = CUSTOM_SECURE_BOOT_MODE; ++ Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, ++ (EFI_VARIABLE_NON_VOLATILE | ++ EFI_VARIABLE_BOOTSERVICE_ACCESS), ++ sizeof Settings.CustomMode, &Settings.CustomMode); ++ if (EFI_ERROR (Status)) { ++ AsciiPrint ("error: SetVariable("%s", %g): %r\n", EFI_CUSTOM_MODE_NAME, ++ &gEfiCustomModeEnableGuid, Status); ++ return 1; ++ } ++ } ++ ++ Status = EnrollListOfCerts ( ++ EFI_IMAGE_SECURITY_DATABASE, ++ &gEfiImageSecurityDatabaseGuid, ++ &gEfiCertX509Guid, ++ MicrosoftPCA, sizeof MicrosoftPCA, &mMicrosoftOwnerGuid, ++ MicrosoftUefiCA, sizeof MicrosoftUefiCA, &mMicrosoftOwnerGuid, ++ NULL); ++ if (EFI_ERROR (Status)) { ++ return 1; ++ } ++ ++ Status = EnrollListOfCerts ( ++ EFI_IMAGE_SECURITY_DATABASE1, ++ &gEfiImageSecurityDatabaseGuid, ++ &gEfiCertSha256Guid, ++ mSha256OfDevNull, sizeof mSha256OfDevNull, &gEfiCallerIdGuid, ++ NULL); ++ if (EFI_ERROR (Status)) { ++ return 1; ++ } ++ ++ Status = EnrollListOfCerts ( ++ EFI_KEY_EXCHANGE_KEY_NAME, ++ &gEfiGlobalVariableGuid, ++ &gEfiCertX509Guid, ++ RedHatPkKek1, sizeof RedHatPkKek1, &gEfiCallerIdGuid, ++ MicrosoftKEK, sizeof MicrosoftKEK, &mMicrosoftOwnerGuid, ++ NULL); ++ if (EFI_ERROR (Status)) { ++ return 1; ++ } ++ ++ Status = EnrollListOfCerts ( ++ EFI_PLATFORM_KEY_NAME, ++ &gEfiGlobalVariableGuid, ++ &gEfiCertX509Guid, ++ RedHatPkKek1, sizeof RedHatPkKek1, &gEfiGlobalVariableGuid, ++ NULL); ++ if (EFI_ERROR (Status)) { ++ return 1; ++ } ++ ++ Settings.CustomMode = STANDARD_SECURE_BOOT_MODE; ++ Status = gRT->SetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, ++ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, ++ sizeof Settings.CustomMode, &Settings.CustomMode); ++ if (EFI_ERROR (Status)) { ++ AsciiPrint ("error: SetVariable("%s", %g): %r\n", EFI_CUSTOM_MODE_NAME, ++ &gEfiCustomModeEnableGuid, Status); ++ return 1; ++ } ++ ++ Status = GetSettings (&Settings); ++ if (EFI_ERROR (Status)) { ++ return 1; ++ } ++ PrintSettings (&Settings); ++ ++ if (Settings.SetupMode != 0 || Settings.SecureBoot != 1 || ++ Settings.SecureBootEnable != 1 || Settings.CustomMode != 0 || ++ Settings.VendorKeys != 0) { ++ AsciiPrint ("error: unexpected\n"); ++ return 1; ++ } ++ ++ AsciiPrint ("info: success\n"); ++ return 0; ++} +diff --git a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf +new file mode 100644 +index 0000000000..0ad86a2843 +--- /dev/null ++++ b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf +@@ -0,0 +1,52 @@ ++## @file ++# Enroll default PK, KEK, DB. ++# ++# Copyright (C) 2014, Red Hat, Inc. ++# ++# 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. ++# ++# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED. ++## ++ ++[Defines] ++ INF_VERSION = 0x00010006 ++ BASE_NAME = EnrollDefaultKeys ++ FILE_GUID = D5C1DF0B-1BAC-4EDF-BA48-08834009CA5A ++ MODULE_TYPE = UEFI_APPLICATION ++ VERSION_STRING = 0.1 ++ ENTRY_POINT = ShellCEntryLib ++ ++# ++# VALID_ARCHITECTURES = IA32 X64 ++# ++ ++[Sources] ++ EnrollDefaultKeys.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ MdeModulePkg/MdeModulePkg.dec ++ SecurityPkg/SecurityPkg.dec ++ ShellPkg/ShellPkg.dec ++ ++[Guids] ++ gEfiCertPkcs7Guid ++ gEfiCertSha256Guid ++ gEfiCertX509Guid ++ gEfiCustomModeEnableGuid ++ gEfiGlobalVariableGuid ++ gEfiImageSecurityDatabaseGuid ++ gEfiSecureBootEnableDisableGuid ++ ++[LibraryClasses] ++ BaseMemoryLib ++ DebugLib ++ MemoryAllocationLib ++ ShellCEntryLib ++ UefiLib ++ UefiRuntimeServicesTableLib +diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc +index 8dc3ad2be4..518f6db2c6 100644 +--- a/OvmfPkg/OvmfPkgIa32.dsc ++++ b/OvmfPkg/OvmfPkgIa32.dsc +@@ -876,6 +876,10 @@ + + !if $(SECURE_BOOT_ENABLE) == TRUE + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf ++ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf { ++ <LibraryClasses> ++ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf ++ } + !endif + + OvmfPkg/PlatformDxe/Platform.inf +diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc +index d81cd865d5..ed2f876e7e 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -885,6 +885,10 @@ + + !if $(SECURE_BOOT_ENABLE) == TRUE + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf ++ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf { ++ <LibraryClasses> ++ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf ++ } + !endif + + OvmfPkg/PlatformDxe/Platform.inf +diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc +index 85bd8d4bf6..a12905f882 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -883,6 +883,10 @@ + + !if $(SECURE_BOOT_ENABLE) == TRUE + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf ++ OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf { ++ <LibraryClasses> ++ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf ++ } + !endif + + OvmfPkg/PlatformDxe/Platform.inf diff --git a/0014-ArmPlatformPkg-introduce-fixed-PCD-for-early-hello-m.patch b/0014-ArmPlatformPkg-introduce-fixed-PCD-for-early-hello-m.patch new file mode 100644 index 0000000..3c9f001 --- /dev/null +++ b/0014-ArmPlatformPkg-introduce-fixed-PCD-for-early-hello-m.patch @@ -0,0 +1,55 @@ +From 6f89eae9f2abe20e35058848e7cc10a69a6b05ec Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 14 Oct 2015 13:49:43 +0200 +Subject: [PATCH] ArmPlatformPkg: introduce fixed PCD for early hello message + (RH only) + +Drew has proposed that ARM|AARCH64 platform firmware (especially virtual +machine firmware) print a reasonably early, simple hello message to the +serial port, regardless of debug mask settings. This should inform +interactive users, and provide some rough help in localizing boot +problems, even with restrictive debug masks. + +If a platform doesn't want this feature, it should stick with the default +empty string. + +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1270279 +Downstream only: +http://thread.gmane.org/gmane.comp.bios.edk2.devel/2996/focus=3433. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Suggested-by: Drew Jones drjones@redhat.com +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 7ce97b06421434c82095f01a1753a8c9c546cc30) +(cherry picked from commit 20b1f1cbd0590aa71c6d99d35e23cf08e0707750) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + ArmPlatformPkg/ArmPlatformPkg.dec | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec +index 5f67e74154..2956d3e2d8 100644 +--- a/ArmPlatformPkg/ArmPlatformPkg.dec ++++ b/ArmPlatformPkg/ArmPlatformPkg.dec +@@ -113,6 +113,13 @@ + ## If set, this will swap settings for HDLCD RED_SELECT and BLUE_SELECT registers + gArmPlatformTokenSpaceGuid.PcdArmHdLcdSwapBlueRedSelect|FALSE|BOOLEAN|0x00000045 + ++ # ++ # Early hello message (ASCII string), printed to the serial port. ++ # If set to the empty string, nothing is printed. ++ # Otherwise, a trailing CRLF should be specified explicitly. ++ # ++ gArmPlatformTokenSpaceGuid.PcdEarlyHelloMessage|""|VOID*|0x00000100 ++ + [PcdsFixedAtBuild.common,PcdsDynamic.common] + ## PL031 RealTimeClock + gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0x0|UINT32|0x00000024 diff --git a/0015-ArmPlatformPkg-PrePeiCore-write-early-hello-message-.patch b/0015-ArmPlatformPkg-PrePeiCore-write-early-hello-message-.patch new file mode 100644 index 0000000..32ce0b3 --- /dev/null +++ b/0015-ArmPlatformPkg-PrePeiCore-write-early-hello-message-.patch @@ -0,0 +1,103 @@ +From e6c0f362edd5834b0d891fc44cd6873566bb0df4 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 14 Oct 2015 13:59:20 +0200 +Subject: [PATCH] ArmPlatformPkg: PrePeiCore: write early hello message to the + serial port (RH) + +The FixedPcdGetSize() macro expands to an integer constant, therefore an +optimizing compiler can eliminate the new code, if the platform DSC +doesn't override the empty string (size=1) default of +PcdEarlyHelloMessage. + +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1270279 +Downstream only: +http://thread.gmane.org/gmane.comp.bios.edk2.devel/2996/focus=3433. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit b16c4c505ce0e27305235533eac9236aa66f132e) +(cherry picked from commit 742e5bf6d5ce5a1e73879d6e5c0dd00feda7a9ac) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + ArmPlatformPkg/PrePeiCore/MainMPCore.c | 5 +++++ + ArmPlatformPkg/PrePeiCore/MainUniCore.c | 5 +++++ + ArmPlatformPkg/PrePeiCore/PrePeiCore.h | 1 + + ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf | 2 ++ + ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf | 2 ++ + 5 files changed, 15 insertions(+) + +diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c +index dc47adbaff..cbd72232c7 100644 +--- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c ++++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c +@@ -117,6 +117,11 @@ PrimaryMain ( + UINTN TemporaryRamBase; + UINTN TemporaryRamSize; + ++ if (FixedPcdGetSize (PcdEarlyHelloMessage) > 1) { ++ SerialPortWrite (FixedPcdGetPtr (PcdEarlyHelloMessage), ++ FixedPcdGetSize (PcdEarlyHelloMessage) - 1); ++ } ++ + CreatePpiList (&PpiListSize, &PpiList); + + // Enable the GIC Distributor +diff --git a/ArmPlatformPkg/PrePeiCore/MainUniCore.c b/ArmPlatformPkg/PrePeiCore/MainUniCore.c +index 134a469427..af39fc017c 100644 +--- a/ArmPlatformPkg/PrePeiCore/MainUniCore.c ++++ b/ArmPlatformPkg/PrePeiCore/MainUniCore.c +@@ -35,6 +35,11 @@ PrimaryMain ( + UINTN TemporaryRamBase; + UINTN TemporaryRamSize; + ++ if (FixedPcdGetSize (PcdEarlyHelloMessage) > 1) { ++ SerialPortWrite (FixedPcdGetPtr (PcdEarlyHelloMessage), ++ FixedPcdGetSize (PcdEarlyHelloMessage) - 1); ++ } ++ + CreatePpiList (&PpiListSize, &PpiList); + + // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at +diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h +index 160894620c..bf843d7768 100644 +--- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h ++++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h +@@ -21,6 +21,7 @@ + #include <Library/DebugLib.h> + #include <Library/IoLib.h> + #include <Library/PcdLib.h> ++#include <Library/SerialPortLib.h> + + #include <PiPei.h> + #include <Ppi/TemporaryRamSupport.h> +diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf +index e3a31fa7c6..1bc0c45420 100644 +--- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf ++++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf +@@ -72,6 +72,8 @@ + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize + ++ gArmPlatformTokenSpaceGuid.PcdEarlyHelloMessage ++ + gArmTokenSpaceGuid.PcdGicDistributorBase + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase + gArmTokenSpaceGuid.PcdGicSgiIntId +diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf +index ec83cec2d8..20698fcfac 100644 +--- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf ++++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf +@@ -71,3 +71,5 @@ + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize + + gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack ++ ++ gArmPlatformTokenSpaceGuid.PcdEarlyHelloMessage diff --git a/0016-ArmVirtPkg-set-early-hello-message-RH-only.patch b/0016-ArmVirtPkg-set-early-hello-message-RH-only.patch new file mode 100644 index 0000000..35303e7 --- /dev/null +++ b/0016-ArmVirtPkg-set-early-hello-message-RH-only.patch @@ -0,0 +1,40 @@ +From e777f7d03c8a8d56e08926ecf0b17e1338837093 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 14 Oct 2015 14:07:17 +0200 +Subject: [PATCH] ArmVirtPkg: set early hello message (RH only) + +Print a friendly banner on QEMU, regardless of debug mask settings. + +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1270279 +Downstream only: +http://thread.gmane.org/gmane.comp.bios.edk2.devel/2996/focus=3433. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Contributed-under: TianoCore Contribution Agreement 1.0 +Signed-off-by: Laszlo Ersek lersek@redhat.com +(cherry picked from commit 5d4a15b9019728b2d96322bc679099da49916925) +(cherry picked from commit 179df76dbb0d199bd905236e98775b4059c6502a) +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +--- + ArmVirtPkg/ArmVirtQemu.dsc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc +index 86d5d5a666..ffe4ba8092 100644 +--- a/ArmVirtPkg/ArmVirtQemu.dsc ++++ b/ArmVirtPkg/ArmVirtQemu.dsc +@@ -87,6 +87,7 @@ + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE + + [PcdsFixedAtBuild.common] ++ gArmPlatformTokenSpaceGuid.PcdEarlyHelloMessage|"UEFI firmware starting.\r\n" + gArmPlatformTokenSpaceGuid.PcdCoreCount|1 + !if $(ARCH) == AARCH64 + gArmTokenSpaceGuid.PcdVFPEnabled|1 diff --git a/0017-BaseTools-footer.makefile-expand-BUILD_CFLAGS-last-f.patch b/0017-BaseTools-footer.makefile-expand-BUILD_CFLAGS-last-f.patch new file mode 100644 index 0000000..a1e5144 --- /dev/null +++ b/0017-BaseTools-footer.makefile-expand-BUILD_CFLAGS-last-f.patch @@ -0,0 +1,35 @@ +From eebbf279b59afa3787d11734d9707cc7ab24d651 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 25 Jul 2018 22:27:53 +0200 +Subject: [PATCH] BaseTools/footer.makefile: expand BUILD_CFLAGS last for C + files too + +BUILD_CPPFLAGS should be expanded before BUILD_CFLAGS. (The rule for C++ +source files already does this, with BUILD_CPPFLAGS and BUILD_CXXFLAGS.) + +This patch doesn't change behavior. + +Cc: Liming Gao liming.gao@intel.com +Cc: Yonghong Zhu yonghong.zhu@intel.com +Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1540244 +Contributed-under: TianoCore Contribution Agreement 1.1 +Signed-off-by: Laszlo Ersek lersek@redhat.com +Reviewed-by: Liming Gao liming.gao@intel.com +(cherry picked from commit 67983484a4430c5f82bb5f1397e010c759136321) +--- + BaseTools/Source/C/Makefiles/footer.makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/BaseTools/Source/C/Makefiles/footer.makefile b/BaseTools/Source/C/Makefiles/footer.makefile +index 0926aa9645..5bda9e4e36 100644 +--- a/BaseTools/Source/C/Makefiles/footer.makefile ++++ b/BaseTools/Source/C/Makefiles/footer.makefile +@@ -24,7 +24,7 @@ $(LIBRARY): $(OBJECTS) + $(BUILD_AR) crs $@ $^ + + %.o : %.c +- $(BUILD_CC) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $< -o $@ ++ $(BUILD_CC) -c $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) $< -o $@ + + %.o : %.cpp + $(BUILD_CXX) -c $(BUILD_CPPFLAGS) $(BUILD_CXXFLAGS) $< -o $@ diff --git a/0018-BaseTools-header.makefile-remove-c-from-BUILD_CFLAGS.patch b/0018-BaseTools-header.makefile-remove-c-from-BUILD_CFLAGS.patch new file mode 100644 index 0000000..0942d9e --- /dev/null +++ b/0018-BaseTools-header.makefile-remove-c-from-BUILD_CFLAGS.patch @@ -0,0 +1,40 @@ +From 0af592dfa9a6d1a3379db1331344f411f7774bea Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 25 Jul 2018 22:40:09 +0200 +Subject: [PATCH] BaseTools/header.makefile: remove "-c" from BUILD_CFLAGS + +Option "-c" is a mode selection flag (choosing between compiling and +linking); it should not be in BUILD_CFLAGS, which applies only to +compiling anyway. The compilation rule for C source files, in +"footer.makefile", already includes "-c" -- currently we have double "-c" +options. + +This patch doesn't change behavior. + +Cc: Liming Gao liming.gao@intel.com +Cc: Yonghong Zhu yonghong.zhu@intel.com +Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1540244 +Contributed-under: TianoCore Contribution Agreement 1.1 +Signed-off-by: Laszlo Ersek lersek@redhat.com +Reviewed-by: Liming Gao liming.gao@intel.com +(cherry picked from commit 03252ae287c4a61983b3793ff71baeabe2ff3df7) +--- + BaseTools/Source/C/Makefiles/header.makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile +index db436773cf..08421ba24c 100644 +--- a/BaseTools/Source/C/Makefiles/header.makefile ++++ b/BaseTools/Source/C/Makefiles/header.makefile +@@ -71,9 +71,9 @@ INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKE + BUILD_CPPFLAGS = $(INCLUDE) -O2 + ifeq ($(DARWIN),Darwin) + # assume clang or clang compatible flags on OS X +-BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-self-assign -Wno-unused-result -nostdlib -c -g ++BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-self-assign -Wno-unused-result -nostdlib -g + else +-BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-stringop-truncation -Wno-restrict -Wno-unused-result -nostdlib -c -g ++BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-stringop-truncation -Wno-restrict -Wno-unused-result -nostdlib -g + endif + BUILD_LFLAGS = + BUILD_CXXFLAGS = -Wno-unused-result diff --git a/0019-BaseTools-Source-C-split-O2-to-BUILD_OPTFLAGS.patch b/0019-BaseTools-Source-C-split-O2-to-BUILD_OPTFLAGS.patch new file mode 100644 index 0000000..52528d9 --- /dev/null +++ b/0019-BaseTools-Source-C-split-O2-to-BUILD_OPTFLAGS.patch @@ -0,0 +1,87 @@ +From 67c8bbaf89bbb4015f0b915fed6fb2f35efd282f Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Wed, 25 Jul 2018 22:59:57 +0200 +Subject: [PATCH] BaseTools/Source/C: split "-O2" to BUILD_OPTFLAGS + +The option "-O2" is not a preprocessor flag, but a code generation +(compilation) flag. Move it from BUILD_CPPFLAGS to BUILD_CFLAGS and +BUILD_CXXFLAGS. + +Because "VfrCompile/GNUmakefile" uses "-O2" through BUILD_CPPFLAGS, and +because it doesn't use BUILD_CXXFLAGS, we have to introduce BUILD_OPTFLAGS +separately, so that "VfrCompile/GNUmakefile" can continue using just this +flag. + +This patch doesn't change behavior. + +Cc: Liming Gao liming.gao@intel.com +Cc: Yonghong Zhu yonghong.zhu@intel.com +Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1540244 +Contributed-under: TianoCore Contribution Agreement 1.1 +Signed-off-by: Laszlo Ersek lersek@redhat.com +Reviewed-by: Liming Gao liming.gao@intel.com +(cherry picked from commit b8a66170264395edeaa61e6d22930a58e576a685) +--- + BaseTools/Source/C/Makefiles/header.makefile | 6 +++++- + BaseTools/Source/C/VfrCompile/GNUmakefile | 11 +++++++---- + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile +index 08421ba24c..498c6cf48b 100644 +--- a/BaseTools/Source/C/Makefiles/header.makefile ++++ b/BaseTools/Source/C/Makefiles/header.makefile +@@ -68,7 +68,8 @@ $(error Bad HOST_ARCH) + endif + + INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKEROOT)/Include/ -I $(MAKEROOT)/Include/IndustryStandard -I $(MAKEROOT)/Common/ -I .. -I . $(ARCH_INCLUDE) +-BUILD_CPPFLAGS = $(INCLUDE) -O2 ++BUILD_CPPFLAGS = $(INCLUDE) ++BUILD_OPTFLAGS = -O2 + ifeq ($(DARWIN),Darwin) + # assume clang or clang compatible flags on OS X + BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-self-assign -Wno-unused-result -nostdlib -g +@@ -91,6 +92,9 @@ ifeq ($(DARWIN),Darwin) + endif + endif + ++# keep BUILD_OPTFLAGS last ++BUILD_CFLAGS += $(BUILD_OPTFLAGS) ++BUILD_CXXFLAGS += $(BUILD_OPTFLAGS) + + .PHONY: all + .PHONY: install +diff --git a/BaseTools/Source/C/VfrCompile/GNUmakefile b/BaseTools/Source/C/VfrCompile/GNUmakefile +index c4ec61aa6c..bbe562cbc5 100644 +--- a/BaseTools/Source/C/VfrCompile/GNUmakefile ++++ b/BaseTools/Source/C/VfrCompile/GNUmakefile +@@ -25,6 +25,9 @@ OBJECTS = AParser.o DLexerBase.o ATokenBuffer.o EfiVfrParser.o VfrLexer.o VfrSyn + + VFR_CPPFLAGS = -DPCCTS_USE_NAMESPACE_STD $(BUILD_CPPFLAGS) + ++# keep BUILD_OPTFLAGS last ++VFR_CXXFLAGS = $(BUILD_OPTFLAGS) ++ + LINKER = $(BUILD_CXX) + + EXTRA_CLEAN_OBJECTS = EfiVfrParser.cpp EfiVfrParser.h VfrParser.dlg VfrTokens.h VfrLexer.cpp VfrLexer.h VfrSyntax.cpp tokens.h +@@ -58,16 +61,16 @@ Pccts/dlg/dlg: + BIN_DIR='.' $(MAKE) -C Pccts/dlg + + ATokenBuffer.o: Pccts/h/ATokenBuffer.cpp +- $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $? -o $@ ++ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@ + + DLexerBase.o: Pccts/h/DLexerBase.cpp +- $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $? -o $@ ++ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@ + + AParser.o: Pccts/h/AParser.cpp +- $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $? -o $@ ++ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@ + + VfrSyntax.o: VfrSyntax.cpp +- $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $? -o $@ ++ $(BUILD_CXX) -c $(VFR_CPPFLAGS) $(INC) $(VFR_CXXFLAGS) $? -o $@ + + clean: localClean + diff --git a/0020-BaseTools-Source-C-take-EXTRA_OPTFLAGS-from-the-call.patch b/0020-BaseTools-Source-C-take-EXTRA_OPTFLAGS-from-the-call.patch new file mode 100644 index 0000000..f61aebe --- /dev/null +++ b/0020-BaseTools-Source-C-take-EXTRA_OPTFLAGS-from-the-call.patch @@ -0,0 +1,37 @@ +From 26296351f9a6b6dad0604f8ed62ce5de0f41ac2c Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Thu, 26 Jul 2018 00:04:26 +0200 +Subject: [PATCH] BaseTools/Source/C: take EXTRA_OPTFLAGS from the caller + +Allow the caller of the top-level makefile either to set EXTRA_OPTFLAGS in +the environment or to pass EXTRA_OPTFLAGS as a macro definition on the +command line. EXTRA_OPTFLAGS extends (and potentially overrides) default C +compilation flags set in the makefiles. + +Cc: Liming Gao liming.gao@intel.com +Cc: Yonghong Zhu yonghong.zhu@intel.com +Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1540244 +Contributed-under: TianoCore Contribution Agreement 1.1 +Signed-off-by: Laszlo Ersek lersek@redhat.com +Reviewed-by: Liming Gao liming.gao@intel.com +(cherry picked from commit b0ca5dae78ff71397a8ef568f1914da7668ff5a9) +--- + BaseTools/Source/C/Makefiles/header.makefile | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile +index 498c6cf48b..1b4cad5497 100644 +--- a/BaseTools/Source/C/Makefiles/header.makefile ++++ b/BaseTools/Source/C/Makefiles/header.makefile +@@ -69,7 +69,10 @@ endif + + INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKEROOT)/Include/ -I $(MAKEROOT)/Include/IndustryStandard -I $(MAKEROOT)/Common/ -I .. -I . $(ARCH_INCLUDE) + BUILD_CPPFLAGS = $(INCLUDE) +-BUILD_OPTFLAGS = -O2 ++ ++# keep EXTRA_OPTFLAGS last ++BUILD_OPTFLAGS = -O2 $(EXTRA_OPTFLAGS) ++ + ifeq ($(DARWIN),Darwin) + # assume clang or clang compatible flags on OS X + BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-self-assign -Wno-unused-result -nostdlib -g diff --git a/0021-BaseTools-Source-C-take-EXTRA_LDFLAGS-from-the-calle.patch b/0021-BaseTools-Source-C-take-EXTRA_LDFLAGS-from-the-calle.patch new file mode 100644 index 0000000..ed987d0 --- /dev/null +++ b/0021-BaseTools-Source-C-take-EXTRA_LDFLAGS-from-the-calle.patch @@ -0,0 +1,35 @@ +From c1a087a76d91665433f190d0468be2b33da443cd Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Thu, 26 Jul 2018 01:24:40 +0200 +Subject: [PATCH] BaseTools/Source/C: take EXTRA_LDFLAGS from the caller + +Allow the caller of the top-level makefile either to set EXTRA_LDFLAGS in +the environment or to pass EXTRA_LDFLAGS as a macro definition on the +command line. EXTRA_LDFLAGS extends (and potentially overrides) default +link-editing flags set in the makefiles. + +Cc: Liming Gao liming.gao@intel.com +Cc: Yonghong Zhu yonghong.zhu@intel.com +Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1540244 +Contributed-under: TianoCore Contribution Agreement 1.1 +Signed-off-by: Laszlo Ersek lersek@redhat.com +Reviewed-by: Liming Gao liming.gao@intel.com +(cherry picked from commit 81502cee20ac4046f08bb4aec754c7091c8808dc) +--- + BaseTools/Source/C/Makefiles/header.makefile | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile +index 1b4cad5497..7f283d6464 100644 +--- a/BaseTools/Source/C/Makefiles/header.makefile ++++ b/BaseTools/Source/C/Makefiles/header.makefile +@@ -99,6 +99,9 @@ endif + BUILD_CFLAGS += $(BUILD_OPTFLAGS) + BUILD_CXXFLAGS += $(BUILD_OPTFLAGS) + ++# keep EXTRA_LDFLAGS last ++BUILD_LFLAGS += $(EXTRA_LDFLAGS) ++ + .PHONY: all + .PHONY: install + .PHONY: clean diff --git a/0022-BaseTools-VfrCompile-honor-EXTRA_LDFLAGS.patch b/0022-BaseTools-VfrCompile-honor-EXTRA_LDFLAGS.patch new file mode 100644 index 0000000..a3e89c5 --- /dev/null +++ b/0022-BaseTools-VfrCompile-honor-EXTRA_LDFLAGS.patch @@ -0,0 +1,69 @@ +From d30cba687d657a68bf83b8dd54db63b3e2e6cb54 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek lersek@redhat.com +Date: Thu, 16 Aug 2018 19:38:02 -0700 +Subject: [PATCH] BaseTools/VfrCompile: honor EXTRA_LDFLAGS + +In commit 81502cee20ac ("BaseTools/Source/C: take EXTRA_LDFLAGS from the +caller", 2018-08-16), I missed that "VfrCompile/GNUmakefile" does not use +BUILD_LFLAGS in the APPLICATION linking rule, unlike "app.makefile" does. +Instead, "VfrCompile/GNUmakefile" uses the (undefined) LFLAGS macro. +Therefore commit 81502cee20ac did not cover the linking step of +VfrCompile. + +Thankfully, the structure of the linking rules is the same, between +"app.makefile" and "VfrCompile/GNUmakefile". Rename the undefined LFLAGS +macro in "VfrCompile/GNUmakefile" to VFR_LFLAGS (for consistency with +VFR_CXXFLAGS), and set it to EXTRA_LDFLAGS. + +As a result, we have: + + | compilation | linking + -----------+--------------------------------+---------------------- + VfrCompile | VFR_CXXFLAGS = | VFR_LFLAGS = + | BUILD_OPTFLAGS = | EXTRA_LDFLAGS + | '-O2' + EXTRA_OPTFLAGS | + -----------+--------------------------------+---------------------- + other apps | BUILD_CFLAGS/BUILD_CXXFLAGS = | BUILD_LFLAGS = + | [...] + BUILD_OPTFLAGS = | [...] + EXTRA_LDFLAGS + | [...] + '-O2' + EXTRA_OPTFLAGS | + +This table shows +- that the VfrCompile compilation and linking flags are always a subset of + the corresponding flags used by the other apps, +- and that the EXTRA flags are always at the end. + +Cc: Liming Gao liming.gao@intel.com +Cc: Yonghong Zhu yonghong.zhu@intel.com +Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1540244 +Fixes: 81502cee20ac4046f08bb4aec754c7091c8808dc +Contributed-under: TianoCore Contribution Agreement 1.1 +Signed-off-by: Laszlo Ersek lersek@redhat.com +Reviewed-by: Liming Gao liming.gao@intel.com +(cherry picked from commit aa4e0df1f0c7ffdff07d7e382c9da89cbe207cdb) +--- + BaseTools/Source/C/VfrCompile/GNUmakefile | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/BaseTools/Source/C/VfrCompile/GNUmakefile b/BaseTools/Source/C/VfrCompile/GNUmakefile +index bbe562cbc5..9273589ff8 100644 +--- a/BaseTools/Source/C/VfrCompile/GNUmakefile ++++ b/BaseTools/Source/C/VfrCompile/GNUmakefile +@@ -28,6 +28,9 @@ VFR_CPPFLAGS = -DPCCTS_USE_NAMESPACE_STD $(BUILD_CPPFLAGS) + # keep BUILD_OPTFLAGS last + VFR_CXXFLAGS = $(BUILD_OPTFLAGS) + ++# keep EXTRA_LDFLAGS last ++VFR_LFLAGS = $(EXTRA_LDFLAGS) ++ + LINKER = $(BUILD_CXX) + + EXTRA_CLEAN_OBJECTS = EfiVfrParser.cpp EfiVfrParser.h VfrParser.dlg VfrTokens.h VfrLexer.cpp VfrLexer.h VfrSyntax.cpp tokens.h +@@ -42,7 +45,7 @@ APPLICATION = $(MAKEROOT)/bin/$(APPNAME) + all: $(MAKEROOT)/bin $(APPLICATION) + + $(APPLICATION): $(OBJECTS) +- $(LINKER) -o $(APPLICATION) $(LFLAGS) $(OBJECTS) -L$(MAKEROOT)/libs $(LIBS) ++ $(LINKER) -o $(APPLICATION) $(VFR_LFLAGS) $(OBJECTS) -L$(MAKEROOT)/libs $(LIBS) + + VfrCompiler.o: ../Include/Common/BuildVersion.h + diff --git a/0099-Tweak-the-tools_def-to-support-cross-compiling.patch b/0099-Tweak-the-tools_def-to-support-cross-compiling.patch new file mode 100644 index 0000000..bada25f --- /dev/null +++ b/0099-Tweak-the-tools_def-to-support-cross-compiling.patch @@ -0,0 +1,75 @@ +From 0784bdc810bcbd275a78ceb0c2cf04f2f0f68061 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini pbonzini@redhat.com +Date: Thu, 16 Aug 2018 15:45:47 -0400 +Subject: [PATCH] Tweak the tools_def to support cross-compiling. + +These files are meant for customization, so this is not upstream. + +Signed-off-by: Paolo Bonzini pbonzini@redhat.com +Signed-off-by: Cole Robinson crobinso@redhat.com +--- + BaseTools/Conf/tools_def.template | 44 +++++++++++++++---------------- + 1 file changed, 22 insertions(+), 22 deletions(-) + +diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template +index a22b96c0b8..8b134ca93f 100755 +--- a/BaseTools/Conf/tools_def.template ++++ b/BaseTools/Conf/tools_def.template +@@ -5068,17 +5068,17 @@ RELEASE_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) + ################## + # GCC5 IA32 definitions + ################## +-*_GCC5_IA32_OBJCOPY_PATH = DEF(GCC5_IA32_PREFIX)objcopy +-*_GCC5_IA32_CC_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_SLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc-ar +-*_GCC5_IA32_DLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_ASLDLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_ASM_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_PP_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_VFRPP_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_ASLCC_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_ASLPP_PATH = DEF(GCC5_IA32_PREFIX)gcc +-*_GCC5_IA32_RC_PATH = DEF(GCC5_IA32_PREFIX)objcopy ++*_GCC5_IA32_OBJCOPY_PATH = ENV(GCC5_IA32_PREFIX)objcopy ++*_GCC5_IA32_CC_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_SLINK_PATH = ENV(GCC5_IA32_PREFIX)gcc-ar ++*_GCC5_IA32_DLINK_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_ASLDLINK_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_ASM_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_PP_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_VFRPP_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_ASLCC_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_ASLPP_PATH = ENV(GCC5_IA32_PREFIX)gcc ++*_GCC5_IA32_RC_PATH = ENV(GCC5_IA32_PREFIX)objcopy + + *_GCC5_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 -fno-lto + *_GCC5_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -no-pie +@@ -5100,17 +5100,17 @@ RELEASE_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl, + ################## + # GCC5 X64 definitions + ################## +-*_GCC5_X64_OBJCOPY_PATH = DEF(GCC5_X64_PREFIX)objcopy +-*_GCC5_X64_CC_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_SLINK_PATH = DEF(GCC5_X64_PREFIX)gcc-ar +-*_GCC5_X64_DLINK_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_ASLDLINK_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_ASM_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_PP_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_VFRPP_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_ASLCC_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_ASLPP_PATH = DEF(GCC5_X64_PREFIX)gcc +-*_GCC5_X64_RC_PATH = DEF(GCC5_X64_PREFIX)objcopy ++*_GCC5_X64_OBJCOPY_PATH = ENV(GCC5_X64_PREFIX)objcopy ++*_GCC5_X64_CC_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_SLINK_PATH = ENV(GCC5_X64_PREFIX)gcc-ar ++*_GCC5_X64_DLINK_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_ASLDLINK_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_ASM_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_PP_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_VFRPP_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_ASLCC_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_ASLPP_PATH = ENV(GCC5_X64_PREFIX)gcc ++*_GCC5_X64_RC_PATH = ENV(GCC5_X64_PREFIX)objcopy + + *_GCC5_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 -fno-lto + *_GCC5_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 diff --git a/EDKII_openssl-1.0.2j-no-srp.patch b/EDKII_openssl-1.0.2j-no-srp.patch deleted file mode 100644 index 0735b73..0000000 --- a/EDKII_openssl-1.0.2j-no-srp.patch +++ /dev/null @@ -1,2028 +0,0 @@ -diff --git a/Configure b/Configure -index c39f71a..98dd1d0 100755 ---- a/Configure -+++ b/Configure -@@ -609,6 +609,9 @@ my %table=( - # with itself, Applink is never engaged and can as well be omitted. - "mingw64", "gcc:-mno-cygwin -DL_ENDIAN -O3 -Wall -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE::-D_MT:MINGW64:-lws2_32 -lgdi32 -lcrypt32:SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:${x86_64_asm}:mingw64:win32:cygwin-shared:-D_WINDLL:-mno-cygwin:.dll.a", - -+# UEFI -+"UEFI", "cc:-DL_ENDIAN -O:::UEFI::::", -+ - # UWIN - "UWIN", "cc:-DTERMIOS -DL_ENDIAN -O -Wall:::UWIN::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:win32", - -@@ -1083,7 +1086,7 @@ if (defined($disabled{"md5"}) || defined($disabled{"sha"}) - } - - if (defined($disabled{"ec"}) || defined($disabled{"dsa"}) -- || defined($disabled{"dh"})) -+ || defined($disabled{"dh"}) || defined($disabled{"stdio"})) - { - $disabled{"gost"} = "forced"; - } -diff --git a/apps/apps.c b/apps/apps.c -index 9fdc3e0..6c183b0 100644 ---- a/apps/apps.c -+++ b/apps/apps.c -@@ -2375,6 +2375,8 @@ int args_verify(char ***pargs, int *pargc, - flags |= X509_V_FLAG_PARTIAL_CHAIN; - else if (!strcmp(arg, "-no_alt_chains")) - flags |= X509_V_FLAG_NO_ALT_CHAINS; -+ else if (!strcmp(arg, "-no_check_time")) -+ flags |= X509_V_FLAG_NO_CHECK_TIME; - else if (!strcmp(arg, "-allow_proxy_certs")) - flags |= X509_V_FLAG_ALLOW_PROXY_CERTS; - else -diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c -index 2d562f9..91203b7 100644 ---- a/crypto/asn1/a_strex.c -+++ b/crypto/asn1/a_strex.c -@@ -104,6 +104,7 @@ static int send_bio_chars(void *arg, const void *buf, int len) - return 1; - } - -+#ifndef OPENSSL_NO_FP_API - static int send_fp_chars(void *arg, const void *buf, int len) - { - if (!arg) -@@ -112,6 +113,7 @@ static int send_fp_chars(void *arg, const void *buf, int len) - return 0; - return 1; - } -+#endif - - typedef int char_io (void *arg, const void *buf, int len); - -diff --git a/crypto/asn1/asn1_mac.h b/crypto/asn1/asn1_mac.h -index abc6dc3..3a672e9 100644 ---- a/crypto/asn1/asn1_mac.h -+++ b/crypto/asn1/asn1_mac.h -@@ -70,7 +70,7 @@ extern "C" { - # endif - - # define ASN1_MAC_H_err(f,r,line) \ -- ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line)) -+ ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),OPENSSL_FILE,(line)) - - # define M_ASN1_D2I_vars(a,type,func) \ - ASN1_const_CTX c; \ -@@ -81,7 +81,7 @@ extern "C" { - c.error=ERR_R_NESTED_ASN1_ERROR; \ - if ((a == NULL) || ((*a) == NULL)) \ - { if ((ret=(type)func()) == NULL) \ -- { c.line=__LINE__; goto err; } } \ -+ { c.line=OPENSSL_LINE; goto err; } } \ - else ret=(*a); - - # define M_ASN1_D2I_Init() \ -@@ -90,7 +90,7 @@ extern "C" { - - # define M_ASN1_D2I_Finish_2(a) \ - if (!asn1_const_Finish(&c)) \ -- { c.line=__LINE__; goto err; } \ -+ { c.line=OPENSSL_LINE; goto err; } \ - *(const unsigned char **)pp=c.p; \ - if (a != NULL) (*a)=ret; \ - return(ret); -@@ -105,7 +105,7 @@ err:\ - - # define M_ASN1_D2I_start_sequence() \ - if (!asn1_GetSequence(&c,&length)) \ -- { c.line=__LINE__; goto err; } -+ { c.line=OPENSSL_LINE; goto err; } - /* Begin reading ASN1 without a surrounding sequence */ - # define M_ASN1_D2I_begin() \ - c.slen = length; -@@ -129,21 +129,21 @@ err:\ - # define M_ASN1_D2I_get(b, func) \ - c.q=c.p; \ - if (func(&(b),&c.p,c.slen) == NULL) \ -- {c.line=__LINE__; goto err; } \ -+ {c.line=OPENSSL_LINE; goto err; } \ - c.slen-=(c.p-c.q); - - /* Don't use this with d2i_ASN1_BOOLEAN() */ - # define M_ASN1_D2I_get_x(type,b,func) \ - c.q=c.p; \ - if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \ -- {c.line=__LINE__; goto err; } \ -+ {c.line=OPENSSL_LINE; goto err; } \ - c.slen-=(c.p-c.q); - - /* use this instead () */ - # define M_ASN1_D2I_get_int(b,func) \ - c.q=c.p; \ - if (func(&(b),&c.p,c.slen) < 0) \ -- {c.line=__LINE__; goto err; } \ -+ {c.line=OPENSSL_LINE; goto err; } \ - c.slen-=(c.p-c.q); - - # define M_ASN1_D2I_get_opt(b,func,type) \ -@@ -164,7 +164,7 @@ err:\ - M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ - c.q=c.p; \ - if (func(&(b),&c.p,c.slen) == NULL) \ -- {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \ -+ {c.line=OPENSSL_LINE; M_ASN1_next_prev = _tmp; goto err; } \ - c.slen-=(c.p-c.q);\ - M_ASN1_next_prev=_tmp; - -@@ -258,20 +258,20 @@ err:\ - c.q=c.p; \ - if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\ - (void (*)())free_func,a,b) == NULL) \ -- { c.line=__LINE__; goto err; } \ -+ { c.line=OPENSSL_LINE; goto err; } \ - c.slen-=(c.p-c.q); - - # define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \ - c.q=c.p; \ - if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\ - free_func,a,b) == NULL) \ -- { c.line=__LINE__; goto err; } \ -+ { c.line=OPENSSL_LINE; goto err; } \ - c.slen-=(c.p-c.q); - - # define M_ASN1_D2I_get_set_strings(r,func,a,b) \ - c.q=c.p; \ - if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \ -- { c.line=__LINE__; goto err; } \ -+ { c.line=OPENSSL_LINE; goto err; } \ - c.slen-=(c.p-c.q); - - # define M_ASN1_D2I_get_EXP_opt(r,func,tag) \ -@@ -285,16 +285,16 @@ err:\ - Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ - if (Tinf & 0x80) \ - { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ -- c.line=__LINE__; goto err; } \ -+ c.line=OPENSSL_LINE; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ - Tlen = c.slen - (c.p - c.q) - 2; \ - if (func(&(r),&c.p,Tlen) == NULL) \ -- { c.line=__LINE__; goto err; } \ -+ { c.line=OPENSSL_LINE; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ - Tlen = c.slen - (c.p - c.q); \ - if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \ - { c.error=ERR_R_MISSING_ASN1_EOS; \ -- c.line=__LINE__; goto err; } \ -+ c.line=OPENSSL_LINE; goto err; } \ - }\ - c.slen-=(c.p-c.q); \ - } -@@ -310,18 +310,18 @@ err:\ - Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ - if (Tinf & 0x80) \ - { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ -- c.line=__LINE__; goto err; } \ -+ c.line=OPENSSL_LINE; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ - Tlen = c.slen - (c.p - c.q) - 2; \ - if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \ - (void (*)())free_func, \ - b,V_ASN1_UNIVERSAL) == NULL) \ -- { c.line=__LINE__; goto err; } \ -+ { c.line=OPENSSL_LINE; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ - Tlen = c.slen - (c.p - c.q); \ - if(!ASN1_check_infinite_end(&c.p, Tlen)) \ - { c.error=ERR_R_MISSING_ASN1_EOS; \ -- c.line=__LINE__; goto err; } \ -+ c.line=OPENSSL_LINE; goto err; } \ - }\ - c.slen-=(c.p-c.q); \ - } -@@ -337,17 +337,17 @@ err:\ - Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ - if (Tinf & 0x80) \ - { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ -- c.line=__LINE__; goto err; } \ -+ c.line=OPENSSL_LINE; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ - Tlen = c.slen - (c.p - c.q) - 2; \ - if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \ - free_func,b,V_ASN1_UNIVERSAL) == NULL) \ -- { c.line=__LINE__; goto err; } \ -+ { c.line=OPENSSL_LINE; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ - Tlen = c.slen - (c.p - c.q); \ - if(!ASN1_check_infinite_end(&c.p, Tlen)) \ - { c.error=ERR_R_MISSING_ASN1_EOS; \ -- c.line=__LINE__; goto err; } \ -+ c.line=OPENSSL_LINE; goto err; } \ - }\ - c.slen-=(c.p-c.q); \ - } -@@ -355,7 +355,7 @@ err:\ - /* New macros */ - # define M_ASN1_New_Malloc(ret,type) \ - if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \ -- { c.line=__LINE__; goto err2; } -+ { c.line=OPENSSL_LINE; goto err2; } - - # define M_ASN1_New(arg,func) \ - if (((arg)=func()) == NULL) return(NULL) -diff --git a/crypto/asn1/n_pkey.c b/crypto/asn1/n_pkey.c -index d5a5514..bede55c 100644 ---- a/crypto/asn1/n_pkey.c -+++ b/crypto/asn1/n_pkey.c -@@ -193,7 +193,12 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp, - OPENSSL_cleanse(pkey->private_key->data, rsalen); - - if (cb == NULL) -+#ifndef OPENSSL_NO_UI - cb = EVP_read_pw_string; -+#else -+ i = 1; -+ else -+#endif - i = cb((char *)buf, 256, "Enter Private Key password:", 1); - if (i != 0) { - ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ); -@@ -264,7 +269,11 @@ RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, - goto err; - } - if (cb == NULL) -+#ifndef OPENSSL_NO_UI - cb = EVP_read_pw_string; -+#else -+ goto err; -+#endif - if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb, sgckey)) == NULL) - goto err; - -diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c -index 1d25687..ad641c3 100644 ---- a/crypto/bn/bn_prime.c -+++ b/crypto/bn/bn_prime.c -@@ -131,7 +131,7 @@ - static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, - const BIGNUM *a1_odd, int k, BN_CTX *ctx, - BN_MONT_CTX *mont); --static int probable_prime(BIGNUM *rnd, int bits); -+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods); - static int probable_prime_dh(BIGNUM *rnd, int bits, - const BIGNUM *add, const BIGNUM *rem, - BN_CTX *ctx); -@@ -166,9 +166,13 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, - BIGNUM *t; - int found = 0; - int i, j, c1 = 0; -- BN_CTX *ctx; -+ BN_CTX *ctx = NULL; -+ prime_t *mods = NULL; - int checks = BN_prime_checks_for_size(bits); - -+ mods = OPENSSL_malloc(sizeof(*mods) * NUMPRIMES); -+ if (mods == NULL) -+ goto err; - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; -@@ -179,7 +183,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, - loop: - /* make a random number and set the top and bottom bits */ - if (add == NULL) { -- if (!probable_prime(ret, bits)) -+ if (!probable_prime(ret, bits, mods)) - goto err; - } else { - if (safe) { -@@ -230,6 +234,7 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, - /* we have a prime :-) */ - found = 1; - err: -+ OPENSSL_free(mods); - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); -@@ -375,10 +380,9 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, - return 1; - } - --static int probable_prime(BIGNUM *rnd, int bits) -+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods) - { - int i; -- prime_t mods[NUMPRIMES]; - BN_ULONG delta, maxdelta; - - again: -diff --git a/crypto/conf/conf.h b/crypto/conf/conf.h -index 8d926d5..c29e97d 100644 ---- a/crypto/conf/conf.h -+++ b/crypto/conf/conf.h -@@ -118,8 +118,10 @@ typedef void conf_finish_func (CONF_IMODULE *md); - - int CONF_set_default_method(CONF_METHOD *meth); - void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); -+# ifndef OPENSSL_NO_STDIO - LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, - long *eline); -+# endif - # ifndef OPENSSL_NO_FP_API - LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, - long *eline); -@@ -133,7 +135,9 @@ char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, - long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, - const char *name); - void CONF_free(LHASH_OF(CONF_VALUE) *conf); -+# ifndef OPENSSL_NO_FP_API - int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); -+# endif - int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); - - void OPENSSL_config(const char *config_name); -@@ -160,7 +164,9 @@ CONF_METHOD *NCONF_XML(void); - void NCONF_free(CONF *conf); - void NCONF_free_data(CONF *conf); - -+# ifndef OPENSSL_NO_STDIO - int NCONF_load(CONF *conf, const char *file, long *eline); -+# endif - # ifndef OPENSSL_NO_FP_API - int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); - # endif -@@ -170,7 +176,9 @@ STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, - char *NCONF_get_string(const CONF *conf, const char *group, const char *name); - int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, - long *result); -+# ifndef OPENSSL_NO_FP_API - int NCONF_dump_fp(const CONF *conf, FILE *out); -+# endif - int NCONF_dump_bio(const CONF *conf, BIO *out); - - # if 0 /* The following function has no error -@@ -184,8 +192,10 @@ long NCONF_get_number(CONF *conf, char *group, char *name); - - int CONF_modules_load(const CONF *cnf, const char *appname, - unsigned long flags); -+# ifndef OPENSSL_NO_STDIO - int CONF_modules_load_file(const char *filename, const char *appname, - unsigned long flags); -+# endif - void CONF_modules_unload(int all); - void CONF_modules_finish(void); - void CONF_modules_free(void); -diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c -index 68c77ce..3d308c7 100644 ---- a/crypto/conf/conf_def.c -+++ b/crypto/conf/conf_def.c -@@ -182,6 +182,10 @@ static int def_destroy_data(CONF *conf) - - static int def_load(CONF *conf, const char *name, long *line) - { -+#ifdef OPENSSL_NO_STDIO -+ CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); -+ return 0; -+#else - int ret; - BIO *in = NULL; - -@@ -202,6 +206,7 @@ static int def_load(CONF *conf, const char *name, long *line) - BIO_free(in); - - return ret; -+#endif - } - - static int def_load_bio(CONF *conf, BIO *in, long *line) -diff --git a/crypto/conf/conf_lib.c b/crypto/conf/conf_lib.c -index 5281384..952b545 100644 ---- a/crypto/conf/conf_lib.c -+++ b/crypto/conf/conf_lib.c -@@ -90,6 +90,7 @@ int CONF_set_default_method(CONF_METHOD *meth) - return 1; - } - -+#ifndef OPENSSL_NO_STDIO - LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, - long *eline) - { -@@ -111,6 +112,7 @@ LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, - - return ltmp; - } -+#endif - - #ifndef OPENSSL_NO_FP_API - LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, -@@ -255,6 +257,7 @@ void NCONF_free_data(CONF *conf) - conf->meth->destroy_data(conf); - } - -+#ifndef OPENSSL_NO_STDIO - int NCONF_load(CONF *conf, const char *file, long *eline) - { - if (conf == NULL) { -@@ -264,6 +267,7 @@ int NCONF_load(CONF *conf, const char *file, long *eline) - - return conf->meth->load(conf, file, eline); - } -+#endif - - #ifndef OPENSSL_NO_FP_API - int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) -diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c -index e0c9a67..13d93ea 100644 ---- a/crypto/conf/conf_mod.c -+++ b/crypto/conf/conf_mod.c -@@ -159,6 +159,7 @@ int CONF_modules_load(const CONF *cnf, const char *appname, - - } - -+#ifndef OPENSSL_NO_STDIO - int CONF_modules_load_file(const char *filename, const char *appname, - unsigned long flags) - { -@@ -194,6 +195,7 @@ int CONF_modules_load_file(const char *filename, const char *appname, - - return ret; - } -+#endif - - static int module_run(const CONF *cnf, char *name, char *value, - unsigned long flags) -diff --git a/crypto/conf/conf_sap.c b/crypto/conf/conf_sap.c -index c042cf2..a25b636 100644 ---- a/crypto/conf/conf_sap.c -+++ b/crypto/conf/conf_sap.c -@@ -87,9 +87,11 @@ void OPENSSL_config(const char *config_name) - ENGINE_load_builtin_engines(); - #endif - ERR_clear_error(); -+#ifndef OPENSSL_NO_STDIO - CONF_modules_load_file(NULL, config_name, - CONF_MFLAGS_DEFAULT_SECTION | - CONF_MFLAGS_IGNORE_MISSING_FILE); -+#endif - openssl_configured = 1; - } - -diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c -index 1925428..da4b34d 100644 ---- a/crypto/cryptlib.c -+++ b/crypto/cryptlib.c -@@ -263,7 +263,7 @@ int CRYPTO_get_new_dynlockid(void) - return (0); - } - pointer->references = 1; -- pointer->data = dynlock_create_callback(__FILE__, __LINE__); -+ pointer->data = dynlock_create_callback(OPENSSL_FILE, OPENSSL_LINE); - if (pointer->data == NULL) { - OPENSSL_free(pointer); - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); -@@ -289,7 +289,7 @@ int CRYPTO_get_new_dynlockid(void) - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (i == -1) { -- dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); -+ dynlock_destroy_callback(pointer->data, OPENSSL_FILE, OPENSSL_LINE); - OPENSSL_free(pointer); - } else - i += 1; /* to avoid 0 */ -@@ -328,7 +328,7 @@ void CRYPTO_destroy_dynlockid(int i) - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) { -- dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); -+ dynlock_destroy_callback(pointer->data, OPENSSL_FILE, OPENSSL_LINE); - OPENSSL_free(pointer); - } - } -@@ -670,6 +670,7 @@ unsigned long *OPENSSL_ia32cap_loc(void) - } - - # if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) -+#include <stdio.h> - # define OPENSSL_CPUID_SETUP - # if defined(_WIN32) - typedef unsigned __int64 IA32CAP; -@@ -980,11 +981,13 @@ void OPENSSL_showfatal(const char *fmta, ...) - #else - void OPENSSL_showfatal(const char *fmta, ...) - { -+#ifndef OPENSSL_NO_STDIO - va_list ap; - - va_start(ap, fmta); - vfprintf(stderr, fmta, ap); - va_end(ap); -+#endif - } - - int OPENSSL_isservice(void) -@@ -1011,10 +1014,12 @@ void OpenSSLDie(const char *file, int line, const char *assertion) - #endif - } - -+#ifndef OPENSSL_NO_STDIO - void *OPENSSL_stderr(void) - { - return stderr; - } -+#endif - - int CRYPTO_memcmp(const volatile void *in_a, const volatile void *in_b, size_t len) - { -diff --git a/crypto/cryptlib.h b/crypto/cryptlib.h -index fba180a..3e3ea5e 100644 ---- a/crypto/cryptlib.h -+++ b/crypto/cryptlib.h -@@ -101,7 +101,9 @@ extern "C" { - void OPENSSL_cpuid_setup(void); - extern unsigned int OPENSSL_ia32cap_P[]; - void OPENSSL_showfatal(const char *fmta, ...); -+#ifndef OPENSSL_NO_STDIO - void *OPENSSL_stderr(void); -+#endif - extern int OPENSSL_NONPIC_relocated; - - #ifdef __cplusplus -diff --git a/crypto/crypto.h b/crypto/crypto.h -index 6c644ce..bea4ca1 100644 ---- a/crypto/crypto.h -+++ b/crypto/crypto.h -@@ -235,15 +235,15 @@ typedef struct openssl_item_st { - # ifndef OPENSSL_NO_LOCKING - # ifndef CRYPTO_w_lock - # define CRYPTO_w_lock(type) \ -- CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,OPENSSL_FILE,OPENSSL_LINE) - # define CRYPTO_w_unlock(type) \ -- CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,OPENSSL_FILE,OPENSSL_LINE) - # define CRYPTO_r_lock(type) \ -- CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,OPENSSL_FILE,OPENSSL_LINE) - # define CRYPTO_r_unlock(type) \ -- CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,OPENSSL_FILE,OPENSSL_LINE) - # define CRYPTO_add(addr,amount,type) \ -- CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) -+ CRYPTO_add_lock(addr,amount,type,OPENSSL_FILE,OPENSSL_LINE) - # endif - # else - # define CRYPTO_w_lock(a) -@@ -378,19 +378,19 @@ int CRYPTO_is_mem_check_on(void); - # define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) - # define is_MemCheck_on() CRYPTO_is_mem_check_on() - --# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) --# define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) -+# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,OPENSSL_FILE,OPENSSL_LINE) -+# define OPENSSL_strdup(str) CRYPTO_strdup((str),OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_realloc(addr,num) \ -- CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) -+ CRYPTO_realloc((char *)addr,(int)num,OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_realloc_clean(addr,old_num,num) \ -- CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) -+ CRYPTO_realloc_clean(addr,old_num,num,OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_remalloc(addr,num) \ -- CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) -+ CRYPTO_remalloc((char **)addr,(int)num,OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_freeFunc CRYPTO_free - # define OPENSSL_free(addr) CRYPTO_free(addr) - - # define OPENSSL_malloc_locked(num) \ -- CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) -+ CRYPTO_malloc_locked((int)num,OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) - - const char *SSLeay_version(int type); -@@ -545,7 +545,7 @@ void CRYPTO_set_mem_debug_options(long bits); - long CRYPTO_get_mem_debug_options(void); - - # define CRYPTO_push_info(info) \ -- CRYPTO_push_info_(info, __FILE__, __LINE__); -+ CRYPTO_push_info_(info, OPENSSL_FILE, OPENSSL_LINE); - int CRYPTO_push_info_(const char *info, const char *file, int line); - int CRYPTO_pop_info(void); - int CRYPTO_remove_all_info(void); -@@ -588,7 +588,7 @@ void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); - - /* die if we have to */ - void OpenSSLDie(const char *file, int line, const char *assertion); --# define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) -+# define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(OPENSSL_FILE, OPENSSL_LINE, #e),1)) - - unsigned long *OPENSSL_ia32cap_loc(void); - # define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) -@@ -605,14 +605,14 @@ void OPENSSL_init(void); - # define fips_md_init_ctx(alg, cx) \ - int alg##_Init(cx##_CTX *c) \ - { \ -- if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ -+ if (FIPS_mode()) OpenSSLDie(OPENSSL_FILE, OPENSSL_LINE, \ - "Low level API call to digest " #alg " forbidden in FIPS mode!"); \ - return private_##alg##_Init(c); \ - } \ - int private_##alg##_Init(cx##_CTX *c) - - # define fips_cipher_abort(alg) \ -- if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ -+ if (FIPS_mode()) OpenSSLDie(OPENSSL_FILE, OPENSSL_LINE, \ - "Low level API call to cipher " #alg " forbidden in FIPS mode!") - - # else -diff --git a/crypto/des/read2pwd.c b/crypto/des/read2pwd.c -index 01e275f..7633139 100644 ---- a/crypto/des/read2pwd.c -+++ b/crypto/des/read2pwd.c -@@ -114,6 +114,10 @@ - #include <openssl/ui.h> - #include <openssl/crypto.h> - -+#ifndef BUFSIZ -+#define BUFSIZ 256 -+#endif -+ - int DES_read_password(DES_cblock *key, const char *prompt, int verify) - { - int ok; -diff --git a/crypto/dh/Makefile b/crypto/dh/Makefile -index 46fa5ac..cc366ec 100644 ---- a/crypto/dh/Makefile -+++ b/crypto/dh/Makefile -@@ -134,7 +134,7 @@ dh_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h - dh_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h - dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h - dh_gen.o: ../cryptlib.h dh_gen.c --dh_kdf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h -+dh_kdf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h - dh_kdf.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h - dh_kdf.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h - dh_kdf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h -diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h -index a5bd901..6488879 100644 ---- a/crypto/dh/dh.h -+++ b/crypto/dh/dh.h -@@ -240,11 +240,13 @@ DH *DH_get_1024_160(void); - DH *DH_get_2048_224(void); - DH *DH_get_2048_256(void); - -+# ifndef OPENSSL_NO_CMS - /* RFC2631 KDF */ - int DH_KDF_X9_42(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - ASN1_OBJECT *key_oid, - const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); -+# endif - - # define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ -@@ -337,7 +339,9 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, - - /* KDF types */ - # define EVP_PKEY_DH_KDF_NONE 1 -+# ifndef OPENSSL_NO_CMS - # define EVP_PKEY_DH_KDF_X9_42 2 -+# endif - - /* BEGIN ERROR CODES */ - /* -diff --git a/crypto/dh/dh_kdf.c b/crypto/dh/dh_kdf.c -index a882cb2..aace5fb 100644 ---- a/crypto/dh/dh_kdf.c -+++ b/crypto/dh/dh_kdf.c -@@ -51,6 +51,9 @@ - * ==================================================================== - */ - -+#include <e_os.h> -+ -+#ifndef OPENSSL_NO_CMS - #include <string.h> - #include <openssl/dh.h> - #include <openssl/evp.h> -@@ -58,6 +61,7 @@ - #include <openssl/cms.h> - - /* Key derivation from X9.42/RFC2631 */ -+/* Uses CMS functions, hence the #ifdef wrapper. */ - - #define DH_KDF_MAX (1L << 30) - -@@ -185,3 +189,4 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, - EVP_MD_CTX_cleanup(&mctx); - return rv; - } -+#endif -diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c -index b58e3fa..926be98 100644 ---- a/crypto/dh/dh_pmeth.c -+++ b/crypto/dh/dh_pmeth.c -@@ -207,7 +207,11 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) - case EVP_PKEY_CTRL_DH_KDF_TYPE: - if (p1 == -2) - return dctx->kdf_type; -+#ifdef OPENSSL_NO_CMS -+ if (p1 != EVP_PKEY_DH_KDF_NONE) -+#else - if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) -+#endif - return -2; - dctx->kdf_type = p1; - return 1; -@@ -448,7 +452,9 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - return ret; - *keylen = ret; - return 1; -- } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { -+ } -+#ifndef OPENSSL_NO_CMS -+ else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { - unsigned char *Z = NULL; - size_t Zlen = 0; - if (!dctx->kdf_outlen || !dctx->kdf_oid) -@@ -479,7 +485,8 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - } - return ret; - } -- return 1; -+#endif -+ return 0; - } - - const EVP_PKEY_METHOD dh_pkey_meth = { -diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h -index 46f163b..b4a72a0 100644 ---- a/crypto/engine/eng_int.h -+++ b/crypto/engine/eng_int.h -@@ -88,7 +88,7 @@ extern "C" { - (unsigned int)(e), (isfunct ? "funct" : "struct"), \ - ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \ - ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ -- (__FILE__), (__LINE__)); -+ (OPENSSL_FILE), (OPENSSL_LINE)); - - # else - -@@ -136,7 +136,7 @@ ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); - # else - ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, - int l); --# define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) -+# define engine_table_select(t,n) engine_table_select_tmp(t,n,OPENSSL_FILE,OPENSSL_LINE) - # endif - typedef void (engine_table_doall_cb) (int nid, STACK_OF(ENGINE) *sk, - ENGINE *def, void *arg); -diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c -index 34b0029..cf622bb 100644 ---- a/crypto/engine/eng_openssl.c -+++ b/crypto/engine/eng_openssl.c -@@ -86,7 +86,9 @@ - * this is no longer automatic in ENGINE_load_builtin_engines(). - */ - #define TEST_ENG_OPENSSL_RC4 -+#ifndef OPENSSL_NO_FP_API - #define TEST_ENG_OPENSSL_PKEY -+#endif - /* #define TEST_ENG_OPENSSL_RC4_OTHERS */ - #define TEST_ENG_OPENSSL_RC4_P_INIT - /* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ -diff --git a/crypto/err/err.h b/crypto/err/err.h -index 585aa8b..04c6cfc 100644 ---- a/crypto/err/err.h -+++ b/crypto/err/err.h -@@ -200,39 +200,39 @@ typedef struct err_state_st { - - # define ERR_LIB_USER 128 - --# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) --# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) --# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) --# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) --# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) --# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) --# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) --# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) --# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) --# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) --# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) --# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) --# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) --# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) --# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) --# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) --# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) --# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) --# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) --# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) --# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) --# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) --# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) --# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) --# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) --# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) --# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) --# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) --# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) --# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) --# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) --# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) --# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) -+# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* - * Borland C seems too stupid to be able to shift and do longs in the -diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h -index 39ab793..ad1e350 100644 ---- a/crypto/evp/evp.h -+++ b/crypto/evp/evp.h -@@ -602,11 +602,13 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); - int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); - int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); - -+#ifndef OPENSSL_NO_UI - int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); - int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, - const char *prompt, int verify); - void EVP_set_pw_prompt(const char *prompt); - char *EVP_get_pw_prompt(void); -+#endif - - int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, - const unsigned char *salt, const unsigned char *data, -diff --git a/crypto/evp/evp_key.c b/crypto/evp/evp_key.c -index 5be9e33..63c8866 100644 ---- a/crypto/evp/evp_key.c -+++ b/crypto/evp/evp_key.c -@@ -63,6 +63,7 @@ - #include <openssl/evp.h> - #include <openssl/ui.h> - -+#ifndef OPENSSL_NO_UI - /* should be init to zeros. */ - static char prompt_string[80]; - -@@ -117,6 +118,7 @@ int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, - OPENSSL_cleanse(buff, BUFSIZ); - return ret; - } -+#endif /* OPENSSL_NO_UI */ - - int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, - const unsigned char *salt, const unsigned char *data, -diff --git a/crypto/opensslconf.h.in b/crypto/opensslconf.h.in -index 7a1c85d..7162c0f 100644 ---- a/crypto/opensslconf.h.in -+++ b/crypto/opensslconf.h.in -@@ -1,5 +1,15 @@ - /* crypto/opensslconf.h.in */ - -+#ifndef OPENSSL_FILE -+#ifdef OPENSSL_NO_FILENAMES -+#define OPENSSL_FILE "" -+#define OPENSSL_LINE 0 -+#else -+#define OPENSSL_FILE __FILE__ -+#define OPENSSL_LINE __LINE__ -+#endif -+#endif -+ - /* Generate 80386 code? */ - #undef I386_ONLY - -@@ -56,7 +66,7 @@ - #endif - #endif - --#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) -+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) && !defined(OPENSSL_SYSNAME_UEFI) - #define CONFIG_HEADER_BN_H - #undef BN_LLONG - -diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h -index aac72fb..d271ec8 100644 ---- a/crypto/pem/pem.h -+++ b/crypto/pem/pem.h -@@ -324,6 +324,7 @@ int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ - - # define DECLARE_PEM_read_fp(name, type) /**/ - # define DECLARE_PEM_write_fp(name, type) /**/ -+# define DECLARE_PEM_write_fp_const(name, type) /**/ - # define DECLARE_PEM_write_cb_fp(name, type) /**/ - # else - -@@ -417,6 +418,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, - pem_password_cb *cd, void *u); - # endif - -+#ifndef OPENSSL_NO_FP_API - int PEM_read(FILE *fp, char **name, char **header, - unsigned char **data, long *len); - int PEM_write(FILE *fp, const char *name, const char *hdr, -@@ -428,6 +430,7 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, - int klen, pem_password_cb *callback, void *u); - STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u); -+#endif - - int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, - EVP_MD *md_type, unsigned char **ek, int *ekl, -@@ -494,6 +497,7 @@ int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u); - -+#ifndef OPENSSL_NO_FP_API - int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u); -@@ -510,6 +514,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cd, - void *u); -+#endif - - EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); - int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); -diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c -index c82b3c0..56c77b1 100644 ---- a/crypto/pem/pem_lib.c -+++ b/crypto/pem/pem_lib.c -@@ -84,7 +84,7 @@ int pem_check_suffix(const char *pem_str, const char *suffix); - - int PEM_def_callback(char *buf, int num, int w, void *key) - { --#ifdef OPENSSL_NO_FP_API -+#if defined(OPENSSL_NO_FP_API) || defined(OPENSSL_NO_UI) - /* - * We should not ever call the default callback routine from windows. - */ -diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c -index 5747c73..9edca4d 100644 ---- a/crypto/pem/pem_pk8.c -+++ b/crypto/pem/pem_pk8.c -@@ -69,9 +69,11 @@ - static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); -+#ifndef OPENSSL_NO_FP_API - static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); -+#endif - - /* - * These functions write a private key in PKCS#8 format: it is a "drop in" -diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c -index dc9b484..e75c4b2 100644 ---- a/crypto/pkcs7/pk7_smime.c -+++ b/crypto/pkcs7/pk7_smime.c -@@ -64,6 +64,8 @@ - #include <openssl/x509.h> - #include <openssl/x509v3.h> - -+#define BUFFERSIZE 4096 -+ - static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); - - PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, -@@ -254,7 +256,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, - STACK_OF(PKCS7_SIGNER_INFO) *sinfos; - PKCS7_SIGNER_INFO *si; - X509_STORE_CTX cert_ctx; -- char buf[4096]; -+ char *buf = NULL; - int i, j = 0, k, ret = 0; - BIO *p7bio = NULL; - BIO *tmpin = NULL, *tmpout = NULL; -@@ -373,8 +375,12 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, - tmpout = out; - - /* We now have to 'read' from p7bio to calculate digests etc. */ -+ if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { -+ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } - for (;;) { -- i = BIO_read(p7bio, buf, sizeof(buf)); -+ i = BIO_read(p7bio, buf, BUFFERSIZE); - if (i <= 0) - break; - if (tmpout) -@@ -405,6 +411,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, - ret = 1; - - err: -+ OPENSSL_free(buf); - if (tmpin == indata) { - if (indata) - BIO_pop(p7bio); -@@ -523,7 +530,7 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) - { - BIO *tmpmem; - int ret, i; -- char buf[4096]; -+ char *buf = NULL; - - if (!p7) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER); -@@ -567,24 +574,30 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) - } - BIO_free_all(bread); - return ret; -- } else { -- for (;;) { -- i = BIO_read(tmpmem, buf, sizeof(buf)); -- if (i <= 0) { -- ret = 1; -- if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { -- if (!BIO_get_cipher_status(tmpmem)) -- ret = 0; -- } -- -- break; -- } -- if (BIO_write(data, buf, i) != i) { -- ret = 0; -- break; -+ } -+ if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { -+ PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ for (;;) { -+ i = BIO_read(tmpmem, buf, BUFFERSIZE); -+ if (i <= 0) { -+ ret = 1; -+ if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { -+ if (!BIO_get_cipher_status(tmpmem)) -+ ret = 0; - } -+ -+ break; -+ } -+ if (BIO_write(data, buf, i) != i) { -+ ret = 0; -+ break; - } -- BIO_free_all(tmpmem); -- return ret; - } -+ -+err: -+ OPENSSL_free(buf); -+ BIO_free_all(tmpmem); -+ return ret; - } -diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c -index 737aebf..f23f348 100644 ---- a/crypto/rand/rand_egd.c -+++ b/crypto/rand/rand_egd.c -@@ -95,7 +95,7 @@ - * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. - */ - --#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS) -+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS) || defined(OPENSSL_SYS_UEFI) - int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) - { - return (-1); -diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c -index 6c5b65d..11ee152 100644 ---- a/crypto/rand/rand_unix.c -+++ b/crypto/rand/rand_unix.c -@@ -116,7 +116,7 @@ - #include <openssl/rand.h> - #include "rand_lcl.h" - --#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) -+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_UEFI)) - - # include <sys/types.h> - # include <sys/time.h> -@@ -439,7 +439,7 @@ int RAND_poll(void) - * defined(OPENSSL_SYS_VXWORKS) || - * defined(OPENSSL_SYS_NETWARE)) */ - --#if defined(OPENSSL_SYS_VXWORKS) -+#if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI) - int RAND_poll(void) - { - return 0; -diff --git a/crypto/ts/ts.h b/crypto/ts/ts.h -index 2daa1b2..5205bc5 100644 ---- a/crypto/ts/ts.h -+++ b/crypto/ts/ts.h -@@ -281,8 +281,10 @@ TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); - - TS_REQ *TS_REQ_dup(TS_REQ *a); - -+#ifndef OPENSSL_NO_FP_API - TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); - int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); -+#endif - TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); - int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); - -@@ -294,10 +296,12 @@ TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, - - TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); - -+#ifndef OPENSSL_NO_FP_API - TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); - int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); --TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); --int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); -+#endif -+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT **a); -+int i2d_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT *a); - - TS_RESP *TS_RESP_new(void); - void TS_RESP_free(TS_RESP *a); -@@ -306,10 +310,12 @@ TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); - TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); - TS_RESP *TS_RESP_dup(TS_RESP *a); - -+#ifndef OPENSSL_NO_FP_API - TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); - int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); --TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); --int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); -+#endif -+TS_RESP *d2i_TS_RESP_bio(BIO *bio, TS_RESP **a); -+int i2d_TS_RESP_bio(BIO *bio, TS_RESP *a); - - TS_STATUS_INFO *TS_STATUS_INFO_new(void); - void TS_STATUS_INFO_free(TS_STATUS_INFO *a); -@@ -325,10 +331,12 @@ TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, - long length); - TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); - -+#ifndef OPENSSL_NO_FP_API - TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); - int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); --TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); --int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); -+#endif -+TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO **a); -+int i2d_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO *a); - - TS_ACCURACY *TS_ACCURACY_new(void); - void TS_ACCURACY_free(TS_ACCURACY *a); -@@ -731,15 +739,18 @@ int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); - * ts/ts_conf.c - */ - -+#ifndef OPENSSL_NO_STDIO - X509 *TS_CONF_load_cert(const char *file); - STACK_OF(X509) *TS_CONF_load_certs(const char *file); - EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); -+#endif - const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); - int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, - TS_RESP_CTX *ctx); - int TS_CONF_set_crypto_device(CONF *conf, const char *section, - const char *device); - int TS_CONF_set_default_engine(const char *name); -+#ifndef OPENSSL_NO_STDIO - int TS_CONF_set_signer_cert(CONF *conf, const char *section, - const char *cert, TS_RESP_CTX *ctx); - int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, -@@ -747,6 +758,7 @@ int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, - int TS_CONF_set_signer_key(CONF *conf, const char *section, - const char *key, const char *pass, - TS_RESP_CTX *ctx); -+#endif - int TS_CONF_set_def_policy(CONF *conf, const char *section, - const char *policy, TS_RESP_CTX *ctx); - int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); -@@ -787,6 +799,11 @@ void ERR_load_TS_strings(void); - # define TS_F_TS_CHECK_SIGNING_CERTS 103 - # define TS_F_TS_CHECK_STATUS_INFO 104 - # define TS_F_TS_COMPUTE_IMPRINT 145 -+# define TS_F_TS_CONF_INVALID 151 -+# define TS_F_TS_CONF_LOAD_CERT 153 -+# define TS_F_TS_CONF_LOAD_CERTS 154 -+# define TS_F_TS_CONF_LOAD_KEY 155 -+# define TS_F_TS_CONF_LOOKUP_FAIL 152 - # define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 - # define TS_F_TS_GET_STATUS_TEXT 105 - # define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 -@@ -825,6 +842,8 @@ void ERR_load_TS_strings(void); - /* Reason codes. */ - # define TS_R_BAD_PKCS7_TYPE 132 - # define TS_R_BAD_TYPE 133 -+# define TS_R_CANNOT_LOAD_CERT 137 -+# define TS_R_CANNOT_LOAD_KEY 138 - # define TS_R_CERTIFICATE_VERIFY_ERROR 100 - # define TS_R_COULD_NOT_SET_ENGINE 127 - # define TS_R_COULD_NOT_SET_TIME 115 -@@ -857,6 +876,8 @@ void ERR_load_TS_strings(void); - # define TS_R_UNACCEPTABLE_POLICY 125 - # define TS_R_UNSUPPORTED_MD_ALGORITHM 126 - # define TS_R_UNSUPPORTED_VERSION 113 -+# define TS_R_VAR_BAD_VALUE 135 -+# define TS_R_VAR_LOOKUP_FAILURE 136 - # define TS_R_WRONG_CONTENT_TYPE 114 - - #ifdef __cplusplus -diff --git a/crypto/ts/ts_conf.c b/crypto/ts/ts_conf.c -index 4716b23..c4416ba 100644 ---- a/crypto/ts/ts_conf.c -+++ b/crypto/ts/ts_conf.c -@@ -92,6 +92,7 @@ - - /* Function definitions for certificate and key loading. */ - -+#ifndef OPENSSL_NO_STDIO - X509 *TS_CONF_load_cert(const char *file) - { - BIO *cert = NULL; -@@ -102,7 +103,7 @@ X509 *TS_CONF_load_cert(const char *file) - x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); - end: - if (x == NULL) -- fprintf(stderr, "unable to load certificate: %s\n", file); -+ TSerr(TS_F_TS_CONF_LOAD_CERT, TS_R_CANNOT_LOAD_CERT); - BIO_free(cert); - return x; - } -@@ -129,7 +130,7 @@ STACK_OF(X509) *TS_CONF_load_certs(const char *file) - } - end: - if (othercerts == NULL) -- fprintf(stderr, "unable to load certificates: %s\n", file); -+ TSerr(TS_F_TS_CONF_LOAD_CERTS, TS_R_CANNOT_LOAD_CERT); - sk_X509_INFO_pop_free(allcerts, X509_INFO_free); - BIO_free(certs); - return othercerts; -@@ -145,21 +146,24 @@ EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) - pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *)pass); - end: - if (pkey == NULL) -- fprintf(stderr, "unable to load private key: %s\n", file); -+ TSerr(TS_F_TS_CONF_LOAD_KEY, TS_R_CANNOT_LOAD_KEY); - BIO_free(key); - return pkey; - } -+#endif /* !OPENSSL_NO_STDIO */ - - /* Function definitions for handling configuration options. */ - - static void TS_CONF_lookup_fail(const char *name, const char *tag) - { -- fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag); -+ TSerr(TS_F_TS_CONF_LOOKUP_FAIL, TS_R_VAR_LOOKUP_FAILURE); -+ ERR_add_error_data(3, name, "::", tag); - } - - static void TS_CONF_invalid(const char *name, const char *tag) - { -- fprintf(stderr, "invalid variable value for %s::%s\n", name, tag); -+ TSerr(TS_F_TS_CONF_INVALID, TS_R_VAR_BAD_VALUE); -+ ERR_add_error_data(3, name, "::", tag); - } - - const char *TS_CONF_get_tsa_section(CONF *conf, const char *section) -@@ -237,6 +241,7 @@ int TS_CONF_set_default_engine(const char *name) - - #endif - -+#ifndef OPENSSL_NO_STDIO - int TS_CONF_set_signer_cert(CONF *conf, const char *section, - const char *cert, TS_RESP_CTX *ctx) - { -@@ -302,6 +307,7 @@ int TS_CONF_set_signer_key(CONF *conf, const char *section, - EVP_PKEY_free(key_obj); - return ret; - } -+#endif /* !OPENSSL_NO_STDIO */ - - int TS_CONF_set_def_policy(CONF *conf, const char *section, - const char *policy, TS_RESP_CTX *ctx) -diff --git a/crypto/ts/ts_err.c b/crypto/ts/ts_err.c -index ff1abf4..3f5b78f 100644 ---- a/crypto/ts/ts_err.c -+++ b/crypto/ts/ts_err.c -@@ -1,6 +1,6 @@ - /* crypto/ts/ts_err.c */ - /* ==================================================================== -- * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. -+ * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions -@@ -87,6 +87,11 @@ static ERR_STRING_DATA TS_str_functs[] = { - {ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "TS_CHECK_SIGNING_CERTS"}, - {ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "TS_CHECK_STATUS_INFO"}, - {ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "TS_COMPUTE_IMPRINT"}, -+ {ERR_FUNC(TS_F_TS_CONF_INVALID), "ts_CONF_invalid"}, -+ {ERR_FUNC(TS_F_TS_CONF_LOAD_CERT), "TS_CONF_load_cert"}, -+ {ERR_FUNC(TS_F_TS_CONF_LOAD_CERTS), "TS_CONF_load_certs"}, -+ {ERR_FUNC(TS_F_TS_CONF_LOAD_KEY), "TS_CONF_load_key"}, -+ {ERR_FUNC(TS_F_TS_CONF_LOOKUP_FAIL), "ts_CONF_lookup_fail"}, - {ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"}, - {ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "TS_GET_STATUS_TEXT"}, - {ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"}, -@@ -132,6 +137,8 @@ static ERR_STRING_DATA TS_str_functs[] = { - static ERR_STRING_DATA TS_str_reasons[] = { - {ERR_REASON(TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"}, - {ERR_REASON(TS_R_BAD_TYPE), "bad type"}, -+ {ERR_REASON(TS_R_CANNOT_LOAD_CERT), "cannot load certificate"}, -+ {ERR_REASON(TS_R_CANNOT_LOAD_KEY), "cannot load private key"}, - {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, - {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE), "could not set engine"}, - {ERR_REASON(TS_R_COULD_NOT_SET_TIME), "could not set time"}, -@@ -170,6 +177,8 @@ static ERR_STRING_DATA TS_str_reasons[] = { - {ERR_REASON(TS_R_UNACCEPTABLE_POLICY), "unacceptable policy"}, - {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"}, - {ERR_REASON(TS_R_UNSUPPORTED_VERSION), "unsupported version"}, -+ {ERR_REASON(TS_R_VAR_BAD_VALUE), "var bad value"}, -+ {ERR_REASON(TS_R_VAR_LOOKUP_FAILURE), "cannot find config variable"}, - {ERR_REASON(TS_R_WRONG_CONTENT_TYPE), "wrong content type"}, - {0, NULL} - }; -diff --git a/crypto/ui/ui_util.c b/crypto/ui/ui_util.c -index 0f29011..80dd40e 100644 ---- a/crypto/ui/ui_util.c -+++ b/crypto/ui/ui_util.c -@@ -56,6 +56,10 @@ - #include <string.h> - #include "ui_locl.h" - -+#ifndef BUFSIZ -+#define BUFSIZ 256 -+#endif -+ - int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, - int verify) - { -diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c -index bbc3189..29695f9 100644 ---- a/crypto/x509/by_dir.c -+++ b/crypto/x509/by_dir.c -@@ -69,6 +69,8 @@ - # include <sys/stat.h> - #endif - -+#ifndef OPENSSL_NO_STDIO -+ - #include <openssl/lhash.h> - #include <openssl/x509.h> - -@@ -438,3 +440,5 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, - BUF_MEM_free(b); - return (ok); - } -+ -+#endif /* OPENSSL_NO_STDIO */ -diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c -index 8334b3f..d075f66 100644 ---- a/crypto/x509/x509_vfy.c -+++ b/crypto/x509/x509_vfy.c -@@ -1064,6 +1064,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) - ctx->current_crl = crl; - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) - ptime = &ctx->param->check_time; -+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) -+ return 1; - else - ptime = NULL; - -@@ -1805,6 +1807,8 @@ static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) - - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) - ptime = &ctx->param->check_time; -+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) -+ return 1; - else - ptime = NULL; - -diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h -index 5062682..e90d931 100644 ---- a/crypto/x509/x509_vfy.h -+++ b/crypto/x509/x509_vfy.h -@@ -443,6 +443,8 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); - * will force the behaviour to match that of previous versions. - */ - # define X509_V_FLAG_NO_ALT_CHAINS 0x100000 -+/* Do not check certificate/CRL validity against current time */ -+# define X509_V_FLAG_NO_CHECK_TIME 0x200000 - - # define X509_VP_FLAG_DEFAULT 0x1 - # define X509_VP_FLAG_OVERWRITE 0x2 -@@ -496,8 +498,10 @@ X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); - - X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); - -+#ifndef OPENSSL_NO_STDIO - X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); - X509_LOOKUP_METHOD *X509_LOOKUP_file(void); -+#endif - - int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); - int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); -diff --git a/crypto/x509v3/ext_dat.h b/crypto/x509v3/ext_dat.h -index c3a6fce..09ebbca 100644 ---- a/crypto/x509v3/ext_dat.h -+++ b/crypto/x509v3/ext_dat.h -@@ -127,8 +127,10 @@ static const X509V3_EXT_METHOD *standard_exts[] = { - &v3_idp, - &v3_alt[2], - &v3_freshest_crl, -+#ifndef OPENSSL_NO_SCT - &v3_ct_scts[0], - &v3_ct_scts[1], -+#endif - }; - - /* Number of standard extensions */ -diff --git a/crypto/x509v3/v3_pci.c b/crypto/x509v3/v3_pci.c -index 34cad53..12f12a7 100644 ---- a/crypto/x509v3/v3_pci.c -+++ b/crypto/x509v3/v3_pci.c -@@ -149,6 +149,7 @@ static int process_pci_value(CONF_VALUE *val, - goto err; - } - OPENSSL_free(tmp_data2); -+#ifndef OPENSSL_NO_STDIO - } else if (strncmp(val->value, "file:", 5) == 0) { - unsigned char buf[2048]; - int n; -@@ -181,6 +182,7 @@ static int process_pci_value(CONF_VALUE *val, - X509V3_conf_err(val); - goto err; - } -+#endif /* !OPENSSL_NO_STDIO */ - } else if (strncmp(val->value, "text:", 5) == 0) { - val_len = strlen(val->value + 5); - tmp_data = OPENSSL_realloc((*policy)->data, -diff --git a/crypto/x509v3/v3_scts.c b/crypto/x509v3/v3_scts.c -index 0b7c681..1895b8f 100644 ---- a/crypto/x509v3/v3_scts.c -+++ b/crypto/x509v3/v3_scts.c -@@ -61,6 +61,7 @@ - #include <openssl/asn1.h> - #include <openssl/x509v3.h> - -+#ifndef OPENSSL_NO_SCT - /* Signature and hash algorithms from RFC 5246 */ - #define TLSEXT_hash_sha256 4 - -@@ -332,3 +333,4 @@ static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list, - - return 1; - } -+#endif -diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h -index f5c6156..a2e78aa 100644 ---- a/crypto/x509v3/x509v3.h -+++ b/crypto/x509v3/x509v3.h -@@ -688,8 +688,9 @@ void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, - int ml); - int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, - int indent); -+#ifndef OPENSSL_NO_FP_API - int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); -- -+#endif - int X509V3_extensions_print(BIO *out, char *title, - STACK_OF(X509_EXTENSION) *exts, - unsigned long flag, int indent); -diff --git a/demos/engines/cluster_labs/hw_cluster_labs_err.h b/demos/engines/cluster_labs/hw_cluster_labs_err.h -index 3300e11..e9e58d5 100644 ---- a/demos/engines/cluster_labs/hw_cluster_labs_err.h -+++ b/demos/engines/cluster_labs/hw_cluster_labs_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_CL_strings(void); - static void ERR_unload_CL_strings(void); - static void ERR_CL_error(int function, int reason, char *file, int line); --# define CLerr(f,r) ERR_CL_error((f),(r),__FILE__,__LINE__) -+# define CLerr(f,r) ERR_CL_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the CL functions. */ - -diff --git a/demos/engines/ibmca/hw_ibmca_err.h b/demos/engines/ibmca/hw_ibmca_err.h -index c17e0c9..10d0212 100644 ---- a/demos/engines/ibmca/hw_ibmca_err.h -+++ b/demos/engines/ibmca/hw_ibmca_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_IBMCA_strings(void); - static void ERR_unload_IBMCA_strings(void); - static void ERR_IBMCA_error(int function, int reason, char *file, int line); --# define IBMCAerr(f,r) ERR_IBMCA_error((f),(r),__FILE__,__LINE__) -+# define IBMCAerr(f,r) ERR_IBMCA_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the IBMCA functions. */ - -diff --git a/demos/engines/rsaref/rsaref_err.h b/demos/engines/rsaref/rsaref_err.h -index 4356815..598836f 100644 ---- a/demos/engines/rsaref/rsaref_err.h -+++ b/demos/engines/rsaref/rsaref_err.h -@@ -68,7 +68,7 @@ extern "C" { - static void ERR_load_RSAREF_strings(void); - static void ERR_unload_RSAREF_strings(void); - static void ERR_RSAREF_error(int function, int reason, char *file, int line); --# define RSAREFerr(f,r) ERR_RSAREF_error((f),(r),__FILE__,__LINE__) -+# define RSAREFerr(f,r) ERR_RSAREF_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - /* Error codes for the RSAREF functions. */ - - /* Function codes. */ -diff --git a/demos/engines/zencod/hw_zencod_err.h b/demos/engines/zencod/hw_zencod_err.h -index f4a8358..94d3293 100644 ---- a/demos/engines/zencod/hw_zencod_err.h -+++ b/demos/engines/zencod/hw_zencod_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_ZENCOD_strings(void); - static void ERR_unload_ZENCOD_strings(void); - static void ERR_ZENCOD_error(int function, int reason, char *file, int line); --# define ZENCODerr(f,r) ERR_ZENCOD_error((f),(r),__FILE__,__LINE__) -+# define ZENCODerr(f,r) ERR_ZENCOD_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the ZENCOD functions. */ - -diff --git a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod -index 44792f9..7f95d58 100644 ---- a/doc/crypto/X509_VERIFY_PARAM_set_flags.pod -+++ b/doc/crypto/X509_VERIFY_PARAM_set_flags.pod -@@ -203,6 +203,10 @@ chain found is not trusted, then OpenSSL will continue to check to see if an - alternative chain can be found that is trusted. With this flag set the behaviour - will match that of OpenSSL versions prior to 1.0.2b. - -+The B<X509_V_FLAG_NO_CHECK_TIME> flag suppresses checking the validity period -+of certificates and CRLs against the current time. If X509_VERIFY_PARAM_set_time() -+is used to specify a verification time, the check is not suppressed. -+ - =head1 NOTES - - The above functions should be used to manipulate verification parameters -diff --git a/doc/crypto/threads.pod b/doc/crypto/threads.pod -index dc0e939..fe123bb 100644 ---- a/doc/crypto/threads.pod -+++ b/doc/crypto/threads.pod -@@ -51,15 +51,15 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support - void CRYPTO_lock(int mode, int n, const char *file, int line); - - #define CRYPTO_w_lock(type) \ -- CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,OPENSSL_FILE,OPENSSL_LINE) - #define CRYPTO_w_unlock(type) \ -- CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,OPENSSL_FILE,OPENSSL_LINE) - #define CRYPTO_r_lock(type) \ -- CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,OPENSSL_FILE,OPENSSL_LINE) - #define CRYPTO_r_unlock(type) \ -- CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) -+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,OPENSSL_FILE,OPENSSL_LINE) - #define CRYPTO_add(addr,amount,type) \ -- CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) -+ CRYPTO_add_lock(addr,amount,type,OPENSSL_FILE,OPENSSL_LINE) - - =head1 DESCRIPTION - -diff --git a/e_os.h b/e_os.h -index 1fa36c1..3e9dae2 100644 ---- a/e_os.h -+++ b/e_os.h -@@ -136,7 +136,7 @@ extern "C" { - # define MSDOS - # endif - --# if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS) -+# if (defined(MSDOS) || defined(OPENSSL_SYS_UEFI)) && !defined(GETPID_IS_MEANINGLESS) - # define GETPID_IS_MEANINGLESS - # endif - -diff --git a/e_os2.h b/e_os2.h -index 7be9989..909e22f 100644 ---- a/e_os2.h -+++ b/e_os2.h -@@ -97,7 +97,14 @@ extern "C" { - * For 32 bit environment, there seems to be the CygWin environment and then - * all the others that try to do the same thing Microsoft does... - */ --# if defined(OPENSSL_SYSNAME_UWIN) -+/* -+ * UEFI lives here because it might be built with a Microsoft toolchain and -+ * we need to avoid the false positive match on Windows. -+ */ -+# if defined(OPENSSL_SYSNAME_UEFI) -+# undef OPENSSL_SYS_UNIX -+# define OPENSSL_SYS_UEFI -+# elif defined(OPENSSL_SYSNAME_UWIN) - # undef OPENSSL_SYS_UNIX - # define OPENSSL_SYS_WIN32_UWIN - # else -diff --git a/engines/ccgost/e_gost_err.h b/engines/ccgost/e_gost_err.h -index a2018ec..9eacdcf 100644 ---- a/engines/ccgost/e_gost_err.h -+++ b/engines/ccgost/e_gost_err.h -@@ -67,7 +67,7 @@ extern "C" { - void ERR_load_GOST_strings(void); - void ERR_unload_GOST_strings(void); - void ERR_GOST_error(int function, int reason, char *file, int line); --# define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__) -+# define GOSTerr(f,r) ERR_GOST_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the GOST functions. */ - -diff --git a/engines/e_4758cca_err.h b/engines/e_4758cca_err.h -index 2f29d96..47a2635 100644 ---- a/engines/e_4758cca_err.h -+++ b/engines/e_4758cca_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_CCA4758_strings(void); - static void ERR_unload_CCA4758_strings(void); - static void ERR_CCA4758_error(int function, int reason, char *file, int line); --# define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__) -+# define CCA4758err(f,r) ERR_CCA4758_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the CCA4758 functions. */ - -diff --git a/engines/e_aep_err.h b/engines/e_aep_err.h -index 2ed0114..1f8fa5b 100644 ---- a/engines/e_aep_err.h -+++ b/engines/e_aep_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_AEPHK_strings(void); - static void ERR_unload_AEPHK_strings(void); - static void ERR_AEPHK_error(int function, int reason, char *file, int line); --# define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__) -+# define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the AEPHK functions. */ - -diff --git a/engines/e_atalla_err.h b/engines/e_atalla_err.h -index 7b71eff..d958496 100644 ---- a/engines/e_atalla_err.h -+++ b/engines/e_atalla_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_ATALLA_strings(void); - static void ERR_unload_ATALLA_strings(void); - static void ERR_ATALLA_error(int function, int reason, char *file, int line); --# define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__) -+# define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the ATALLA functions. */ - -diff --git a/engines/e_capi_err.h b/engines/e_capi_err.h -index b5d06dc..cfe46b1 100644 ---- a/engines/e_capi_err.h -+++ b/engines/e_capi_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_CAPI_strings(void); - static void ERR_unload_CAPI_strings(void); - static void ERR_CAPI_error(int function, int reason, char *file, int line); --# define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__) -+# define CAPIerr(f,r) ERR_CAPI_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the CAPI functions. */ - -diff --git a/engines/e_chil_err.h b/engines/e_chil_err.h -index d86a4ce..3d961b9 100644 ---- a/engines/e_chil_err.h -+++ b/engines/e_chil_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_HWCRHK_strings(void); - static void ERR_unload_HWCRHK_strings(void); - static void ERR_HWCRHK_error(int function, int reason, char *file, int line); --# define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__) -+# define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the HWCRHK functions. */ - -diff --git a/engines/e_cswift_err.h b/engines/e_cswift_err.h -index fde3a82..7c20691 100644 ---- a/engines/e_cswift_err.h -+++ b/engines/e_cswift_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_CSWIFT_strings(void); - static void ERR_unload_CSWIFT_strings(void); - static void ERR_CSWIFT_error(int function, int reason, char *file, int line); --# define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__) -+# define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the CSWIFT functions. */ - -diff --git a/engines/e_gmp_err.h b/engines/e_gmp_err.h -index 637abbc..ccaf3da 100644 ---- a/engines/e_gmp_err.h -+++ b/engines/e_gmp_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_GMP_strings(void); - static void ERR_unload_GMP_strings(void); - static void ERR_GMP_error(int function, int reason, char *file, int line); --# define GMPerr(f,r) ERR_GMP_error((f),(r),__FILE__,__LINE__) -+# define GMPerr(f,r) ERR_GMP_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the GMP functions. */ - -diff --git a/engines/e_nuron_err.h b/engines/e_nuron_err.h -index aa7849c..e607d3e 100644 ---- a/engines/e_nuron_err.h -+++ b/engines/e_nuron_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_NURON_strings(void); - static void ERR_unload_NURON_strings(void); - static void ERR_NURON_error(int function, int reason, char *file, int line); --# define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__) -+# define NURONerr(f,r) ERR_NURON_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the NURON functions. */ - -diff --git a/engines/e_sureware_err.h b/engines/e_sureware_err.h -index bef8623..54f2848 100644 ---- a/engines/e_sureware_err.h -+++ b/engines/e_sureware_err.h -@@ -68,7 +68,7 @@ static void ERR_load_SUREWARE_strings(void); - static void ERR_unload_SUREWARE_strings(void); - static void ERR_SUREWARE_error(int function, int reason, char *file, - int line); --# define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__) -+# define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the SUREWARE functions. */ - -diff --git a/engines/e_ubsec_err.h b/engines/e_ubsec_err.h -index c8aec7c..67110ed 100644 ---- a/engines/e_ubsec_err.h -+++ b/engines/e_ubsec_err.h -@@ -67,7 +67,7 @@ extern "C" { - static void ERR_load_UBSEC_strings(void); - static void ERR_unload_UBSEC_strings(void); - static void ERR_UBSEC_error(int function, int reason, char *file, int line); --# define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__) -+# define UBSECerr(f,r) ERR_UBSEC_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* Error codes for the UBSEC functions. */ - -diff --git a/makevms.com b/makevms.com -index f6b3ff2..1dcbe36 100755 ---- a/makevms.com -+++ b/makevms.com -@@ -293,6 +293,7 @@ $ CONFIG_LOGICALS := AES,- - RFC3779,- - RIPEMD,- - RSA,- -+ SCT,- - SCTP,- - SEED,- - SHA,- -diff --git a/ssl/d1_both.c b/ssl/d1_both.c -index 9bc6153..b5648eb 100644 ---- a/ssl/d1_both.c -+++ b/ssl/d1_both.c -@@ -1068,7 +1068,7 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) - int dtls1_read_failed(SSL *s, int code) - { - if (code > 0) { -- fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); -+ fprintf(stderr, "dtls1_read_failed(); invalid state reached\n"); - return 1; - } - -diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c -index 499f0e8..5672f99 100644 ---- a/ssl/ssl_asn1.c -+++ b/ssl/ssl_asn1.c -@@ -418,7 +418,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, - if (ssl_version == SSL2_VERSION) { - if (os.length != 3) { - c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; -- c.line = __LINE__; -+ c.line = OPENSSL_LINE; - goto err; - } - id = 0x02000000L | -@@ -429,14 +429,14 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, - || ssl_version == DTLS1_BAD_VER) { - if (os.length != 2) { - c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; -- c.line = __LINE__; -+ c.line = OPENSSL_LINE; - goto err; - } - id = 0x03000000L | - ((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1]; - } else { - c.error = SSL_R_UNKNOWN_SSL_VERSION; -- c.line = __LINE__; -+ c.line = OPENSSL_LINE; - goto err; - } - -@@ -526,7 +526,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, - if (os.data != NULL) { - if (os.length > SSL_MAX_SID_CTX_LENGTH) { - c.error = SSL_R_BAD_LENGTH; -- c.line = __LINE__; -+ c.line = OPENSSL_LINE; - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; -diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c -index f48ebae..ac4f08c 100644 ---- a/ssl/ssl_cert.c -+++ b/ssl/ssl_cert.c -@@ -857,12 +857,12 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) - return (add_client_CA(&(ctx->client_CA), x)); - } - -+#ifndef OPENSSL_NO_STDIO - static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) - { - return (X509_NAME_cmp(*a, *b)); - } - --#ifndef OPENSSL_NO_STDIO - /** - * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; - * it doesn't really have anything to do with clients (except that a common use -@@ -930,7 +930,6 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) - ERR_clear_error(); - return (ret); - } --#endif - - /** - * Add a file of certs to a stack. -@@ -1050,6 +1049,7 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, - CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); - return ret; - } -+#endif /* !OPENSSL_NO_STDIO */ - - /* Add a certificate to a BUF_MEM structure */ - -diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c -index 8d3709d..2bb403b 100644 ---- a/ssl/ssl_conf.c -+++ b/ssl/ssl_conf.c -@@ -370,6 +370,7 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) - return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); - } - -+#ifndef OPENSSL_NO_STDIO - static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) - { - int rv = 1; -@@ -436,7 +437,9 @@ static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) - BIO_free(in); - return rv > 0; - } --#endif -+#endif /* !OPENSSL_NO_DH */ -+#endif /* !OPENSSL_NO_STDIO */ -+ - typedef struct { - int (*cmd) (SSL_CONF_CTX *cctx, const char *value); - const char *str_file; -@@ -462,12 +465,14 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { - SSL_CONF_CMD_STRING(CipherString, "cipher"), - SSL_CONF_CMD_STRING(Protocol, NULL), - SSL_CONF_CMD_STRING(Options, NULL), -+#ifndef OPENSSL_NO_STDIO - SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE), - SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE), - SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE), - #ifndef OPENSSL_NO_DH - SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE) - #endif -+#endif - }; - - static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) -diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c -index b6d1ee9..75f38cd 100644 ---- a/ssl/t1_enc.c -+++ b/ssl/t1_enc.c -@@ -779,9 +779,7 @@ int tls1_enc(SSL *s, int send) - * we can't write into the input stream: Can this ever - * happen?? (steve) - */ -- fprintf(stderr, -- "%s:%d: rec->data != rec->input\n", -- __FILE__, __LINE__); -+ fprintf(stderr, "tls1_enc: rec->data != rec->input\n"); - else if (RAND_bytes(rec->input, ivlen) <= 0) - return -1; - } -diff --git a/test/cms-test.pl b/test/cms-test.pl -index baa3b59..1ee3f02 100644 ---- a/test/cms-test.pl -+++ b/test/cms-test.pl -@@ -100,6 +100,13 @@ my $no_ec2m; - my $no_ecdh; - my $ossl8 = `$ossl_path version -v` =~ /0.9.8/; - -+system ("$ossl_path no-cms > $null_path"); -+if ($? == 0) -+ { -+ print "CMS disabled\n"; -+ exit 0; -+ } -+ - system ("$ossl_path no-ec > $null_path"); - if ($? == 0) - { -diff --git a/util/libeay.num b/util/libeay.num -index 2094ab3..992abb2 100755 ---- a/util/libeay.num -+++ b/util/libeay.num -@@ -4370,7 +4370,7 @@ DH_compute_key_padded 4732 EXIST::FUNCTION:DH - ECDSA_METHOD_set_sign 4733 EXIST::FUNCTION:ECDSA - CMS_RecipientEncryptedKey_cert_cmp 4734 EXIST:!VMS:FUNCTION:CMS - CMS_RecipEncryptedKey_cert_cmp 4734 EXIST:VMS:FUNCTION:CMS --DH_KDF_X9_42 4735 EXIST::FUNCTION:DH -+DH_KDF_X9_42 4735 EXIST::FUNCTION:CMS,DH - RSA_OAEP_PARAMS_free 4736 EXIST::FUNCTION:RSA - EVP_des_ede3_wrap 4737 EXIST::FUNCTION:DES - RSA_OAEP_PARAMS_it 4738 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:RSA -diff --git a/util/mkdef.pl b/util/mkdef.pl -index b9b159a..9841498 100755 ---- a/util/mkdef.pl -+++ b/util/mkdef.pl -@@ -97,6 +97,8 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", - "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM", - # Engines - "STATIC_ENGINE", "ENGINE", "HW", "GMP", -+ # X.509v3 Signed Certificate Timestamps -+ "SCT", - # RFC3779 - "RFC3779", - # TLS -@@ -144,7 +146,7 @@ my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2; - my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5; - my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw; - my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated; --my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng; -+my $no_sct; my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng; - my $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc; - my $no_nextprotoneg; my $no_sctp; my $no_srtp; my $no_ssl_trace; - my $no_unit_test; my $no_ssl3_method; my $no_ssl2_method; -@@ -235,6 +237,7 @@ foreach (@ARGV, split(/ /, $options)) - elsif (/^no-engine$/) { $no_engine=1; } - elsif (/^no-hw$/) { $no_hw=1; } - elsif (/^no-gmp$/) { $no_gmp=1; } -+ elsif (/^no-sct$/) { $no_sct=1; } - elsif (/^no-rfc3779$/) { $no_rfc3779=1; } - elsif (/^no-tlsext$/) { $no_tlsext=1; } - elsif (/^no-cms$/) { $no_cms=1; } -@@ -1209,6 +1212,7 @@ sub is_valid - if ($keyword eq "FP_API" && $no_fp_api) { return 0; } - if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; } - if ($keyword eq "GMP" && $no_gmp) { return 0; } -+ if ($keyword eq "SCT" && $no_sct) { return 0; } - if ($keyword eq "RFC3779" && $no_rfc3779) { return 0; } - if ($keyword eq "TLSEXT" && $no_tlsext) { return 0; } - if ($keyword eq "PSK" && $no_psk) { return 0; } -diff --git a/util/mkerr.pl b/util/mkerr.pl -index c197f3a..97b295c 100644 ---- a/util/mkerr.pl -+++ b/util/mkerr.pl -@@ -89,7 +89,7 @@ Options: - void ERR_load_<LIB>_strings(void); - void ERR_unload_<LIB>_strings(void); - void ERR_<LIB>_error(int f, int r, char *fn, int ln); -- #define <LIB>err(f,r) ERR_<LIB>_error(f,r,__FILE__,__LINE__) -+ #define <LIB>err(f,r) ERR_<LIB>_error(f,r,OPENSSL_FILE,OPENSSL_LINE) - while the code facilitates the use of these in an environment - where the error support routines are dynamically loaded at - runtime. -@@ -482,7 +482,7 @@ EOF - ${staticloader}void ERR_load_${lib}_strings(void); - ${staticloader}void ERR_unload_${lib}_strings(void); - ${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line); --# define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__) -+# define ${lib}err(f,r) ERR_${lib}_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - - EOF - } diff --git a/build-iso.sh b/build-iso.sh index 4643e16..413c119 100644 --- a/build-iso.sh +++ b/build-iso.sh @@ -6,25 +6,21 @@ dir="$1" # cfg shell="$dir/Shell.efi" enroll="$dir/EnrollDefaultKeys.efi" +root="$dir/image" vfat="$dir/shell.img" iso="$dir/UefiShell.iso" -export MTOOLS_SKIP_CHECK=1
-# calc size -s1=$(stat --format=%s -- $shell) -s2=$(stat --format=%s -- $enroll) -size=$(( ($s1 + $s2) * 11 / 10 )) -set -x - -# create non-partitioned FAT image -/usr/sbin/mkdosfs -C "$vfat" -n UEFI_SHELL -- "$(( $size / 1024 ))" -mmd -i "$vfat" ::efi -mmd -i "$vfat" ::efi/boot -mcopy -i "$vfat" "$shell" ::efi/boot/bootx64.efi -mcopy -i "$vfat" "$enroll" :: -#mdir -i "$vfat" -/ :: +# create non-partitioned (1.44 MB floppy disk) FAT image +mkdir "$root" +mkdir "$root"/efi +mkdir "$root"/efi/boot +cp "$shell" "$root"/efi/boot/bootx64.efi +cp "$enroll" "$root" +qemu-img convert --image-opts \ + driver=vvfat,floppy=on,fat-type=12,label=UEFI_SHELL,dir="$root/" \ + $vfat
# build ISO with FAT image file as El Torito EFI boot image genisoimage -input-charset ASCII -J -rational-rock \ -efi-boot "${vfat##*/}" -no-emul-boot -o "$iso" -- "$vfat" -rm -f "$vfat" +rm -rf "$root/" "$vfat" diff --git a/edk2.spec b/edk2.spec index 644df30..5e2a6ca 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,11 +1,21 @@ -%global edk2_date 20170209 -%global edk2_githash 296153c5 -%global openssl_version 1.0.2j +%global edk2_date 20180815 +%global edk2_githash cb5f4f45ce +%global openssl_version 1.1.0h +%global qosb_version 1.1.3
+%define qosb_testing 0 + +%ifarch x86_64 +%define qosb_testing 1 +%endif +%if 0%{?fedora:1} %define cross 1 +%endif
%ifarch %{ix86} x86_64 +%if 0%{?fedora:1} %define build_ovmf_ia32 1 +%endif %ifarch x86_64 %define build_ovmf_x64 1 %endif @@ -25,48 +35,61 @@
Name: edk2 Version: %{edk2_date}git%{edk2_githash} -Release: 7%{dist} +Release: 1%{dist} Summary: EFI Development Kit II
Group: Applications/Emulators License: BSD URL: http://www.tianocore.org/edk2/ + +# Tarball generated from git object update-tarball.sh script Source0: edk2-%{edk2_date}-%{edk2_githash}.tar.xz -# We have to remove certain patented algorithms from the openssl source -# tarball with the hobble-openssl script which is included below. -# The original openssl upstream tarball cannot be shipped in the .src.rpm. Source1: openssl-%{openssl_version}-hobbled.tar.xz -Source2: hobble-openssl -Source3: build-iso.sh -Source9: update-tarball.sh - -# This is the version of the OpenSSL patch that EDK2 applies, but -# with all changes to srp.* files removed. -Source10: EDKII_openssl-1.0.2j-no-srp.patch - -# Debug output tweaks, not for upstream +Source2: ovmf-whitepaper-c770f8c.txt +Source3: https://github.com/puiterwijk/qemu-ovmf-secureboot/archive/v%%7Bqosb_version... +Source10: hobble-openssl +Source11: build-iso.sh +Source12: update-tarball.sh +Source13: openssl-patch-to-tarball.sh + +# non-upstream patches Patch0001: 0001-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-NvmExpre.patch Patch0002: 0002-OvmfPkg-silence-EFI_D_VERBOSE-0x00400000-in-the-DXE-.patch Patch0003: 0003-OvmfPkg-enable-DEBUG_VERBOSE.patch Patch0004: 0004-OvmfPkg-increase-max-debug-message-length-to-512.patch -Patch0005: 0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch -# Exclude EFI shell from firmware, suggested by pjones re: secureboot. -# Not for upstream, see bug 1325023#c16 -Patch0006: 0006-EXCLUDE_SHELL_FROM_FD.patch -# Ship EnrollDefaultKeys application. -# Not for upstream, see bug 1325023#c16 -Patch0007: 0007-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch -# More text console resolutions. Upstreaming attempted, but failed -Patch0008: 0008-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch +Patch0005: 0005-advertise-OpenSSL-on-TianoCore-splash-screen-boot-lo.patch +Patch0006: 0006-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch +Patch0007: 0007-MdeModulePkg-TerminalDxe-add-other-text-resolutions.patch +Patch0008: 0008-MdeModulePkg-TerminalDxe-set-xterm-resolution-on-mod.patch +Patch0009: 0009-OvmfPkg-take-PcdResizeXterm-from-the-QEMU-command-li.patch +Patch0010: 0010-ArmVirtPkg-QemuFwCfgLib-allow-UEFI_DRIVER-client-mod.patch +Patch0011: 0011-ArmVirtPkg-take-PcdResizeXterm-from-the-QEMU-command.patch +Patch0012: 0012-OvmfPkg-allow-exclusion-of-the-shell-from-the-firmwa.patch +Patch0013: 0013-OvmfPkg-EnrollDefaultKeys-application-for-enrolling-.patch +Patch0014: 0014-ArmPlatformPkg-introduce-fixed-PCD-for-early-hello-m.patch +Patch0015: 0015-ArmPlatformPkg-PrePeiCore-write-early-hello-message-.patch +Patch0016: 0016-ArmVirtPkg-set-early-hello-message-RH-only.patch +# Fix passing through RPM build flags (bz 1540244) +Patch0017: 0017-BaseTools-footer.makefile-expand-BUILD_CFLAGS-last-f.patch +Patch0018: 0018-BaseTools-header.makefile-remove-c-from-BUILD_CFLAGS.patch +Patch0019: 0019-BaseTools-Source-C-split-O2-to-BUILD_OPTFLAGS.patch +Patch0020: 0020-BaseTools-Source-C-take-EXTRA_OPTFLAGS-from-the-call.patch +Patch0021: 0021-BaseTools-Source-C-take-EXTRA_LDFLAGS-from-the-calle.patch +Patch0022: 0022-BaseTools-VfrCompile-honor-EXTRA_LDFLAGS.patch + %if 0%{?cross:1} # Tweak the tools_def to support cross-compiling. -# These files are meant for customization, so this is not upstream. -Patch0009: 0009-Tweak-the-tools_def-to-support-cross-compiling.patch +# These files are meant for customization, so this is not upstream too. +Patch0099: 0099-Tweak-the-tools_def-to-support-cross-compiling.patch %endif
-# fix for build failure, sent upstream -Patch0010: 0010-VfrCompile-fix-invalid-comparison-between-pointer-an.patch +# openssl patches from Fedora +Patch1021: openssl-1.1.0-issuer-hash.patch +Patch1039: openssl-1.1.0-cc-reqs.patch +Patch1040: openssl-1.1.0-disable-ssl3.patch +Patch1044: openssl-1.1.0-bio-fd-preserve-nl.patch
+%if 0%{?fedora:1} # # actual firmware builds support cross-compiling. edk2-tools # in theory should build everywhere without much trouble, but @@ -74,7 +97,11 @@ Patch0010: 0010-VfrCompile-fix-invalid-comparison-between-pointer-an.patch # (such as ppc), so lets limit things to the known-good ones. # ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 +%else +ExclusiveArch: x86_64 aarch64 +%endif
+BuildRequires: gcc gcc-c++ BuildRequires: python BuildRequires: libuuid-devel %if 0%{?cross:1} @@ -84,10 +111,22 @@ BuildRequires: gcc-x86_64-linux-gnu %endif BuildRequires: iasl BuildRequires: nasm -BuildRequires: dosfstools -BuildRequires: mtools +BuildRequires: qemu-img BuildRequires: genisoimage
+# These are for QOSB +BuildRequires: python3-requests +BuildRequires: qemu-system-x86 +%if %{?qosb_testing} +# This is used for testing the enrollment: builds are run in a chroot, lacking +# a kernel. The testing is only performed on x86_64 for now, but we can't make +# the BuildRequires only on a specific arch, as that'd come through in the SRPM +# NOTE: The actual enrollment needs to happen in all builds for all architectures, +# because OVMF is built as noarch, which means that koji enforces that the build +# results don't actually differ per arch, and then it picks a random arches' build +# for the actual RPM. +BuildRequires: kernel-core +%endif
%description EDK II is a development code base for creating UEFI drivers, applications @@ -119,10 +158,22 @@ BuildArch: noarch This package documents the tools that are needed to build EFI executables and ROMs using the GNU tools.
+%package qosb +Summary: Tool to enroll secureboot +Group: Development/Tools +Buildarch: noarch +%description qosb +This package contains QOSB (QEMU OVMF Secure Boot), which can enroll OVMF +variable files to enforce Secure Boot. + + %if 0%{?build_ovmf_x64:1} %package ovmf Summary: Open Virtual Machine Firmware +# OVMF includes the Secure Boot and IPv6 features; it has a builtin OpenSSL +# library. License: BSD and OpenSSL +Provides: bundled(openssl) Provides: OVMF = %{version}-%{release} Obsoletes: OVMF < %{version}-%{release} BuildArch: noarch @@ -134,7 +185,10 @@ Open Virtual Machine Firmware (x64) %if 0%{?build_ovmf_ia32:1} %package ovmf-ia32 Summary: Open Virtual Machine Firmware +# OVMF includes the Secure Boot and IPv6 features; it has a builtin OpenSSL +# library. License: BSD and OpenSSL +Provides: bundled(openssl) BuildArch: noarch %description ovmf-ia32 EFI Development Kit II @@ -147,6 +201,9 @@ Summary: AARCH64 Virtual Machine Firmware Provides: AAVMF = %{version}-%{release} Obsoletes: AAVMF < %{version}-%{release} BuildArch: noarch +# No Secure Boot for AAVMF yet, but we include OpenSSL for the IPv6 stack. +License: BSD and OpenSSL +Provides: bundled(openssl) %description aarch64 EFI Development Kit II AARCH64 UEFI Firmware @@ -164,24 +221,32 @@ armv7 UEFI Firmware
%prep %setup -q -n tianocore-%{name}-%{edk2_githash} -%autopatch -p1
-# replace upstream patch with ours -cp %{SOURCE10} CryptoPkg/Library/OpensslLib/EDKII_openssl-%{openssl_version}.patch
-# add openssl -tar -C CryptoPkg/Library/OpensslLib -xf %{SOURCE1} -(cd CryptoPkg/Library/OpensslLib/openssl-%{openssl_version}; - patch -p1 < ../EDKII_openssl-%{openssl_version}.patch) -(cd CryptoPkg/Library/OpensslLib; ./Install.sh) -cp CryptoPkg/Library/OpensslLib/openssl-*/LICENSE LICENSE.openssl +# Ensure old shell and binary packages are not used +rm -rf EdkShellBinPkg +rm -rf EdkShellPkg +rm -rf FatBinPkg +rm -rf ShellBinPkg
+# copy whitepaper into place +cp -a -- %{SOURCE2} . +# extract openssl into place +tar -xvf %{SOURCE1} --strip-components=1 + +# Extract QOSB +tar -xvf %{SOURCE3} +mv qemu-ovmf-secureboot-%{qosb_version}/README.md README.qosb +mv qemu-ovmf-secureboot-%{qosb_version}/LICENSE LICENSE.qosb + +%autopatch -p1 +base64 --decode < MdeModulePkg/Logo/Logo-OpenSSL.bmp.b64 > MdeModulePkg/Logo/Logo-OpenSSL.bmp
%build source ./edksetup.sh
# compiler -CC_FLAGS="-t GCC49" +CC_FLAGS="-t GCC5"
# parallel builds JOBS="%{?_smp_mflags}" @@ -191,11 +256,13 @@ if test "$JOBS" != ""; then fi
# common features -CC_FLAGS="${CC_FLAGS} -b DEBUG" -CC_FLAGS="${CC_FLAGS} --cmd-len=65536" +CC_FLAGS="$CC_FLAGS --cmd-len=65536 -t %{TOOLCHAIN} -b DEBUG --hash" +CC_FLAGS="$CC_FLAGS -D NETWORK_IP6_ENABLE" +CC_FLAGS="$CC_FLAGS -D TPM2_ENABLE"
# ovmf features OVMF_FLAGS="${CC_FLAGS}" +OVMF_FLAGS="${OVMF_FLAGS} -D TLS_ENABLE" OVMF_FLAGS="${OVMF_FLAGS} -D HTTP_BOOT_ENABLE" OVMF_FLAGS="${OVMF_FLAGS} -D NETWORK_IP6_ENABLE" OVMF_FLAGS="${OVMF_FLAGS} -D FD_SIZE_2MB" @@ -211,15 +278,17 @@ ARM_FLAGS="${CC_FLAGS}" ARM_FLAGS="${ARM_FLAGS} -D DEBUG_PRINT_ERROR_LEVEL=0x8040004F"
unset MAKEFLAGS -make -C BaseTools #%{?_smp_mflags} +make -C BaseTools %{?_smp_mflags} \ + EXTRA_OPTFLAGS="%{optflags}" \ + EXTRA_LDFLAGS="%{__global_ldflags}" sed -i -e 's/-Werror//' Conf/tools_def.txt
%if 0%{?cross:1} -export GCC49_IA32_PREFIX="x86_64-linux-gnu-" -export GCC49_X64_PREFIX="x86_64-linux-gnu-" -export GCC49_AARCH64_PREFIX="aarch64-linux-gnu-" -export GCC49_ARM_PREFIX="arm-linux-gnu-" +export GCC5_IA32_PREFIX="x86_64-linux-gnu-" +export GCC5_X64_PREFIX="x86_64-linux-gnu-" +export GCC5_AARCH64_PREFIX="aarch64-linux-gnu-" +export GCC5_ARM_PREFIX="arm-linux-gnu-" %endif
# build ovmf (x64) @@ -237,7 +306,15 @@ cp Build/Ovmf3264/*/FV/OVMF_CODE.fd ovmf/OVMF_CODE.secboot.fd cp Build/Ovmf3264/*/X64/Shell.efi ovmf/ cp Build/Ovmf3264/*/X64/EnrollDefaultKeys.efi ovmf sh %{_sourcedir}/build-iso.sh ovmf/ -unset GCC49_X64_PREFIX + +# Build enrolled VARS file +python3 qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator \ + --qemu-binary /usr/bin/qemu-system-x86_64 \ + --skip-testing \ + --ovmf-binary ovmf/OVMF_CODE.secboot.fd \ + --ovmf-template-vars ovmf/OVMF_VARS.fd \ + --uefi-shell-iso ovmf/UefiShell.iso \ + ovmf/OVMF_VARS.secboot.fd %endif
@@ -256,7 +333,6 @@ cp Build/OvmfIa32/*/FV/OVMF_CODE.fd ovmf-ia32/OVMF_CODE.secboot.fd cp Build/OvmfIa32/*/IA32/Shell.efi ovmf-ia32/Shell.efi cp Build/OvmfIa32/*/IA32/EnrollDefaultKeys.efi ovmf-ia32/EnrollDefaultKeys.efi sh %{_sourcedir}/build-iso.sh ovmf-ia32/ -unset GCC49_IA32_PREFIX %endif
@@ -268,7 +344,6 @@ cp Build/ArmVirtQemu-AARCH64/DEBUG_*/FV/*.fd aarch64 dd of="aarch64/QEMU_EFI-pflash.raw" if="/dev/zero" bs=1M count=64 dd of="aarch64/QEMU_EFI-pflash.raw" if="aarch64/QEMU_EFI.fd" conv=notrunc dd of="aarch64/vars-template-pflash.raw" if="/dev/zero" bs=1M count=64 -unset GCC49_AARCH64_PREFIX %endif
@@ -280,10 +355,27 @@ cp Build/ArmVirtQemu-ARM/DEBUG_*/FV/*.fd arm dd of="arm/QEMU_EFI-pflash.raw" if="/dev/zero" bs=1M count=64 dd of="arm/QEMU_EFI-pflash.raw" if="arm/QEMU_EFI.fd" conv=notrunc dd of="arm/vars-template-pflash.raw" if="/dev/zero" bs=1M count=64 -unset GCC49_ARM_PREFIX +%endif + +%check +%if 0%{?build_ovmf_x64:1} +%if 0%{?qosb_testing} +# Verify enrolled VARS file +python3 qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator \ + --qemu-binary /usr/bin/qemu-system-x86_64 \ + --skip-enrollment \ + --print-output \ + --ovmf-binary ovmf/OVMF_CODE.secboot.fd \ + --ovmf-template-vars ovmf/OVMF_VARS.fd \ + --uefi-shell-iso ovmf/UefiShell.iso \ + --no-download \ + --kernel-path `rpm -ql kernel-core | grep "/vmlinuz$" -m 1` \ + ovmf/OVMF_VARS.secboot.fd +%endif %endif
%install +cp CryptoPkg/Library/OpensslLib/openssl/LICENSE LICENSE.openssl mkdir -p %{buildroot}%{_bindir} \ %{buildroot}%{_datadir}/%{name}/Conf \ %{buildroot}%{_datadir}/%{name}/Scripts @@ -314,6 +406,7 @@ mkdir %{buildroot}/usr/share/OVMF ln -sf ../%{name}/ovmf/OVMF_CODE.fd %{buildroot}/usr/share/OVMF ln -sf ../%{name}/ovmf/OVMF_CODE.secboot.fd %{buildroot}/usr/share/OVMF ln -sf ../%{name}/ovmf/OVMF_VARS.fd %{buildroot}/usr/share/OVMF +ln -sf ../%{name}/ovmf/OVMF_VARS.secboot.fd %{buildroot}/usr/share/OVMF ln -sf ../%{name}/ovmf/UefiShell.iso %{buildroot}/usr/share/OVMF %endif %if 0%{?build_ovmf_ia32:1} @@ -331,9 +424,15 @@ cp -a arm %{buildroot}/usr/share/%{name} ln -sf ../%{name}/arm/QEMU_EFI-pflash.raw %{buildroot}/usr/share/AAVMF/AAVMF32_CODE.fd %endif
+install qemu-ovmf-secureboot-%{qosb_version}/ovmf-vars-generator %{buildroot}%{_bindir} +
%files tools +%license License.txt +%license LICENSE.openssl %{_bindir}/BootSectImage +%{_bindir}/Brotli +%{_bindir}/DevicePath %{_bindir}/EfiLdrImage %{_bindir}/EfiRom %{_bindir}/GenCrc32 @@ -372,11 +471,17 @@ ln -sf ../%{name}/arm/QEMU_EFI-pflash.raw %{buildroot}/usr/share/AAVMF/ %files tools-doc %doc BaseTools/UserManuals/*.rtf
+%files qosb +%license LICENSE.qosb +%doc README.qosb +%{_bindir}/ovmf-vars-generator + %if 0%{?build_ovmf_x64:1} %files ovmf %license OvmfPkg/License.txt %license LICENSE.openssl %doc OvmfPkg/README +%doc ovmf-whitepaper-c770f8c.txt %dir /usr/share/%{name} %dir /usr/share/%{name}/ovmf /usr/share/%{name}/ovmf/OVMF*.fd @@ -390,6 +495,7 @@ ln -sf ../%{name}/arm/QEMU_EFI-pflash.raw %{buildroot}/usr/share/AAVMF/ %license OvmfPkg/License.txt %license LICENSE.openssl %doc OvmfPkg/README +%doc ovmf-whitepaper-c770f8c.txt %dir /usr/share/%{name} %dir /usr/share/%{name}/ovmf-ia32 /usr/share/%{name}/ovmf-ia32/OVMF*.fd @@ -399,7 +505,8 @@ ln -sf ../%{name}/arm/QEMU_EFI-pflash.raw %{buildroot}/usr/share/AAVMF/
%if 0%{?build_aavmf_aarch64:1} %files aarch64 -%license ArmVirtPkg/License.txt +%license OvmfPkg/License.txt +%license LICENSE.openssl %dir /usr/share/%{name} %dir /usr/share/%{name}/aarch64 /usr/share/%{name}/aarch64/QEMU*.fd @@ -409,7 +516,8 @@ ln -sf ../%{name}/arm/QEMU_EFI-pflash.raw %{buildroot}/usr/share/AAVMF/
%if 0%{?build_aavmf_arm:1} %files arm -%license ArmVirtPkg/License.txt +%license OvmfPkg/License.txt +%license LICENSE.openssl %dir /usr/share/%{name} %dir /usr/share/%{name}/arm /usr/share/%{name}/arm/QEMU*.fd @@ -419,6 +527,9 @@ ln -sf ../%{name}/arm/QEMU_EFI-pflash.raw %{buildroot}/usr/share/AAVMF/
%changelog +* Fri Aug 31 2018 Cole Robinson crobinso@redhat.com - 20180815gitcb5f4f45ce-1 +- Update to edk2 git cb5f4f45ce, edk2-stable201808 + * Mon Nov 13 2017 Paolo Bonzini pbonzini@redhat.com - 20170209git296153c5-6 - Allow non-cross builds - Install /usr/share/OVMF and /usr/share/AAVMF diff --git a/openssl-1.1.0-bio-fd-preserve-nl.patch b/openssl-1.1.0-bio-fd-preserve-nl.patch new file mode 100644 index 0000000..5d71291 --- /dev/null +++ b/openssl-1.1.0-bio-fd-preserve-nl.patch @@ -0,0 +1,34 @@ +diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c +index 2bd3517..a886655 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c +@@ -204,8 +204,10 @@ static int fd_gets(BIO *bp, char *buf, int size) + char *ptr = buf; + char *end = buf + size - 1; + +- while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n')) +- ptr++; ++ while (ptr < end && fd_read(bp, ptr, 1) > 0) { ++ if (*ptr++ == '\n') ++ break; ++ } + + ptr[0] = '\0'; + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_read.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_read.pod +index 45871c1..fe70e9f 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_read.pod ++++ b/CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_read.pod +@@ -23,7 +23,8 @@ in B<buf>. Usually this operation will attempt to read a line of data + from the BIO of maximum length B<len-1>. There are exceptions to this, + however; for example, BIO_gets() on a digest BIO will calculate and + return the digest and other BIOs may not support BIO_gets() at all. +-The returned string is always NUL-terminated. ++The returned string is always NUL-terminated and the '\n' is preserved ++if present in the input data. + + BIO_write() attempts to write B<len> bytes from B<buf> to BIO B<b>. + +-- +2.17.0 + diff --git a/openssl-1.1.0-cc-reqs.patch b/openssl-1.1.0-cc-reqs.patch new file mode 100644 index 0000000..b62e75f --- /dev/null +++ b/openssl-1.1.0-cc-reqs.patch @@ -0,0 +1,29 @@ +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_gen.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_gen.c +@@ -86,6 +86,12 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL)) + goto err; + ++ /* prepare minimum p and q difference */ ++ if (!BN_one(r3)) ++ goto err; ++ if (bitsp > 100 && !BN_lshift(r3, r3, bitsp - 100)) ++ goto err; ++ + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + +@@ -118,7 +124,9 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + do { + if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; +- } while (BN_cmp(rsa->p, rsa->q) == 0); ++ if (!BN_sub(r2, rsa->q, rsa->p)) ++ goto err; ++ } while (BN_ucmp(r2, r3) <= 0); + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; + ERR_set_mark(); +-- +2.17.0 + diff --git a/openssl-1.1.0-disable-ssl3.patch b/openssl-1.1.0-disable-ssl3.patch new file mode 100644 index 0000000..1e61659 --- /dev/null +++ b/openssl-1.1.0-disable-ssl3.patch @@ -0,0 +1,65 @@ +diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +index 8a190d2..6b4c5ae 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c +@@ -2653,6 +2653,13 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) + * or by using the SSL_CONF library. + */ + ret->options |= SSL_OP_NO_COMPRESSION; ++ /* ++ * Disable SSLv3 by default. Applications can ++ * re-enable it by configuring ++ * SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv3); ++ * or by using the SSL_CONF library. ++ */ ++ ret->options |= SSL_OP_NO_SSLv3; + + ret->tlsext_status_type = -1; + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/ssl_test.c b/CryptoPkg/Library/OpensslLib/openssl/test/ssl_test.c +index 2cbbddd..1a409d1 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/ssl_test.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/ssl_test.c +@@ -277,6 +277,7 @@ static int execute_test(SSL_TEST_FIXTURE fixture) + SSL_TEST_SERVERNAME_CB_NONE) { + server2_ctx = SSL_CTX_new(TLS_server_method()); + TEST_check(server2_ctx != NULL); ++ SSL_CTX_clear_options(server2_ctx, SSL_OP_NO_SSLv3); + } + client_ctx = SSL_CTX_new(TLS_client_method()); + TEST_check(SSL_CTX_set_max_proto_version(client_ctx, TLS_MAX_VERSION)); +@@ -290,11 +291,15 @@ static int execute_test(SSL_TEST_FIXTURE fixture) + TLS_MAX_VERSION)); + TEST_check(resume_server_ctx != NULL); + TEST_check(resume_client_ctx != NULL); ++ SSL_CTX_clear_options(resume_server_ctx, SSL_OP_NO_SSLv3); ++ SSL_CTX_clear_options(resume_client_ctx, SSL_OP_NO_SSLv3); + } + } + + TEST_check(server_ctx != NULL); + TEST_check(client_ctx != NULL); ++ SSL_CTX_clear_options(server_ctx, SSL_OP_NO_SSLv3); ++ SSL_CTX_clear_options(client_ctx, SSL_OP_NO_SSLv3); + + TEST_check(CONF_modules_load(conf, fixture.test_app, 0) > 0); + +diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/ssltest_old.c b/CryptoPkg/Library/OpensslLib/openssl/test/ssltest_old.c +index e77c692..e586072 100644 +--- a/CryptoPkg/Library/OpensslLib/openssl/test/ssltest_old.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/test/ssltest_old.c +@@ -1460,6 +1460,11 @@ int main(int argc, char *argv[]) + ERR_print_errors(bio_err); + goto end; + } ++ ++ SSL_CTX_clear_options(c_ctx, SSL_OP_NO_SSLv3); ++ SSL_CTX_clear_options(s_ctx, SSL_OP_NO_SSLv3); ++ SSL_CTX_clear_options(s_ctx2, SSL_OP_NO_SSLv3); ++ + /* + * Since we will use low security ciphersuites and keys for testing set + * security level to zero by default. Tests can override this by adding +-- +2.17.0 + diff --git a/openssl-1.1.0-issuer-hash.patch b/openssl-1.1.0-issuer-hash.patch new file mode 100644 index 0000000..74087f3 --- /dev/null +++ b/openssl-1.1.0-issuer-hash.patch @@ -0,0 +1,13 @@ +--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_cmp.c ++++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_cmp.c +@@ -39,6 +39,7 @@ unsigned long X509_issuer_and_serial_hash(X509 *a) + + if (ctx == NULL) + goto err; ++ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + f = X509_NAME_oneline(a->cert_info.issuer, NULL, 0); + if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) + goto err; +-- +2.17.0 + diff --git a/openssl-patch-to-tarball.sh b/openssl-patch-to-tarball.sh new file mode 100644 index 0000000..5b327ca --- /dev/null +++ b/openssl-patch-to-tarball.sh @@ -0,0 +1,63 @@ +#! /bin/sh + +: << \EOF + For importing the hobbled OpenSSL tarball from Fedora, the following + steps are necessary. Note that both the "sources" file format and the + pkgs.fedoraproject.org directory structure have changed, accommodating + SHA512 checksums. + + # in a separate directory + fedpkg clone -a openssl + cd openssl + fedpkg switch-branch master + gitk -- sources + + # the commit that added the 1.1.0h hobbled tarball is 6eb8f620273 + # subject "update to upstream version 1.1.0h" + git checkout 6eb8f620273 + + # fetch the hobbled tarball and verify the checksum + ( + set -e + while read HASH_TYPE FN EQ HASH; do + # remove leading and trailing parens + FN="${FN#(*}" + FN="${FN%*)}" + wget \ + http://pkgs.fedoraproject.org/repo/pkgs/openssl/$FN/sha512/$HASH/$FN + done <sources + sha512sum -c sources + ) + + # unpack the hobbled tarball into edk2, according to + # "OpenSSL-HOWTO.txt"; WORKSPACE stands for the root of the edk2 project + # tree + tar -x --xz -f openssl-1.1.0h-hobbled.tar.xz + mv -- openssl-1.1.0h "$WORKSPACE"/CryptoPkg/Library/OpensslLib/openssl + + # update the INF files as described in "OpenSSL-HOWTO.txt", then save + # the results as a single commit + (cd "$WORKSPACE"/CryptoPkg/Library/OpensslLib && perl process_files.pl) + git rm --cached CryptoPkg/Library/OpensslLib/openssl + git commit -m'remove openssl submodule' + git add -A CryptoPkg/Library/OpensslLib/openssl + git commit -m'add openssl 1.1.0h' + git format-patch -1 + +Then run the patch through this script which will build a new tar file. +EOF + +set -e +edk2_githash=$(awk '/^%global edk2_githash/ {print $3}' edk2.spec) +openssl_version=$(awk '/^%global openssl_version/ {print $3}' edk2.spec) +mkdir -p tianocore-openssl-${openssl_version} +(exec 3> openssl-${openssl_version}-hobbled.tar.xz + cd tianocore-openssl-${openssl_version} + git init . + git config core.whitespace cr-at-eol + git config am.keepcr true + git am + git archive --format=tar --prefix=tianocore-edk2-${edk2_githash}/ \ + HEAD CryptoPkg/Library/OpensslLib/ | \ + xz -9ev >&3) < $1 +rm -rf tianocore-openssl-${openssl_version} diff --git a/ovmf-whitepaper-c770f8c.txt b/ovmf-whitepaper-c770f8c.txt new file mode 100644 index 0000000..ba727b4 --- /dev/null +++ b/ovmf-whitepaper-c770f8c.txt @@ -0,0 +1,2422 @@ +Open Virtual Machine Firmware (OVMF) Status Report +July 2014 (with updates in August 2014 - January 2015) + +Author: Laszlo Ersek lersek@redhat.com +Copyright (C) 2014-2015, Red Hat, Inc. +CC BY-SA 4.0 http://creativecommons.org/licenses/by-sa/4.0/ + +Abstract +-------- + +The Unified Extensible Firmware Interface (UEFI) is a specification that +defines a software interface between an operating system and platform firmware. +UEFI is designed to replace the Basic Input/Output System (BIOS) firmware +interface. + +Hardware platform vendors have been increasingly adopting the UEFI +Specification to govern their boot firmware developments. OVMF (Open Virtual +Machine Firmware), a sub-project of Intel's EFI Development Kit II (edk2), +enables UEFI support for Ia32 and X64 Virtual Machines. + +This paper reports on the status of the OVMF project, treats features and +limitations, gives end-user hints, and examines some areas in-depth. + +Keywords: ACPI, boot options, CSM, edk2, firmware, flash, fw_cfg, KVM, memory +map, non-volatile variables, OVMF, PCD, QEMU, reset vector, S3, Secure Boot, +Smbios, SMM, TianoCore, UEFI, VBE shim, Virtio + +Table of Contents +----------------- + +- Motivation +- Scope +- Example qemu invocation +- Installation of OVMF guests with virt-manager and virt-install +- Supported guest operating systems +- Compatibility Support Module (CSM) +- Phases of the boot process +- Project structure +- Platform Configuration Database (PCD) +- Firmware image structure +- S3 (suspend to RAM and resume) +- A comprehensive memory map of OVMF +- Known Secure Boot limitations +- Variable store and LockBox in SMRAM +- Select features + - X64-specific reset vector for OVMF + - Client library for QEMU's firmware configuration interface + - Guest ACPI tables + - Guest SMBIOS tables + - Platform-specific boot policy + - Virtio drivers + - Platform Driver + - Video driver +- Afterword + +Motivation +---------- + +OVMF extends the usual benefits of virtualization to UEFI. Reasons to use OVMF +include: + +- Legacy-free guests. A UEFI-based environment eliminates dependencies on + legacy address spaces and devices. This is especially beneficial when used + with physically assigned devices where the legacy operating mode is + troublesome to support, ex. assigned graphics cards operating in legacy-free, + non-VGA mode in the guest. + +- Future proof guests. The x86 market is steadily moving towards a legacy-free + platform and guest operating systems may eventually require a UEFI + environment. OVMF provides that next generation firmware support for such + applications. + +- GUID partition tables (GPTs). MBR partition tables represent partition + offsets and sizes with 32-bit integers, in units of 512 byte sectors. This + limits the addressable portion of the disk to 2 TB. GPT represents logical + block addresses with 64 bits. + +- Liberating boot loader binaries from residing in contested and poorly defined + space between the partition table and the partitions. + +- Support for booting off disks (eg. pass-through physical SCSI devices) with a + 4kB physical and logical sector size, i.e. which don't have 512-byte block + emulation. + +- Development and testing of Secure Boot-related features in guest operating + systems. Although OVMF's Secure Boot implementation is currently not secure + against malicious UEFI drivers, UEFI applications, and guest kernels, + trusted guest code that only uses standard UEFI interfaces will find a valid + Secure Boot environment under OVMF, with working key enrollment and signature + validation. This enables development and testing of portable, Secure + Boot-related guest code. + +- Presence of non-volatile UEFI variables. This furthers development and + testing of OS installers, UEFI boot loaders, and unique, dependent guest OS + features. For example, an efivars-backed pstore (persistent storage) + file system works under Linux. + +- Altogether, a near production-level UEFI environment for virtual machines + when Secure Boot is not required. + +Scope +----- + +UEFI and especially Secure Boot have been topics fraught with controversy and +political activism. This paper sidesteps these aspects and strives to focus on +use cases, hands-on information for end users, and technical details. + +Unless stated otherwise, the expression "X supports Y" means "X is technically +compatible with interfaces provided or required by Y". It does not imply +support as an activity performed by natural persons or companies. + +We discuss the status of OVMF at a state no earlier than edk2 SVN revision +16158. The paper concentrates on upstream projects and communities, but +occasionally it pans out about OVMF as it is planned to be shipped (as +Technical Preview) in Red Hat Enterprise Linux 7.1. Such digressions are marked +with the [RHEL] margin notation. + +Although other VMMs and accelerators are known to support (or plan to support) +OVMF to various degrees -- for example, VirtualBox, Xen, BHyVe --, we'll +emphasize OVMF on qemu/KVM, because QEMU and KVM have always been Red Hat's +focus wrt. OVMF. + +The recommended upstream QEMU version is 2.1+. The recommended host Linux +kernel (KVM) version is 3.10+. The recommended QEMU machine type is +"qemu-system-x86_64 -M pc-i440fx-2.1" or later. + +The term "TianoCore" is used interchangeably with "edk2" in this paper. + +Example qemu invocation +----------------------- + +The following commands give a quick foretaste of installing a UEFI operating +system on OVMF, relying only on upstream edk2 and qemu. + +- Clone and build OVMF: + + git clone https://github.com/tianocore/edk2.git + cd edk2 + nice OvmfPkg/build.sh -a X64 -n $(getconf _NPROCESSORS_ONLN) + + (Note that this ad-hoc build will not include the Secure Boot feature.) + +- The build output file, "OVMF.fd", includes not only the executable firmware + code, but the non-volatile variable store as well. For this reason, make a + VM-specific copy of the build output (the variable store should be private to + the virtual machine): + + cp Build/OvmfX64/DEBUG_GCC4?/FV/OVMF.fd fedora.flash + + (The variable store and the firmware executable are also available in the + build output as separate files: "OVMF_VARS.fd" and "OVMF_CODE.fd". This + enables central management and updates of the firmware executable, while each + virtual machine can retain its own variable store.) + +- Download a Fedora LiveCD: + + wget https://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora... + +- Create a virtual disk (qcow2 format, 20 GB in size): + + qemu-img create -f qcow2 fedora.img 20G + +- Create the following qemu wrapper script under the name "fedora.sh": + + # Basic virtual machine properties: a recent i440fx machine type, KVM + # acceleration, 2048 MB RAM, two VCPUs. + OPTS="-M pc-i440fx-2.1 -enable-kvm -m 2048 -smp 2" + + # The OVMF binary, including the non-volatile variable store, appears as a + # "normal" qemu drive on the host side, and it is exposed to the guest as a + # persistent flash device. + OPTS="$OPTS -drive if=pflash,format=raw,file=fedora.flash" + + # The hard disk is exposed to the guest as a virtio-block device. OVMF has a + # driver stack that supports such a disk. We specify this disk as first boot + # option. OVMF recognizes the boot order specification. + OPTS="$OPTS -drive id=disk0,if=none,format=qcow2,file=fedora.img" + OPTS="$OPTS -device virtio-blk-pci,drive=disk0,bootindex=0" + + # The Fedora installer disk appears as an IDE CD-ROM in the guest. This is + # the 2nd boot option. + OPTS="$OPTS -drive id=cd0,if=none,format=raw,readonly" + OPTS="$OPTS,file=Fedora-Live-Xfce-x86_64-20-1.iso" + OPTS="$OPTS -device ide-cd,bus=ide.1,drive=cd0,bootindex=1" + + # The following setting enables S3 (suspend to RAM). OVMF supports S3 + # suspend/resume. + OPTS="$OPTS -global PIIX4_PM.disable_s3=0" + + # OVMF emits a number of info / debug messages to the QEMU debug console, at + # ioport 0x402. We configure qemu so that the debug console is indeed + # available at that ioport. We redirect the host side of the debug console to + # a file. + OPTS="$OPTS -global isa-debugcon.iobase=0x402 -debugcon file:fedora.ovmf.log" + + # QEMU accepts various commands and queries from the user on the monitor + # interface. Connect the monitor with the qemu process's standard input and + # output. + OPTS="$OPTS -monitor stdio" + + # A USB tablet device in the guest allows for accurate pointer tracking + # between the host and the guest. + OPTS="$OPTS -device piix3-usb-uhci -device usb-tablet" + + # Provide the guest with a virtual network card (virtio-net). + # + # Normally, qemu provides the guest with a UEFI-conformant network driver + # from the iPXE project, in the form of a PCI expansion ROM. For this test, + # we disable the expansion ROM and allow OVMF's built-in virtio-net driver to + # take effect. + # + # On the host side, we use the SLIRP ("user") network backend, which has + # relatively low performance, but it doesn't require extra privileges from + # the user executing qemu. + OPTS="$OPTS -netdev id=net0,type=user" + OPTS="$OPTS -device virtio-net-pci,netdev=net0,romfile=" + + # A Spice QXL GPU is recommended as the primary VGA-compatible display + # device. It is a full-featured virtual video card, with great operating + # system driver support. OVMF supports it too. + OPTS="$OPTS -device qxl-vga" + + qemu-system-x86_64 $OPTS + +- Start the Fedora guest: + + sh fedora.sh + +- The above command can be used for both installation and later boots of the + Fedora guest. + +- In order to verify basic OVMF network connectivity: + + - Assuming that the non-privileged user running qemu belongs to group G + (where G is a numeric identifier), ensure as root on the host that the + group range in file "/proc/sys/net/ipv4/ping_group_range" includes G. + + - As the non-privileged user, boot the guest as usual. + + - On the TianoCore splash screen, press ESC. + + - Navigate to Boot Manager | EFI Internal Shell + + - In the UEFI Shell, issue the following commands: + + ifconfig -s eth0 dhcp + ping A.B.C.D + + where A.B.C.D is a public IPv4 address in dotted decimal notation that your + host can reach. + + - Type "quit" at the (qemu) monitor prompt. + +Installation of OVMF guests with virt-manager and virt-install +-------------------------------------------------------------- + +(1) Assuming OVMF has been installed on the host with the following files: + - /usr/share/OVMF/OVMF_CODE.fd + - /usr/share/OVMF/OVMF_VARS.fd + + locate the "nvram" stanza in "/etc/libvirt/qemu.conf", and edit it as + follows: + + nvram = [ "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" ] + +(2) Restart libvirtd with your Linux distribution's service management tool; + for example, + + systemctl restart libvirtd + +(3) In virt-manager, proceed with the guest installation as usual: + - select File | New Virtual Machine, + - advance to Step 5 of 5, + - in Step 5, check "Customize configuration before install", + - click Finish; + - in the customization dialog, select Overview | Firmware, and choose UEFI, + - click Apply and Begin Installation. + +(4) With virt-install: + + LDR="loader=/usr/share/OVMF/OVMF_CODE.fd,loader_ro=yes,loader_type=pflash" + virt-install \ + --name fedora20 \ + --memory 2048 \ + --vcpus 2 \ + --os-variant fedora20 \ + --boot hd,cdrom,$LDR \ + --disk size=20 \ + --disk path=Fedora-Live-Xfce-x86_64-20-1.iso,device=cdrom,bus=scsi + +(5) A popular, distribution-independent, bleeding-edge OVMF package is + available under https://www.kraxel.org/repos/, courtesy of Gerd Hoffmann. + + The "edk2.git-ovmf-x64" package provides the following files, among others: + - /usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd + - /usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd + + When using this package, adapt steps (1) and (4) accordingly. + +(6) Additionally, the "edk2.git-ovmf-x64" package seeks to simplify the + enablement of Secure Boot in a virtual machine (strictly for development + and testing purposes). + + - Boot the virtual machine off the CD-ROM image called + "/usr/share/edk2.git/ovmf-x64/UefiShell.iso"; before or after installing + the main guest operating system. + + - When the UEFI shell appears, issue the following commands: + + EnrollDefaultKeys.efi + reset -s + + - The EnrollDefaultKeys.efi utility enrolls the following keys: + + - A static example X.509 certificate (CN=TestCommonName) as Platform Key + and first Key Exchange Key. + + The private key matching this certificate has been destroyed (but you + shouldn't trust this statement). + + - "Microsoft Corporation KEK CA 2011" as second Key Exchange Key + (SHA1: 31:59:0b:fd:89:c9:d7:4e:d0:87:df:ac:66:33:4b:39:31:25:4b:30). + + - "Microsoft Windows Production PCA 2011" as first DB entry + (SHA1: 58:0a:6f:4c:c4:e4:b6:69:b9:eb:dc:1b:2b:3e:08:7b:80:d0:67:8d). + + - "Microsoft Corporation UEFI CA 2011" as second DB entry + (SHA1: 46:de:f6:3b:5c:e6:1c:f8:ba:0d:e2:e6:63:9c:10:19:d0:ed:14:f3). + + These keys suffice to boot released versions of popular Linux + distributions (through the shim.efi utility), and Windows 8 and Windows + Server 2012 R2, in Secure Boot mode. + +Supported guest operating systems +--------------------------------- + +Upstream OVMF does not favor some guest operating systems over others for +political or ideological reasons. However, some operating systems are harder to +obtain and/or technically more difficult to support. The general expectation is +that recent UEFI OSes should just work. Please consult the "OvmfPkg/README" +file. + +The following guest OSes were tested with OVMF: +- Red Hat Enterprise Linux 6 +- Red Hat Enterprise Linux 7 +- Fedora 18 +- Fedora 19 +- Fedora 20 +- Windows Server 2008 R2 SP1 +- Windows Server 2012 +- Windows 8 + +Notes about Windows Server 2008 R2 (paraphrasing the "OvmfPkg/README" file): + +- QEMU should be started with one of the "-device qxl-vga" and "-device VGA" + options. + +- Only one video mode, 1024x768x32, is supported at OS runtime. + + Please refer to the section about QemuVideoDxe (OVMF's built-in video driver) + for more details on this limitation. + +- The qxl-vga video card is recommended ("-device qxl-vga"). After booting the + installed guest OS, select the video card in Device Manager, and upgrade the + video driver to the QXL XDDM one. + + The QXL XDDM driver can be downloaded from + http://www.spice-space.org/download.html, under Guest | Windows binaries. + + This driver enables additional graphics resolutions at OS runtime, and + provides S3 (suspend/resume) capability. + +Notes about Windows Server 2012 and Windows 8: + +- QEMU should be started with the "-device qxl-vga,revision=4" option (or a + later revision, if available). + +- The guest OS's builtin video driver inherits the video mode / frame buffer + from OVMF. There's no way to change the resolution at OS runtime. + + For this reason, a platform driver has been developed for OVMF, which allows + users to change the preferred video mode in the firmware. Please refer to the + section about PlatformDxe for details. + +- It is recommended to upgrade the guest OS's video driver to the QXL WDDM one, + via Device Manager. + + Binaries for the QXL WDDM driver can be found at + http://people.redhat.com/~vrozenfe/qxlwddm (pick a version greater than or + equal to 0.6), while the source code resides at + https://github.com/vrozenfe/qxl-dod. + + This driver enables additional graphics resolutions at OS runtime, and + provides S3 (suspend/resume) capability. + +Compatibility Support Module (CSM) +---------------------------------- + +Collaboration between SeaBIOS and OVMF developers has enabled SeaBIOS to be +built as a Compatibility Support Module, and OVMF to embed and use it. + +Benefits of a SeaBIOS CSM include: + +- The ability to boot legacy (non-UEFI) operating systems, such as legacy Linux + systems, Windows 7, OpenBSD 5.2, FreeBSD 8/9, NetBSD, DragonflyBSD, Solaris + 10/11. + +- Legacy (non-UEFI-compliant) PCI expansion ROMs, such as a VGA BIOS, mapped by + QEMU in emulated devices' ROM BARs, are loaded and executed by OVMF. + + For example, this grants the Windows Server 2008 R2 SP1 guest's native, + legacy video driver access to all modes of all QEMU video cards. + +Building the CSM target of the SeaBIOS source tree is out of scope for this +report. Additionally, upstream OVMF does not enable the CSM by default. + +Interested users and developers should look for OVMF's "-D CSM_ENABLE" +build-time option, and check out the https://www.kraxel.org/repos/ continuous +integration repository, which provides CSM-enabled OVMF builds. + +[RHEL] The "OVMF_CODE.fd" firmware image made available on the Red Hat + Enterprise Linux 7.1 host does not include a Compatibility Support + Module, for the following reasons: + + - Virtual machines running officially supported, legacy guest operating + systems should just use the standalone SeaBIOS firmware. Firmware + selection is flexible in virtualization, see eg. "Installation of OVMF + guests with virt-manager and virt-install" above. + + - The 16-bit thunking interface between OVMF and SeaBIOS is very complex + and presents a large debugging and support burden, based on past + experience. + + - Secure Boot is incompatible with CSM. + + - Inter-project dependencies should be minimized whenever possible. + + - Using the default QXL video card, the Windows 2008 R2 SP1 guest can be + installed with its built-in, legacy video driver. Said driver will + select the only available video mode, 1024x768x32. After installation, + the video driver can be upgraded to the full-featured QXL XDDM driver. + +Phases of the boot process +-------------------------- + +The PI and UEFI specifications, and Intel's UEFI and EDK II Learning and +Development materials provide ample information on PI and UEFI concepts. The +following is an absolutely minimal, rough glossary that is included only to +help readers new to PI and UEFI understand references in later, OVMF-specific +sections. We defer heavily to the official specifications and the training +materials, and frequently quote them below. + +A central concept to mention early is the GUID -- globally unique identifier. A +GUID is a 128-bit number, written as XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, +where each X stands for a hexadecimal nibble. GUIDs are used to name everything +in PI and in UEFI. Programmers introduce new GUIDs with the "uuidgen" utility, +and standards bodies standardize well-known services by positing their GUIDs. + +The boot process is roughly divided in the following phases: + +- Reset vector code. + +- SEC: Security phase. This phase is the root of firmware integrity. + +- PEI: Pre-EFI Initialization. This phase performs "minimal processor, chipset + and platform configuration for the purpose of discovering memory". Modules in + PEI collectively save their findings about the platform in a list of HOBs + (hand-off blocks). + + When developing PEI code, the Platform Initialization (PI) specification + should be consulted. + +- DXE: Driver eXecution Environment, pronounced as "Dixie". This "is the phase + where the bulk of the booting occurs: devices are enumerated and initialized, + UEFI services are supported, and protocols and drivers are implemented. Also, + the tables that create the UEFI interface are produced". + + On the PEI/DXE boundary, the HOBs produced by PEI are consumed. For example, + this is how the memory space map is configured initially. + +- BDS: Boot Device Selection. It is "responsible for determining how and where + you want to boot the operating system". + + When developing DXE and BDS code, it is mainly the UEFI specification that + should be consulted. When speaking about DXE, BDS is frequently considered to + be a part of it. + +The following concepts are tied to specific boot process phases: + +- PEIM: a PEI Module (pronounced "PIM"). A binary module running in the PEI + phase, consuming some PPIs and producing other PPIs, and producing HOBs. + +- PPI: PEIM-to-PEIM interface. A structure of function pointers and related + data members that establishes a PEI service, or an instance of a PEI service. + PPIs are identified by GUID. + + An example is EFI_PEI_S3_RESUME2_PPI (6D582DBC-DB85-4514-8FCC-5ADF6227B147). + +- DXE driver: a binary module running in the DXE and BDS phases, consuming some + protocols and producing other protocols. + +- Protocol: A structure of function pointers and related data members that + establishes a DXE service, or an instance of a DXE service. Protocols are + identified by GUID. + + An example is EFI_BLOCK_IO_PROTOCOL (964E5B21-6459-11D2-8E39-00A0C969723B). + +- Architectural protocols: a set of standard protocols that are foundational to + the working of a UEFI system. Each architectural protocol has at most one + instance. Architectural protocols are implemented by a subset of DXE drivers. + DXE drivers explicitly list the set of protocols (including architectural + protocols) that they need to work. UEFI drivers can only be loaded once all + architectural protocols have become available during the DXE phase. + + An example is EFI_VARIABLE_WRITE_ARCH_PROTOCOL + (6441F818-6362-4E44-B570-7DBA31DD2453). + +Project structure +----------------- + +The term "OVMF" usually denotes the project (community and development effort) +that provide and maintain the subject matter UEFI firmware for virtual +machines. However the term is also frequently applied to the firmware binary +proper that a virtual machine executes. + +OVMF emerges as a compilation of several modules from the edk2 source +repository. "edk2" stands for EFI Development Kit II; it is a "modern, +feature-rich, cross-platform firmware development environment for the UEFI and +PI specifications". + +The composition of OVMF is dictated by the following build control files: + + OvmfPkg/OvmfPkgIa32.dsc + OvmfPkg/OvmfPkgIa32.fdf + + OvmfPkg/OvmfPkgIa32X64.dsc + OvmfPkg/OvmfPkgIa32X64.fdf + + OvmfPkg/OvmfPkgX64.dsc + OvmfPkg/OvmfPkgX64.fdf + +The format of these files is described in the edk2 DSC and FDF specifications. +Roughly, the DSC file determines: +- library instance resolutions for library class requirements presented by the + modules to be compiled, +- the set of modules to compile. + +The FDF file roughly determines: +- what binary modules (compilation output files, precompiled binaries, graphics + image files, verbatim binary sections) to include in the firmware image, +- how to lay out the firmware image. + +The Ia32 flavor of these files builds a firmware where both PEI and DXE phases +are 32-bit. The Ia32X64 flavor builds a firmware where the PEI phase consists +of 32-bit modules, and the DXE phase is 64-bit. The X64 flavor builds a purely +64-bit firmware. + +The word size of the DXE phase must match the word size of the runtime OS -- a +32-bit DXE can't cooperate with a 64-bit OS, and a 64-bit DXE can't work a +32-bit OS. + +OVMF pulls together modules from across the edk2 tree. For example: + +- common drivers and libraries that are platform independent are usually + located under MdeModulePkg and MdePkg, + +- common but hardware-specific drivers and libraries that match QEMU's + pc-i440fx-* machine type are pulled in from IntelFrameworkModulePkg, + PcAtChipsetPkg and UefiCpuPkg, + +- the platform independent UEFI Shell is built from ShellPkg, + +- OvmfPkg includes drivers and libraries that are useful for virtual machines + and may or may not be specific to QEMU's pc-i440fx-* machine type. + +Platform Configuration Database (PCD) +------------------------------------- + +Like the "Phases of the boot process" section, this one introduces a concept in +very raw form. We defer to the PCD related edk2 specifications, and we won't +discuss implementation details here. Our purpose is only to offer the reader a +usable (albeit possibly inaccurate) definition, so that we can refer to PCDs +later on. + +Colloquially, when we say "PCD", we actually mean "PCD entry"; that is, an +entry stored in the Platform Configuration Database. + +The Platform Configuration Database is +- a firmware-wide +- name-value store +- of scalars and buffers +- where each entry may be + - build-time constant, or + - run-time dynamic, or + - theoretically, a middle option: patchable in the firmware file itself, + using a dedicated tool. (OVMF does not utilize externally patchable + entries.) + +A PCD entry is declared in the DEC file of the edk2 top-level Package directory +whose modules (drivers and libraries) are the primary consumers of the PCD +entry. (See for example OvmfPkg/OvmfPkg.dec). Basically, a PCD in a DEC file +exposes a simple customization point. + +Interest in a PCD entry is communicated to the build system by naming the PCD +entry in the INF file of the interested module (application, driver or +library). The module may read and -- dependent on the PCD entry's category -- +write the PCD entry. + +Let's investigate the characteristics of the Database and the PCD entries. + +- Firmware-wide: technically, all modules may access all entries they are + interested in, assuming they advertise their interest in their INF files. + With careful design, PCDs enable inter-driver propagation of (simple) system + configuration. PCDs are available in both PEI and DXE. + + (UEFI drivers meant to be portable (ie. from third party vendors) are not + supposed to use PCDs, since PCDs qualify internal to the specific edk2 + firmware in question.) + +- Name-value store of scalars and buffers: each PCD has a symbolic name, and a + fixed scalar type (UINT16, UINT32 etc), or VOID* for buffers. Each PCD entry + belongs to a namespace, where a namespace is (obviously) a GUID, defined in + the DEC file. + +- A DEC file can permit several categories for a PCD: + - build-time constant ("FixedAtBuild"), + - patchable in the firmware image ("PatchableInModule", unused in OVMF), + - runtime modifiable ("Dynamic"). + +The platform description file (DSC) of a top-level Package directory may choose +the exact category for a given PCD entry that its modules wish to use, and +assign a default (or constant) initial value to it. + +In addition, the edk2 build system too can initialize PCD entries to values +that it calculates while laying out the flash device image. Such PCD +assignments are described in the FDF control file. + +Firmware image structure +------------------------ + +(We assume the common X64 choice for both PEI and DXE, and the default DEBUG +build target.) + +The OvmfPkg/OvmfPkgX64.fdf file defines the following layout for the flash +device image "OVMF.fd": + + Description Compression type Size + ------------------------------ ---------------------- ------- + Non-volatile data storage open-coded binary data 128 KB + Variable store 56 KB + Event log 4 KB + Working block 4 KB + Spare area 64 KB + + FVMAIN_COMPACT uncompressed 1712 KB + FV Firmware File System file LZMA compressed + PEIFV uncompressed 896 KB + individual PEI modules uncompressed + DXEFV uncompressed 8192 KB + individual DXE modules uncompressed + + SECFV uncompressed 208 KB + SEC driver + reset vector code + +The top-level image consists of three regions (three firmware volumes): +- non-volatile data store (128 KB), +- main firmware volume (FVMAIN_COMPACT, 1712 KB), +- firmware volume containing the reset vector code and the SEC phase code (208 + KB). + +In total, the OVMF.fd file has size 128 KB + 1712 KB + 208 KB == 2 MB. + +(1) The firmware volume with non-volatile data store (128 KB) has the following + internal structure, in blocks of 4 KB: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ L: event log + LIVE | varstore |L|W| W: working block + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + SPARE | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The first half of this firmware volume is "live", while the second half is + "spare". The spare half is important when the variable driver reclaims + unused storage and reorganizes the variable store. + + The live half dedicates 14 blocks (56 KB) to the variable store itself. On + top of those, one block is set aside for an event log, and one block is + used as the working block of the fault tolerant write protocol. Fault + tolerant writes are used to recover from an occasional (virtual) power loss + during variable updates. + + The blocks in this firmware volume are accessed, in stacking order from + least abstract to most abstract, by: + + - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL (provided by + OvmfPkg/QemuFlashFvbServicesRuntimeDxe), + + - EFI_FAULT_TOLERANT_WRITE_PROTOCOL (provided by + MdeModulePkg/Universal/FaultTolerantWriteDxe), + + - architectural protocols instrumental to the runtime UEFI variable + services: + - EFI_VARIABLE_ARCH_PROTOCOL, + - EFI_VARIABLE_WRITE_ARCH_PROTOCOL. + + In a non-secure boot build, the DXE driver providing these architectural + protocols is MdeModulePkg/Universal/Variable/RuntimeDxe. In a secure boot + build, where authenticated variables are available, the DXE driver + offering these protocols is SecurityPkg/VariableAuthenticated/RuntimeDxe. + +(2) The main firmware volume (FVMAIN_COMPACT, 1712 KB) embeds further firmware + volumes. The outermost layer is a Firmware File System (FFS), carrying a + single file. This file holds an LZMA-compressed section, which embeds two + firmware volumes: PEIFV (896 KB) with PEIMs, and DXEFV (8192 KB) with DXE + and UEFI drivers. + + This scheme enables us to build 896 KB worth of PEI drivers and 8192 KB + worth of DXE and UEFI drivers, compress them all with LZMA in one go, and + store the compressed result in 1712 KB, saving room in the flash device. + +(3) The SECFV firmware volume (208 KB) is not compressed. It carries the + "volume top file" with the reset vector code, to end at 4 GB in + guest-physical address space, and the SEC phase driver (OvmfPkg/Sec). + + The last 16 bytes of the volume top file (mapped directly under 4 GB) + contain a NOP slide and a jump instruction. This is where QEMU starts + executing the firmware, at address 0xFFFF_FFF0. The reset vector and the + SEC driver run from flash directly. + + The SEC driver locates FVMAIN_COMPACT in the flash, and decompresses the + main firmware image to RAM. The rest of OVMF (PEI, DXE, BDS phases) run + from RAM. + +As already mentioned, the OVMF.fd file is mapped by qemu's +"hw/block/pflash_cfi01.c" device just under 4 GB in guest-physical address +space, according to the command line option + + -drive if=pflash,format=raw,file=fedora.flash + +(refer to the Example qemu invocation). This is a "ROMD device", which can +switch out of "ROMD mode" and back into it. + +Namely, in the default ROMD mode, the guest-physical address range backed by +the flash device reads and executes as ROM (it does not trap from KVM to QEMU). +The first write access in this mode traps to QEMU, and flips the device out of +ROMD mode. + +In non-ROMD mode, the flash chip is programmed by storing CFI (Common Flash +Interface) command values at the flash-covered addresses; both reads and writes +trap to QEMU, and the flash contents are modified and synchronized to the +host-side file. A special CFI command flips the flash device back to ROMD mode. + +Qemu implements the above based on the KVM_CAP_READONLY_MEM / KVM_MEM_READONLY +KVM features, and OVMF puts it to use in its EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL +implementation, under "OvmfPkg/QemuFlashFvbServicesRuntimeDxe". + +IMPORTANT: Never pass OVMF.fd to qemu with the -bios option. That option maps +the firmware image as ROM into the guest's address space, and forces OVMF to +emulate non-volatile variables with a fallback driver that is bound to have +insufficient and confusing semantics. + +The 128 KB firmware volume with the variable store, discussed under (1), is +also built as a separate host-side file, named "OVMF_VARS.fd". The "rest" is +built into a third file, "OVMF_CODE.fd", which is only 1920 KB in size. The +variable store is mapped into its usual location, at 4 GB - 2 MB = 0xFFE0_0000, +through the following qemu options: + + -drive if=pflash,format=raw,readonly,file=OVMF_CODE.fd \ + -drive if=pflash,format=raw,file=fedora.varstore.fd + +This way qemu configures two flash chips consecutively, with start addresses +growing downwards, which is transparent to OVMF. + +[RHEL] Red Hat Enterprise Linux 7.1 ships a Secure Boot-enabled, X64, DEBUG + firmware only. Furthermore, only the split files ("OVMF_VARS.fd" and + "OVMF_CODE.fd") are available. + +S3 (suspend to RAM and resume) +------------------------------ + +As noted in Example qemu invocation, the + + -global PIIX4_PM.disable_s3=0 + +command line option tells qemu and OVMF if the user would like to enable S3 +support. (This is corresponds to the /domain/pm/suspend-to-mem/@enabled libvirt +domain XML attribute.) + +Implementing / orchestrating S3 was a considerable community effort in OVMF. A +detailed description exceeds the scope of this report; we only make a few +statements. + +(1) S3-related PPIs and protocols are well documented in the PI specification. + +(2) Edk2 contains most modules that are needed to implement S3 on a given + platform. One abstraction that is central to the porting / extending of the + S3-related modules to a new platform is the LockBox library interface, + which a specific platform can fill in by implementing its own LockBox + library instance. + + The LockBox library provides a privileged name-value store (to be addressed + by GUIDs). The privilege separation stretches between the firmware and the + operating system. That is, the S3-related machinery of the firmware saves + some items in the LockBox securely, under well-known GUIDs, before booting + the operating system. During resume (which is a form of warm reset), the + firmware is activated again, and retrieves items from the LockBox. Before + jumping to the OS's resume vector, the LockBox is secured again. + + We'll return to this later when we separately discuss SMRAM and SMM. + +(3) During resume, the DXE and later phases are never reached; only the reset + vector, and the SEC and PEI phases of the firmware run. The platform is + supposed to detect a resume in progress during PEI, and to store that fact + in the BootMode field of the Phase Handoff Information Table (PHIT) HOB. + OVMF keys this off the CMOS, see OvmfPkg/PlatformPei. + + At the end of PEI, the DXE IPL PEIM (Initial Program Load PEI Module, see + MdeModulePkg/Core/DxeIplPeim) examines the Boot Mode, and if it says "S3 + resume in progress", then the IPL branches to the PEIM that exports + EFI_PEI_S3_RESUME2_PPI (provided by UefiCpuPkg/Universal/Acpi/S3Resume2Pei) + rather than loading the DXE core. + + S3Resume2Pei executes the technical steps of the resumption, relying on the + contents of the LockBox. + +(4) During first boot (or after a normal platform reset), when DXE does run, + hardware drivers in the DXE phase are encouraged to "stash" their hardware + configuration steps (eg. accesses to PCI config space, I/O ports, memory + mapped addresses, and so on) in a centrally maintained, so called "S3 boot + script". Hardware accesses are represented with opcodes of a special binary + script language. + + This boot script is to be replayed during resume, by S3Resume2Pei. The + general goal is to bring back hardware devices -- which have been powered + off during suspend -- to their original after-first-boot state, and in + particular, to do so quickly. + + At the moment, OVMF saves only one opcode in the S3 resume boot script: an + INFORMATION opcode, with contents 0xDEADBEEF (in network byte order). The + consensus between Linux developers seems to be that boot firmware is only + responsible for restoring basic chipset state, which OVMF does during PEI + anyway, independently of S3 vs. normal reset. (One example is the power + management registers of the i440fx chipset.) Device and peripheral state is + the responsibility of the runtime operating system. + + Although an experimental OVMF S3 boot script was at one point captured for + the virtual Cirrus VGA card, such a boot script cannot follow eg. video + mode changes effected by the OS. Hence the operating system can never avoid + restoring device state, and most Linux display drivers (eg. stdvga, QXL) + already cover S3 resume fully. + + The XDDM and WDDM driver models used under Windows OSes seem to recognize + this notion of runtime OS responsibility as well. (See the list of OSes + supported by OVMF in a separate section.) + +(5) The S3 suspend/resume data flow in OVMF is included here tersely, for + interested developers. + + (a) BdsLibBootViaBootOption() + EFI_ACPI_S3_SAVE_PROTOCOL [AcpiS3SaveDxe] + - saves ACPI S3 Context to LockBox ---------------------+ + (including FACS address -- FACS ACPI table | + contains OS waking vector) | + | + - prepares boot script: | + EFI_S3_SAVE_STATE_PROTOCOL.Write() [S3SaveStateDxe] | + S3BootScriptLib [PiDxeS3BootScriptLib] | + - opcodes & arguments are saved in NVS. --+ | + | | + - issues a notification by installing | | + EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL | | + | | + (b) EFI_S3_SAVE_STATE_PROTOCOL [S3SaveStateDxe] | | + S3BootScriptLib [PiDxeS3BootScriptLib] | | + - closes script with special opcode <---------+ | + - script is available in non-volatile memory | + via PcdS3BootScriptTablePrivateDataPtr --+ | + | | + BootScriptExecutorDxe | | + S3BootScriptLib [PiDxeS3BootScriptLib] | | + - Knows about boot script location by <----+ | + synchronizing with the other library | + instance via | + PcdS3BootScriptTablePrivateDataPtr. | + - Copies relocated image of itself to | + reserved memory. --------------------------------+ | + - Saved image contains pointer to boot script. ---|--+ | + | | | + Runtime: | | | + | | | + (c) OS is booted, writes OS waking vector to FACS, | | | + suspends machine | | | + | | | + S3 Resume (PEI): | | | + | | | + (d) PlatformPei sets S3 Boot Mode based on CMOS | | | + | | | + (e) DXE core is skipped and EFI_PEI_S3_RESUME2 is | | | + called as last step of PEI | | | + | | | + (f) S3Resume2Pei retrieves from LockBox: | | | + - ACPI S3 Context (path to FACS) <------------------|--|--+ + | | | + +------------------|--|--+ + - Boot Script Executor Image <----------------------+ | | + | | + (g) BootScriptExecutorDxe | | + S3BootScriptLib [PiDxeS3BootScriptLib] | | + - executes boot script <-----------------------------+ | + | + (h) OS waking vector available from ACPI S3 Context / FACS <--+ + is called + +A comprehensive memory map of OVMF +---------------------------------- + +The following section gives a detailed analysis of memory ranges below 4 GB +that OVMF statically uses. + +In the rightmost column, the PCD entry is identified by which the source refers +to the address or size in question. + +The flash-covered range has been discussed previously in "Firmware image +structure", therefore we include it only for completeness. Due to the fact that +this range is always backed by a memory mapped device (and never RAM), it is +unaffected by S3 (suspend to RAM and resume). + ++--------------------------+ 4194304 KB +| | +| SECFV | size: 208 KB +| | ++--------------------------+ 4194096 KB +| | +| FVMAIN_COMPACT | size: 1712 KB +| | ++--------------------------+ 4192384 KB +| | +| variable store | size: 64 KB PcdFlashNvStorageFtwSpareSize +| spare area | +| | ++--------------------------+ 4192320 KB PcdOvmfFlashNvStorageFtwSpareBase +| | +| FTW working block | size: 4 KB PcdFlashNvStorageFtwWorkingSize +| | ++--------------------------+ 4192316 KB PcdOvmfFlashNvStorageFtwWorkingBase +| | +| Event log of | size: 4 KB PcdOvmfFlashNvStorageEventLogSize +| non-volatile storage | +| | ++--------------------------+ 4192312 KB PcdOvmfFlashNvStorageEventLogBase +| | +| variable store | size: 56 KB PcdFlashNvStorageVariableSize +| | ++--------------------------+ 4192256 KB PcdOvmfFlashNvStorageVariableBase + +The flash-mapped image of OVMF.fd covers the entire structure above (2048 KB). + +When using the split files, the address 4192384 KB +(PcdOvmfFlashNvStorageFtwSpareBase + PcdFlashNvStorageFtwSpareSize) is the +boundary between the mapped images of OVMF_VARS.fd (56 KB + 4 KB + 4 KB + 64 KB += 128 KB) and OVMF_CODE.fd (1712 KB + 208 KB = 1920 KB). + +With regard to RAM that is statically used by OVMF, S3 (suspend to RAM and +resume) complicates matters. Many ranges have been introduced only to support +S3, hence for all ranges below, the following questions will be audited: + +(a) when and how a given range is initialized after first boot of the VM, +(b) how it is protected from memory allocations during DXE, +(c) how it is protected from the OS, +(d) how it is accessed on the S3 resume path, +(e) how it is accessed on the warm reset path. + +Importantly, the term "protected" is meant as protection against inadvertent +reallocations and overwrites by co-operating DXE and OS modules. It does not +imply security against malicious code. + ++--------------------------+ 17408 KB +| | +|DXEFV from FVMAIN_COMPACT | size: 8192 KB PcdOvmfDxeMemFvSize +| decompressed firmware | +| volume with DXE modules | +| | ++--------------------------+ 9216 KB PcdOvmfDxeMemFvBase +| | +|PEIFV from FVMAIN_COMPACT | size: 896 KB PcdOvmfPeiMemFvSize +| decompressed firmware | +| volume with PEI modules | +| | ++--------------------------+ 8320 KB PcdOvmfPeiMemFvBase +| | +| permanent PEI memory for | size: 32 KB PcdS3AcpiReservedMemorySize +| the S3 resume path | +| | ++--------------------------+ 8288 KB PcdS3AcpiReservedMemoryBase +| | +| temporary SEC/PEI heap | size: 32 KB PcdOvmfSecPeiTempRamSize +| and stack | +| | ++--------------------------+ 8256 KB PcdOvmfSecPeiTempRamBase +| | +| unused | size: 32 KB +| | ++--------------------------+ 8224 KB +| | +| SEC's table of | size: 4 KB PcdGuidedExtractHandlerTableSize +| GUIDed section handlers | +| | ++--------------------------+ 8220 KB PcdGuidedExtractHandlerTableAddress +| | +| LockBox storage | size: 4 KB PcdOvmfLockBoxStorageSize +| | ++--------------------------+ 8216 KB PcdOvmfLockBoxStorageBase +| | +| early page tables on X64 | size: 24 KB PcdOvmfSecPageTablesSize +| | ++--------------------------+ 8192 KB PcdOvmfSecPageTablesBase + +(1) Early page tables on X64: + + (a) when and how it is initialized after first boot of the VM + + The range is filled in during the SEC phase + [OvmfPkg/ResetVector/Ia32/PageTables64.asm]. The CR3 register is verified + against the base address in SecCoreStartupWithStack() + [OvmfPkg/Sec/SecMain.c]. + + (b) how it is protected from memory allocations during DXE + + If S3 was enabled on the QEMU command line (see "-global + PIIX4_PM.disable_s3=0" earlier), then InitializeRamRegions() + [OvmfPkg/PlatformPei/MemDetect.c] protects the range with an AcpiNVS memory + allocation HOB, in PEI. + + If S3 was disabled, then this range is not protected. DXE's own page tables + are first built while still in PEI (see HandOffToDxeCore() + [MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c]). Those tables are located + in permanent PEI memory. After CR3 is switched over to them (which occurs + before jumping to the DXE core entry point), we don't have to preserve the + initial tables. + + (c) how it is protected from the OS + + If S3 is enabled, then (1b) reserves it from the OS too. + + If S3 is disabled, then the range needs no protection. + + (d) how it is accessed on the S3 resume path + + It is rewritten same as in (1a), which is fine because (1c) reserved it. + + (e) how it is accessed on the warm reset path + + It is rewritten same as in (1a). + +(2) LockBox storage: + + (a) when and how it is initialized after first boot of the VM + + InitializeRamRegions() [OvmfPkg/PlatformPei/MemDetect.c] zeroes out the + area during PEI. This is correct but not strictly necessary, since on first + boot the area is zero-filled anyway. + + The LockBox signature of the area is filled in by the PEI module or DXE + driver that has been linked against OVMF's LockBoxLib and is run first. The + signature is written in LockBoxLibInitialize() + [OvmfPkg/Library/LockBoxLib/LockBoxLib.c]. + + Any module calling SaveLockBox() [OvmfPkg/Library/LockBoxLib/LockBoxLib.c] + will co-populate this area. + + (b) how it is protected from memory allocations during DXE + + If S3 is enabled, then InitializeRamRegions() + [OvmfPkg/PlatformPei/MemDetect.c] protects the range as AcpiNVS. + + Otherwise, the range is covered with a BootServicesData memory allocation + HOB. + + (c) how it is protected from the OS + + If S3 is enabled, then (2b) protects it sufficiently. + + Otherwise the range requires no runtime protection, and the + BootServicesData allocation type from (2b) ensures that the range will be + released to the OS. + + (d) how it is accessed on the S3 resume path + + The S3 Resume PEIM restores data from the LockBox, which has been correctly + protected in (2c). + + (e) how it is accessed on the warm reset path + + InitializeRamRegions() [OvmfPkg/PlatformPei/MemDetect.c] zeroes out the + range during PEI, effectively emptying the LockBox. Modules will + re-populate the LockBox as described in (2a). + +(3) SEC's table of GUIDed section handlers + + (a) when and how it is initialized after first boot of the VM + + The following two library instances are linked into SecMain: + - IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib, + - MdePkg/Library/BaseExtractGuidedSectionLib. + + The first library registers its LZMA decompressor plugin (which is a called + a "section handler") by calling the second library: + + LzmaDecompressLibConstructor() [GuidedSectionExtraction.c] + ExtractGuidedSectionRegisterHandlers() [BaseExtractGuidedSectionLib.c] + + The second library maintains its table of registered "section handlers", to + be indexed by GUID, in this fixed memory area, independently of S3 + enablement. + + (The decompression of FVMAIN_COMPACT's FFS file section that contains the + PEIFV and DXEFV firmware volumes occurs with the LZMA decompressor + registered above. See (6) and (7) below.) + + (b) how it is protected from memory allocations during DXE + + There is no need to protect this area from DXE: because nothing else in + OVMF links against BaseExtractGuidedSectionLib, the area loses its + significance as soon as OVMF progresses from SEC to PEI, therefore DXE is + allowed to overwrite the region. + + (c) how it is protected from the OS + + When S3 is enabled, we cover the range with an AcpiNVS memory allocation + HOB in InitializeRamRegions(). + + When S3 is disabled, the range is not protected. + + (d) how it is accessed on the S3 resume path + + The table of registered section handlers is again managed by + BaseExtractGuidedSectionLib linked into SecMain exclusively. Section + handler registrations update the table in-place (based on GUID matches). + + (e) how it is accessed on the warm reset path + + If S3 is enabled, then the OS won't damage the table (due to (3c)), thus + see (3d). + + If S3 is disabled, then the OS has most probably overwritten the range with + its own data, hence (3a) -- complete reinitialization -- will come into + effect, based on the table signature check in BaseExtractGuidedSectionLib. + +(4) temporary SEC/PEI heap and stack + + (a) when and how it is initialized after first boot of the VM + + The range is configured in [OvmfPkg/Sec/X64/SecEntry.S] and + SecCoreStartupWithStack() [OvmfPkg/Sec/SecMain.c]. The stack half is read & + written by the CPU transparently. The heap half is used for memory + allocations during PEI. + + Data is migrated out (to permanent PEI stack & memory) in (or soon after) + PublishPeiMemory() [OvmfPkg/PlatformPei/MemDetect.c]. + + (b) how it is protected from memory allocations during DXE + + It is not necessary to protect this range during DXE because its use ends + still in PEI. + + (c) how it is protected from the OS + + If S3 is enabled, then InitializeRamRegions() + [OvmfPkg/PlatformPei/MemDetect.c] reserves it as AcpiNVS. + + If S3 is disabled, then the range doesn't require protection. + + (d) how it is accessed on the S3 resume path + + Same as in (4a), except the target area of the migration triggered by + PublishPeiMemory() [OvmfPkg/PlatformPei/MemDetect.c] is different -- see + (5). + + (e) how it is accessed on the warm reset path + + Same as in (4a). The stack and heap halves both may contain garbage, but it + doesn't matter. + +(5) permanent PEI memory for the S3 resume path + + (a) when and how it is initialized after first boot of the VM + + No particular initialization or use. + + (b) how it is protected from memory allocations during DXE + + We don't need to protect this area during DXE. + + (c) how it is protected from the OS + + When S3 is enabled, InitializeRamRegions() + [OvmfPkg/PlatformPei/MemDetect.c] makes sure the OS stays away by covering + the range with an AcpiNVS memory allocation HOB. + + When S3 is disabled, the range needs no protection. + + (d) how it is accessed on the S3 resume path + + PublishPeiMemory() installs the range as permanent RAM for PEI. The range + will serve as stack and will satisfy allocation requests during the rest of + PEI. OS data won't overlap due to (5c). + + (e) how it is accessed on the warm reset path + + Same as (5a). + +(6) PEIFV -- decompressed firmware volume with PEI modules + + (a) when and how it is initialized after first boot of the VM + + DecompressMemFvs() [OvmfPkg/Sec/SecMain.c] populates the area, by + decompressing the flash-mapped FVMAIN_COMPACT volume's contents. (Refer to + "Firmware image structure".) + + (b) how it is protected from memory allocations during DXE + + When S3 is disabled, PeiFvInitialization() [OvmfPkg/PlatformPei/Fv.c] + covers the range with a BootServicesData memory allocation HOB. + + When S3 is enabled, the same is coverage is ensured, just with the stronger + AcpiNVS memory allocation type. + + (c) how it is protected from the OS + + When S3 is disabled, it is not necessary to keep the range from the OS. + + Otherwise the AcpiNVS type allocation from (6b) provides coverage. + + (d) how it is accessed on the S3 resume path + + Rather than decompressing it again from FVMAIN_COMPACT, GetS3ResumePeiFv() + [OvmfPkg/Sec/SecMain.c] reuses the protected area for parsing / execution + from (6c). + + (e) how it is accessed on the warm reset path + + Same as (6a). + +(7) DXEFV -- decompressed firmware volume with DXE modules + + (a) when and how it is initialized after first boot of the VM + + Same as (6a). + + (b) how it is protected from memory allocations during DXE + + PeiFvInitialization() [OvmfPkg/PlatformPei/Fv.c] covers the range with a + BootServicesData memory allocation HOB. + + (c) how it is protected from the OS + + The OS is allowed to release and reuse this range. + + (d) how it is accessed on the S3 resume path + + It's not; DXE never runs during S3 resume. + + (e) how it is accessed on the warm reset path + + Same as in (7a). + +Known Secure Boot limitations +----------------------------- + +Under "Motivation" we've mentioned that OVMF's Secure Boot implementation is +not suitable for production use yet -- it's only good for development and +testing of standards-conformant, non-malicious guest code (UEFI and operating +system alike). + +Now that we've examined the persistent flash device, the workings of S3, and +the memory map, we can discuss two currently known shortcomings of OVMF's +Secure Boot that in fact make it insecure. (Clearly problems other than these +two might exist; the set of issues considered here is not meant to be +exhaustive.) + +One trait of Secure Boot is tamper-evidence. Secure Boot may not prevent +malicious modification of software components (for example, operating system +drivers), but by being the root of integrity on a platform, it can catch (or +indirectly contribute to catching) unauthorized changes, by way of signature +and certificate checks at the earliest phases of boot. + +If an attacker can tamper with key material stored in authenticated and/or +boot-time only persistent variables (for example, PK, KEK, db, dbt, dbx), then +the intended security of this scheme is compromised. The UEFI 2.4A +specification says + +- in section 28.3.4: + + Platform Keys: + + The public key must be stored in non-volatile storage which is tamper and + delete resistant. + + Key Exchange Keys: + + The public key must be stored in non-volatile storage which is tamper + resistant. + +- in section 28.6.1: + + The signature database variables db, dbt, and dbx must be stored in + tamper-resistant non-volatile storage. + +(1) The combination of QEMU, KVM, and OVMF does not provide this kind of + resistance. The variable store in the emulated flash chip is directly + accessible to, and reprogrammable by, UEFI drivers, applications, and + operating systems. + +(2) Under "S3 (suspend to RAM and resume)" we pointed out that the LockBox + storage must be similarly secure and tamper-resistant. + + On the S3 resume path, the PEIM providing EFI_PEI_S3_RESUME2_PPI + (UefiCpuPkg/Universal/Acpi/S3Resume2Pei) restores and interprets data from + the LockBox that has been saved there during boot. This PEIM, being part of + the firmware, has full access to the platform. If an operating system can + tamper with the contents of the LockBox, then at the next resume the + platform's integrity might be subverted. + + OVMF stores the LockBox in normal guest RAM (refer to the memory map + section above). Operating systems and third party UEFI drivers and UEFI + applications that respect the UEFI memory map will not inadvertently + overwrite the LockBox storage, but there's nothing to prevent eg. a + malicious kernel from modifying the LockBox. + +One means to address these issues is SMM and SMRAM (System Management Mode and +System Management RAM). + +During boot and resume, the firmware can enter and leave SMM and access SMRAM. +Before the DXE phase is left, and control is transferred to the BDS phase (when +third party UEFI drivers and applications can be loaded, and an operating +system can be loaded), SMRAM is locked in hardware, and subsequent modules +cannot access it directly. (See EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL.) + +Once SMRAM has been locked, UEFI drivers and the operating system can enter SMM +by raising a System Management Interrupt (SMI), at which point trusted code +(part of the platform firmware) takes control. SMRAM is also unlocked by +platform reset, at which point the boot firmware takes control again. + +Variable store and LockBox in SMRAM +----------------------------------- + +Edk2 provides almost all components to implement the variable store and the +LockBox in SMRAM. In this section we summarize ideas for utilizing those +facilities. + +The SMRAM and SMM infrastructure in edk2 is built up as follows: + +(1) The platform hardware provides SMM / SMI / SMRAM. + + Qemu/KVM doesn't support these features currently and should implement them + in the longer term. + +(2) The platform vendor (in this case, OVMF developers) implement device + drivers for the platform's System Management Mode: + + - EFI_SMM_CONTROL2_PROTOCOL: for raising a synchronous (and/or) periodic + SMI(s); that is, for entering SMM. + + - EFI_SMM_ACCESS2_PROTOCOL: for describing and accessing SMRAM. + + These protocols are documented in the PI Specification, Volume 4. + +(3) The platform DSC file is to include the following platform-independent + modules: + + - MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf: SMM Initial Program Load + - MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf: SMM Core + +(4) At this point, modules of type DXE_SMM_DRIVER can be loaded. + + Such drivers are privileged. They run in SMM, have access to SMRAM, and are + separated and switched from other drivers through SMIs. Secure + communication between unprivileged (non-SMM) and privileged (SMM) drivers + happens through EFI_SMM_COMMUNICATION_PROTOCOL (implemented by the SMM + Core, see (3)). + + DXE_SMM_DRIVER modules must sanitize their input (coming from unprivileged + drivers) carefully. + +(5) The authenticated runtime variable services driver (for Secure Boot builds) + is located under "SecurityPkg/VariableAuthenticated/RuntimeDxe". OVMF + currently builds the driver (a DXE_RUNTIME_DRIVER module) with the + "VariableRuntimeDxe.inf" control file (refer to "OvmfPkg/OvmfPkgX64.dsc"), + which does not use SMM. + + The directory includes two more INF files: + + - VariableSmm.inf -- module type: DXE_SMM_DRIVER. A privileged driver that + runs in SMM and has access to SMRAM. + + - VariableSmmRuntimeDxe.inf -- module type: DXE_RUNTIME_DRIVER. A + non-privileged driver that implements the variable runtime services + (replacing the current "VariableRuntimeDxe.inf" file) by communicating + with the above privileged SMM half via EFI_SMM_COMMUNICATION_PROTOCOL. + +(6) An SMRAM-based LockBox implementation needs to be discussed in two parts, + because the LockBox is accessed in both PEI and DXE. + + (a) During DXE, drivers save data in the LockBox. A save operation is + layered as follows: + + - The unprivileged driver wishing to store data in the LockBox links + against the "MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf" + library instance. + + The library allows the unprivileged driver to format requests for the + privileged SMM LockBox driver (see below), and to parse responses. + + - The privileged SMM LockBox driver is built from + "MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf". This + driver has module type DXE_SMM_DRIVER and can access SMRAM. + + The driver delegates command parsing and response formatting to + "MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf". + + - The above two halves (unprivileged and privileged) mirror what we've + seen in case of the variable service drivers, under (5). + + (b) In PEI, the S3 Resume PEIM (UefiCpuPkg/Universal/Acpi/S3Resume2Pei) + retrieves data from the LockBox. + + Presumably, S3Resume2Pei should be considered an "unprivileged PEIM", + and the SMRAM access should be layered as seen in DXE. Unfortunately, + edk2 does not implement all of the layers in PEI -- the code either + doesn't exist, or it is not open source: + + role | DXE: protocol/module | PEI: PPI/module + -------------+--------------------------------+------------------------------ + unprivileged | any | S3Resume2Pei.inf + driver | | + -------------+--------------------------------+------------------------------ + command | LIBRARY_CLASS = LockBoxLib | LIBRARY_CLASS = LockBoxLib + formatting | | + and response | SmmLockBoxDxeLib.inf | SmmLockBoxPeiLib.inf + parsing | | + -------------+--------------------------------+------------------------------ + privilege | EFI_SMM_COMMUNICATION_PROTOCOL | EFI_PEI_SMM_COMMUNICATION_PPI + separation | | + | PiSmmCore.inf | missing! + -------------+--------------------------------+------------------------------ + platform SMM | EFI_SMM_CONTROL2_PROTOCOL | PEI_SMM_CONTROL_PPI + and SMRAM | EFI_SMM_ACCESS2_PROTOCOL | PEI_SMM_ACCESS_PPI + access | | + | to be done in OVMF | to be done in OVMF + -------------+--------------------------------+------------------------------ + command | LIBRARY_CLASS = LockBoxLib | LIBRARY_CLASS = LockBoxLib + parsing and | | + response | SmmLockBoxSmmLib.inf | missing! + formatting | | + -------------+--------------------------------+------------------------------ + privileged | SmmLockBox.inf | missing! + LockBox | | + driver | | + + Alternatively, in the future OVMF might be able to provide a LockBoxLib + instance (an SmmLockBoxPeiLib substitute) for S3Resume2Pei that + accesses SMRAM directly, eliminating the need for deeper layers in the + stack (that is, EFI_PEI_SMM_COMMUNICATION_PPI and deeper). + + In fact, a "thin" EFI_PEI_SMM_COMMUNICATION_PPI implementation whose + sole Communicate() member invariably returns EFI_NOT_STARTED would + cause the current SmmLockBoxPeiLib library instance to directly perform + full-depth SMRAM access and LockBox search, obviating the "missing" + cells. (With reference to A Tour Beyond BIOS: Implementing S3 Resume + with EDK2, by Jiewen Yao and Vincent Zimmer, October 2014.) + +Select features +--------------- + +In this section we'll browse the top-level "OvmfPkg" package directory, and +discuss the more interesting drivers and libraries that have not been mentioned +thus far. + +X64-specific reset vector for OVMF +.................................. + +The "OvmfPkg/ResetVector" directory customizes the reset vector (found in +"UefiCpuPkg/ResetVector/Vtf0") for "OvmfPkgX64.fdf", that is, when the SEC/PEI +phases run in 64-bit (ie. long) mode. + +The reset vector's control flow looks roughly like: + + resetVector [Ia16/ResetVectorVtf0.asm] + EarlyBspInitReal16 [Ia16/Init16.asm] + Main16 [Main.asm] + EarlyInit16 [Ia16/Init16.asm] + + ; Transition the processor from + ; 16-bit real mode to 32-bit flat mode + TransitionFromReal16To32BitFlat [Ia16/Real16ToFlat32.asm] + + ; Search for the + ; Boot Firmware Volume (BFV) + Flat32SearchForBfvBase [Ia32/SearchForBfvBase.asm] + + ; Search for the SEC entry point + Flat32SearchForSecEntryPoint [Ia32/SearchForSecEntry.asm] + + %ifdef ARCH_IA32 + ; Jump to the 32-bit SEC entry point + %else + ; Transition the processor + ; from 32-bit flat mode + ; to 64-bit flat mode + Transition32FlatTo64Flat [Ia32/Flat32ToFlat64.asm] + + SetCr3ForPageTables64 [Ia32/PageTables64.asm] + ; set CR3 to page tables + ; built into the ROM image + + ; enable PAE + ; set LME + ; enable paging + + ; Jump to the 64-bit SEC entry point + %endif + +On physical platforms, the initial page tables referenced by +SetCr3ForPageTables64 are built statically into the flash device image, and are +present in ROM at runtime. This is fine on physical platforms because the +pre-built page table entries have the Accessed and Dirty bits set from the +start. + +Accordingly, for OVMF running in long mode on qemu/KVM, the initial page tables +were mapped as a KVM_MEM_READONLY slot, as part of QEMU's pflash device (refer +to "Firmware image structure" above). + +In spite of the Accessed and Dirty bits being pre-set in the read-only, +in-flash PTEs, in a virtual machine attempts are made to update said PTE bits, +differently from physical hardware. The component attempting to update the +read-only PTEs can be one of the following: + +- The processor itself, if it supports nested paging, and the user enables that + processor feature, + +- KVM code implementing shadow paging, otherwise. + +The first case presents no user-visible symptoms, but the second case (KVM, +shadow paging) used to cause a triple fault, prior to Linux commit ba6a354 +("KVM: mmu: allow page tables to be in read-only slots"). + +For compatibility with earlier KVM versions, the OvmfPkg/ResetVector directory +adapts the generic reset vector code as follows: + + Transition32FlatTo64Flat [UefiCpuPkg/.../Ia32/Flat32ToFlat64.asm] + + SetCr3ForPageTables64 [OvmfPkg/ResetVector/Ia32/PageTables64.asm] + + ; dynamically build the initial page tables in RAM, at address + ; PcdOvmfSecPageTablesBase (refer to the memory map above), + ; identity-mapping the first 4 GB of address space + + ; set CR3 to PcdOvmfSecPageTablesBase + + ; enable PAE + ; set LME + ; enable paging + +This way the PTEs that earlier KVM versions try to update (during shadow +paging) are located in a read-write memory slot, and the write attempts +succeed. + +Client library for QEMU's firmware configuration interface +.......................................................... + +QEMU provides a write-only, 16-bit wide control port, and a read-write, 8-bit +wide data port for exchanging configuration elements with the firmware. + +The firmware writes a selector (a key) to the control port (0x510), and then +reads the corresponding configuration data (produced by QEMU) from the data +port (0x511). + +If the selected entry is writable, the firmware may overwrite it. If QEMU has +associated a callback with the entry, then when the entry is completely +rewritten, QEMU runs the callback. (OVMF does not rewrite any entries at the +moment.) + +A number of selector values (keys) are predefined. In particular, key 0x19 +selects (returns) a directory of { name, selector, size } triplets, roughly +speaking. + +The firmware can request configuration elements by well-known name as well, by +looking up the selector value first in the directory, by name, and then writing +the selector to the control port. The number of bytes to read subsequently from +the data port is known from the directory entry's "size" field. + +By convention, directory entries (well-known symbolic names of configuration +elements) are formatted as POSIX pathnames. For example, the array selected by +the "etc/system-states" name indicates (among other things) whether the user +enabled S3 support in QEMU. + +The above interface is called "fw_cfg". + +The binary data associated with a symbolic name is called an "fw_cfg file". + +OVMF's fw_cfg client library is found in "OvmfPkg/Library/QemuFwCfgLib". OVMF +discovers many aspects of the virtual system with it; we refer to a few +examples below. + +Guest ACPI tables +................. + +An operating system discovers a good amount of its hardware by parsing ACPI +tables, and by interpreting ACPI objects and methods. On physical hardware, the +platform vendor's firmware installs ACPI tables in memory that match both the +hardware present in the system and the user's firmware configuration ("BIOS +setup"). + +Under qemu/KVM, the owner of the (virtual) hardware configuration is QEMU. +Hardware can easily be reconfigured on the command line. Furthermore, features +like CPU hotplug, PCI hotplug, memory hotplug are continuously developed for +QEMU, and operating systems need direct ACPI support to exploit these features. + +For this reason, QEMU builds its own ACPI tables dynamically, in a +self-descriptive manner, and exports them to the firmware through a complex, +multi-file fw_cfg interface. It is rooted in the "etc/table-loader" fw_cfg +file. (Further details of this interface are out of scope for this report.) + +OVMF's AcpiPlatformDxe driver fetches the ACPI tables, and installs them for +the guest OS with the EFI_ACPI_TABLE_PROTOCOL (which is in turn provided by the +generic "MdeModulePkg/Universal/Acpi/AcpiTableDxe" driver). + +For earlier QEMU versions and machine types (which we generally don't recommend +for OVMF; see "Scope"), the "OvmfPkg/AcpiTables" directory contains a few +static ACPI table templates. When the "etc/table-loader" fw_cfg file is +unavailable, AcpiPlatformDxe installs these default tables (with a little bit +of dynamic patching). + +When OVMF runs in a Xen domU, AcpiTableDxe also installs ACPI tables that +originate from the hypervisor's environment. + +Guest SMBIOS tables +................... + +Quoting the SMBIOS Reference Specification, + + [...] the System Management BIOS Reference Specification addresses how + motherboard and system vendors present management information about their + products in a standard format [...] + +In practice SMBIOS tables are just another set of tables that the platform +vendor's firmware installs in RAM for the operating system, and, importantly, +for management applications running on the OS. Without rehashing the "Guest +ACPI tables" section in full, let's map the OVMF roles seen there from ACPI to +SMBIOS: + + role | ACPI | SMBIOS + -------------------------+-------------------------+------------------------- + fw_cfg file | etc/table-loader | etc/smbios/smbios-tables + -------------------------+-------------------------+------------------------- + OVMF driver | AcpiPlatformDxe | SmbiosPlatformDxe + under "OvmfPkg" | | + -------------------------+-------------------------+------------------------- + Underlying protocol, | EFI_ACPI_TABLE_PROTOCOL | EFI_SMBIOS_PROTOCOL + implemented by generic | | + driver under | Acpi/AcpiTableDxe | SmbiosDxe + "MdeModulePkg/Universal" | | + -------------------------+-------------------------+------------------------- + default tables available | yes | [RHEL] yes, Type0 and + for earlier QEMU machine | | Type1 tables + types, with hot-patching | | + -------------------------+-------------------------+------------------------- + tables fetched in Xen | yes | yes + domUs | | + +Platform-specific boot policy +............................. + +OVMF's BDS (Boot Device Selection) phase is implemented by +IntelFrameworkModulePkg/Universal/BdsDxe. Roughly speaking, this large driver: + +- provides the EFI BDS architectural protocol (which DXE transfers control to + after dispatching all DXE drivers), + +- connects drivers to devices, + +- enumerates boot devices, + +- auto-generates boot options, + +- provides "BIOS setup" screens, such as: + + - Boot Manager, for booting an option, + + - Boot Maintenance Manager, for adding, deleting, and reordering boot + options, changing console properties etc, + + - Device Manager, where devices can register configuration forms, including + + - Secure Boot configuration forms, + + - OVMF's Platform Driver form (see under PlatformDxe). + +Firmware that includes the "IntelFrameworkModulePkg/Universal/BdsDxe" driver +can customize its behavior by providing an instance of the PlatformBdsLib +library class. The driver links against this platform library, and the +platform library can call Intel's BDS utility functions from +"IntelFrameworkModulePkg/Library/GenericBdsLib". + +OVMF's PlatformBdsLib instance can be found in +"OvmfPkg/Library/PlatformBdsLib". The main function where the BdsDxe driver +enters the library is PlatformBdsPolicyBehavior(). We mention two OVMF +particulars here. + +(1) OVMF is capable of loading kernel images directly from fw_cfg, matching + QEMU's -kernel, -initrd, and -append command line options. This feature is + useful for rapid, repeated Linux kernel testing, and is implemented in the + following call tree: + + PlatformBdsPolicyBehavior() [OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c] + TryRunningQemuKernel() [OvmfPkg/Library/PlatformBdsLib/QemuKernel.c] + LoadLinux*() [OvmfPkg/Library/LoadLinuxLib/Linux.c] + + OvmfPkg/Library/LoadLinuxLib ports the efilinux bootloader project into + OvmfPkg. + +(2) OVMF seeks to comply with the boot order specification passed down by QEMU + over fw_cfg. + + (a) About Boot Modes + + During the PEI phase, OVMF determines and stores the Boot Mode in the + PHIT HOB (already mentioned in "S3 (suspend to RAM and resume)"). The + boot mode is supposed to influence the rest of the system, for example it + distinguishes S3 resume (BOOT_ON_S3_RESUME) from a "normal" boot. + + In general, "normal" boots can be further differentiated from each other; + for example for speed reasons. When the firmware can tell during PEI that + the chassis has not been opened since last power-up, then it might want + to save time by not connecting all devices and not enumerating all boot + options from scratch; it could just rely on the stored results of the + last enumeration. The matching BootMode value, to be set during PEI, + would be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES. + + OVMF only sets one of the following two boot modes, based on CMOS + contents: + - BOOT_ON_S3_RESUME, + - BOOT_WITH_FULL_CONFIGURATION. + + For BOOT_ON_S3_RESUME, please refer to "S3 (suspend to RAM and resume)". + The other boot mode supported by OVMF, BOOT_WITH_FULL_CONFIGURATION, is + an appropriate "catch-all" for a virtual machine, where hardware can + easily change from boot to boot. + + (b) Auto-generation of boot options + + Accordingly, when not resuming from S3 sleep (*), OVMF always connects + all devices, and enumerates all bootable devices as new boot options + (non-volatile variables called Boot####). + + (*) During S3 resume, DXE is not reached, hence BDS isn't either. + + The auto-enumerated boot options are stored in the BootOrder non-volatile + variable after any preexistent options. (Boot options may exist before + auto-enumeration eg. because the user added them manually with the Boot + Maintenance Manager or the efibootmgr utility. They could also originate + from an earlier auto-enumeration.) + + PlatformBdsPolicyBehavior() [OvmfPkg/.../BdsPlatform.c] + TryRunningQemuKernel() [OvmfPkg/.../QemuKernel.c] + BdsLibConnectAll() [IntelFrameworkModulePkg/.../BdsConnect.c] + BdsLibEnumerateAllBootOption() [IntelFrameworkModulePkg/.../BdsBoot.c] + BdsLibBuildOptionFromHandle() [IntelFrameworkModulePkg/.../BdsBoot.c] + BdsLibRegisterNewOption() [IntelFrameworkModulePkg/.../BdsMisc.c] + // + // Append the new option number to the original option order + // + + (c) Relative UEFI device paths in boot options + + The handling of relative ("short-form") UEFI device paths is best + demonstrated through an example, and by quoting the UEFI 2.4A + specification. + + A short-form hard drive UEFI device path could be (displaying each device + path node on a separate line for readability): + + HD(1,GPT,14DD1CC5-D576-4BBF-8858-BAF877C8DF61,0x800,0x64000)/ + \EFI\fedora\shim.efi + + This device path lacks prefix nodes (eg. hardware or messaging type + nodes) that would lead to the hard drive. During load option processing, + the above short-form or relative device path could be matched against the + following absolute device path: + + PciRoot(0x0)/ + Pci(0x4,0x0)/ + HD(1,GPT,14DD1CC5-D576-4BBF-8858-BAF877C8DF61,0x800,0x64000)/ + \EFI\fedora\shim.efi + + The motivation for this type of device path matching / completion is to + allow the user to move around the hard drive (for example, to plug a + controller in a different PCI slot, or to expose the block device on a + different iSCSI path) and still enable the firmware to find the hard + drive. + + The UEFI specification says, + + 9.3.6 Media Device Path + 9.3.6.1 Hard Drive + + [...] Section 3.1.2 defines special rules for processing the Hard + Drive Media Device Path. These special rules enable a disk's location + to change and still have the system boot from the disk. [...] + + 3.1.2 Load Option Processing + + [...] The boot manager must [...] support booting from a short-form + device path that starts with the first element being a hard drive + media device path [...]. The boot manager must use the GUID or + signature and partition number in the hard drive device path to match + it to a device in the system. If the drive supports the GPT + partitioning scheme the GUID in the hard drive media device path is + compared with the UniquePartitionGuid field of the GUID Partition + Entry [...]. If the drive supports the PC-AT MBR scheme the signature + in the hard drive media device path is compared with the + UniqueMBRSignature in the Legacy Master Boot Record [...]. If a + signature match is made, then the partition number must also be + matched. The hard drive device path can be appended to the matching + hardware device path and normal boot behavior can then be used. If + more than one device matches the hard drive device path, the boot + manager will pick one arbitrarily. Thus the operating system must + ensure the uniqueness of the signatures on hard drives to guarantee + deterministic boot behavior. + + Edk2 implements and exposes the device path completion logic in the + already referenced "IntelFrameworkModulePkg/Library/GenericBdsLib" + library, in the BdsExpandPartitionPartialDevicePathToFull() function. + + (d) Filtering and reordering the boot options based on fw_cfg + + Once we have an "all-inclusive", partly preexistent, partly freshly + auto-generated boot option list from bullet (b), OVMF loads QEMU's + requested boot order from fw_cfg, and filters and reorders the list from + (b) with it: + + PlatformBdsPolicyBehavior() [OvmfPkg/.../BdsPlatform.c] + TryRunningQemuKernel() [OvmfPkg/.../QemuKernel.c] + BdsLibConnectAll() [IntelFrameworkModulePkg/.../BdsConnect.c] + BdsLibEnumerateAllBootOption() [IntelFrameworkModulePkg/.../BdsBoot.c] + SetBootOrderFromQemu() [OvmfPkg/.../QemuBootOrder.c] + + According to the (preferred) "-device ...,bootindex=N" and the (legacy) + '-boot order=drives' command line options, QEMU requests a boot order + from the firmware through the "bootorder" fw_cfg file. (For a bootindex + example, refer to the "Example qemu invocation" section.) + + This fw_cfg file consists of OpenFirmware (OFW) device paths -- note: not + UEFI device paths! --, one per line. An example list is: + + /pci@i0cf8/scsi@4/disk@0,0 + /pci@i0cf8/ide@1,1/drive@1/disk@0 + /pci@i0cf8/ethernet@3/ethernet-phy@0 + + OVMF filters and reorders the boot option list from bullet (b) with the + following nested loops algorithm: + + new_uefi_order := <empty> + for each qemu_ofw_path in QEMU's OpenFirmware device path list: + qemu_uefi_path_prefix := translate(qemu_ofw_path) + + for each boot_option in current_uefi_order: + full_boot_option := complete(boot_option) + + if match(qemu_uefi_path_prefix, full_boot_option): + append(new_uefi_order, boot_option) + break + + for each unmatched boot_option in current_uefi_order: + if survives(boot_option): + append(new_uefi_order, boot_option) + + current_uefi_order := new_uefi_order + + OVMF iterates over QEMU's OFW device paths in order, translates each to a + UEFI device path prefix, tries to match the translated prefix against the + UEFI boot options (which are completed from relative form to absolute + form for the purpose of prefix matching), and if there's a match, the + matching boot option is appended to the new boot order (which starts out + empty). + + (We elaborate on the translate() function under bullet (e). The + complete() function has been explained in bullet (c).) + + In addition, UEFI boot options that remain unmatched after filtering and + reordering are post-processed, and some of them "survive". Due to the + fact that OpenFirmware device paths have less expressive power than their + UEFI counterparts, some UEFI boot options are simply inexpressible (hence + unmatchable) by the nested loops algorithm. + + An important example is the memory-mapped UEFI shell, whose UEFI device + path is inexpressible by QEMU's OFW device paths: + + MemoryMapped(0xB,0x900000,0x10FFFFF)/ + FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1) + + (Side remark: notice that the address range visible in the MemoryMapped() + node corresponds to DXEFV under "comprehensive memory map of OVMF"! In + addition, the FvFile() node's GUID originates from the FILE_GUID entry of + "ShellPkg/Application/Shell/Shell.inf".) + + The UEFI shell can be booted by pressing ESC in OVMF on the TianoCore + splash screen, and navigating to Boot Manager | EFI Internal Shell. If + the "survival policy" was not implemented, the UEFI shell's boot option + would always be filtered out. + + The current "survival policy" preserves all boot options that start with + neither PciRoot() nor HD(). + + (e) Translating QEMU's OpenFirmware device paths to UEFI device path + prefixes + + In this section we list the (strictly heuristical) mappings currently + performed by OVMF. + + The "prefix only" nature of the translation output is rooted minimally in + the fact that QEMU's OpenFirmware device paths cannot carry pathnames + within filesystems. There's no way to specify eg. + + \EFI\fedora\shim.efi + + in an OFW device path, therefore a UEFI device path translated from an + OFW device path can at best be a prefix (not a full match) of a UEFI + device path that ends with "\EFI\fedora\shim.efi". + + - IDE disk, IDE CD-ROM: + + OpenFirmware device path: + + /pci@i0cf8/ide@1,1/drive@0/disk@0 + ^ ^ ^ ^ ^ + | | | | master or slave + | | | primary or secondary + | PCI slot & function holding IDE controller + PCI root at system bus port, PIO + + UEFI device path prefix: + + PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0) + ^ + fixed LUN + + - Floppy disk: + + OpenFirmware device path: + + /pci@i0cf8/isa@1/fdc@03f0/floppy@0 + ^ ^ ^ ^ + | | | A: or B: + | | ISA controller io-port (hex) + | PCI slot holding ISA controller + PCI root at system bus port, PIO + + UEFI device path prefix: + + PciRoot(0x0)/Pci(0x1,0x0)/Floppy(0x0) + ^ + ACPI UID (A: or B:) + + - Virtio-block disk: + + OpenFirmware device path: + + /pci@i0cf8/scsi@6[,3]/disk@0,0 + ^ ^ ^ ^ ^ + | | | fixed + | | PCI function corresponding to disk (optional) + | PCI slot holding disk + PCI root at system bus port, PIO + + UEFI device path prefixes (dependent on the presence of a nonzero PCI + function in the OFW device path): + + PciRoot(0x0)/Pci(0x6,0x0)/HD( + PciRoot(0x0)/Pci(0x6,0x3)/HD( + + - Virtio-scsi disk and virtio-scsi passthrough: + + OpenFirmware device path: + + /pci@i0cf8/scsi@7[,3]/channel@0/disk@2,3 + ^ ^ ^ ^ ^ + | | | | LUN + | | | target + | | channel (unused, fixed 0) + | PCI slot[, function] holding SCSI controller + PCI root at system bus port, PIO + + UEFI device path prefixes (dependent on the presence of a nonzero PCI + function in the OFW device path): + + PciRoot(0x0)/Pci(0x7,0x0)/Scsi(0x2,0x3) + PciRoot(0x0)/Pci(0x7,0x3)/Scsi(0x2,0x3) + + - Emulated and passed-through (physical) network cards: + + OpenFirmware device path: + + /pci@i0cf8/ethernet@3[,2] + ^ ^ + | PCI slot[, function] holding Ethernet card + PCI root at system bus port, PIO + + UEFI device path prefixes (dependent on the presence of a nonzero PCI + function in the OFW device path): + + PciRoot(0x0)/Pci(0x3,0x0) + PciRoot(0x0)/Pci(0x3,0x2) + +Virtio drivers +.............. + +UEFI abstracts various types of hardware resources into protocols, and allows +firmware developers to implement those protocols in device drivers. The Virtio +Specification defines various types of virtual hardware for virtual machines. +Connecting the two specifications, OVMF provides UEFI drivers for QEMU's +virtio-block, virtio-scsi, and virtio-net devices. + +The following diagram presents the protocol and driver stack related to Virtio +devices in edk2 and OVMF. Each node in the graph identifies a protocol and/or +the edk2 driver that produces it. Nodes on the top are more abstract. + + EFI_BLOCK_IO_PROTOCOL EFI_SIMPLE_NETWORK_PROTOCOL + [OvmfPkg/VirtioBlkDxe] [OvmfPkg/VirtioNetDxe] + | | + | EFI_EXT_SCSI_PASS_THRU_PROTOCOL | + | [OvmfPkg/VirtioScsiDxe] | + | | | + +------------------------+--------------------------+ + | + VIRTIO_DEVICE_PROTOCOL + | + +---------------------+---------------------+ + | | + [OvmfPkg/VirtioPciDeviceDxe] [custom platform drivers] + | | + | | + EFI_PCI_IO_PROTOCOL [OvmfPkg/Library/VirtioMmioDeviceLib] + [MdeModulePkg/Bus/Pci/PciBusDxe] direct MMIO register access + +The top three drivers produce standard UEFI abstractions: the Block IO +Protocol, the Extended SCSI Pass Thru Protocol, and the Simple Network +Protocol, for virtio-block, virtio-scsi, and virtio-net devices, respectively. + +Comparing these device-specific virtio drivers to each other, we can determine: + +- They all conform to the UEFI Driver Model. This means that their entry point + functions don't immediately start to search for devices and to drive them, + they only register instances of the EFI_DRIVER_BINDING_PROTOCOL. The UEFI + Driver Model then enumerates devices and chains matching drivers + automatically. + +- They are as minimal as possible, while remaining correct (refer to source + code comments for details). For example, VirtioBlkDxe and VirtioScsiDxe both + support only one request in flight. + + In theory, VirtioBlkDxe could implement EFI_BLOCK_IO2_PROTOCOL, which allows + queueing. Similarly, VirtioScsiDxe does not support the non-blocking mode of + EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru(). (Which is permitted by the UEFI + specification.) Both VirtioBlkDxe and VirtioScsiDxe delegate synchronous + request handling to "OvmfPkg/Library/VirtioLib". This limitation helps keep + the implementation simple, and testing thus far seems to imply satisfactory + performance, for a virtual boot firmware. + + VirtioNetDxe cannot avoid queueing, because EFI_SIMPLE_NETWORK_PROTOCOL + requires it on the interface level. Consequently, VirtioNetDxe is + significantly more complex than VirtioBlkDxe and VirtioScsiDxe. Technical + notes are provided in "OvmfPkg/VirtioNetDxe/TechNotes.txt". + +- None of these drivers access hardware directly. Instead, the Virtio Device + Protocol (OvmfPkg/Include/Protocol/VirtioDevice.h) collects / extracts virtio + operations defined in the Virtio Specification, and these backend-independent + virtio device drivers go through the abstract VIRTIO_DEVICE_PROTOCOL. + + IMPORTANT: the VIRTIO_DEVICE_PROTOCOL is not a standard UEFI protocol. It is + internal to edk2 and not described in the UEFI specification. It should only + be used by drivers and applications that live inside the edk2 source tree. + +Currently two providers exist for VIRTIO_DEVICE_PROTOCOL: + +- The first one is the "more traditional" virtio-pci backend, implemented by + OvmfPkg/VirtioPciDeviceDxe. This driver also complies with the UEFI Driver + Model. It consumes an instance of the EFI_PCI_IO_PROTOCOL, and, if the PCI + device/function under probing appears to be a virtio device, it produces a + Virtio Device Protocol instance for it. The driver translates abstract virtio + operations to PCI accesses. + +- The second provider, the virtio-mmio backend, is a library, not a driver, + living in OvmfPkg/Library/VirtioMmioDeviceLib. This library translates + abstract virtio operations to MMIO accesses. + + The virtio-mmio backend is only a library -- rather than a standalone, UEFI + Driver Model-compliant driver -- because the type of resource it consumes, an + MMIO register block base address, is not enumerable. + + In other words, while the PCI root bridge driver and the PCI bus driver + produce instances of EFI_PCI_IO_PROTOCOL automatically, thereby enabling the + UEFI Driver Model to probe devices and stack up drivers automatically, no + such enumeration exists for MMIO register blocks. + + For this reason, VirtioMmioDeviceLib needs to be linked into thin, custom + platform drivers that dispose over this kind of information. As soon as a + driver knows about the MMIO register block base addresses, it can pass each + to the library, and then the VIRTIO_DEVICE_PROTOCOL will be instantiated + (assuming a valid virtio-mmio register block of course). From that point on + the UEFI Driver Model again takes care of the chaining. + + Typically, such a custom driver does not conform to the UEFI Driver Model + (because that would presuppose auto-enumeration for MMIO register blocks). + Hence it has the following responsibilities: + + - it shall behave as a "wrapper" UEFI driver around the library, + + - it shall know virtio-mmio base addresses, + + - in its entry point function, it shall create a new UEFI handle with an + instance of the EFI_DEVICE_PATH_PROTOCOL for each virtio-mmio device it + knows the base address for, + + - it shall call VirtioMmioInstallDevice() on those handles, with the + corresponding base addresses. + + OVMF itself does not employ VirtioMmioDeviceLib. However, the library is used + (or has been tested as Proof-of-Concept) in the following 64-bit and 32-bit + ARM emulator setups: + + - in "RTSM_VE_FOUNDATIONV8_EFI.fd" and "FVP_AARCH64_EFI.fd", on ARM Holdings' + ARM(R) v8-A Foundation Model and ARM(R) AEMv8-A Base Platform FVP + emulators, respectively: + + EFI_BLOCK_IO_PROTOCOL + [OvmfPkg/VirtioBlkDxe] + | + VIRTIO_DEVICE_PROTOCOL + [ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf] + | + [OvmfPkg/Library/VirtioMmioDeviceLib] + direct MMIO register access + + - in "RTSM_VE_CORTEX-A15_EFI.fd" and "RTSM_VE_CORTEX-A15_MPCORE_EFI.fd", on + "qemu-system-arm -M vexpress-a15": + + EFI_BLOCK_IO_PROTOCOL EFI_SIMPLE_NETWORK_PROTOCOL + [OvmfPkg/VirtioBlkDxe] [OvmfPkg/VirtioNetDxe] + | | + +------------------+---------------+ + | + VIRTIO_DEVICE_PROTOCOL + [ArmPlatformPkg/ArmVExpressPkg/ArmVExpressDxe/ArmFvpDxe.inf] + | + [OvmfPkg/Library/VirtioMmioDeviceLib] + direct MMIO register access + + In the above ARM / VirtioMmioDeviceLib configurations, VirtioBlkDxe was + tested with booting Linux distributions, while VirtioNetDxe was tested with + pinging public IPv4 addresses from the UEFI shell. + +Platform Driver +............... + +Sometimes, elements of persistent firmware configuration are best exposed to +the user in a friendly way. OVMF's platform driver (OvmfPkg/PlatformDxe) +presents such settings on the "OVMF Platform Configuration" dialog: + +- Press ESC on the TianoCore splash screen, +- Navigate to Device Manager | OVMF Platform Configuration. + +At the moment, OVMF's platform driver handles only one setting: the preferred +graphics resolution. This is useful for two purposes: + +- Some UEFI shell commands, like DRIVERS and DEVICES, benefit from a wide + display. Using the MODE shell command, the user can switch to a larger text + resolution (limited by the graphics resolution), and see the command output + in a more easily consumable way. + + [RHEL] The list of text modes available to the MODE command is also limited + by ConSplitterDxe (found under MdeModulePkg/Universal/Console). + ConSplitterDxe builds an intersection of text modes that are + simultaneously supported by all consoles that ConSplitterDxe + multiplexes console output to. + + In practice, the strongest text mode restriction comes from + TerminalDxe, which provides console I/O on serial ports. TerminalDxe + has a very limited built-in list of text modes, heavily pruning the + intersection built by ConSplitterDxe, and made available to the MODE + command. + + On the Red Hat Enterprise Linux 7.1 host, TerminalDxe's list of modes + has been extended with text resolutions that match the Spice QXL GPU's + common graphics resolutions. This way a "full screen" text mode should + always be available in the MODE command. + +- The other advantage of controlling the graphics resolution lies with UEFI + operating systems that don't (yet) have a native driver for QEMU's virtual + video cards -- eg. the Spice QXL GPU. Such OSes may choose to inherit the + properties of OVMF's EFI_GRAPHICS_OUTPUT_PROTOCOL (provided by + OvmfPkg/QemuVideoDxe, see later). + + Although the display can be used at runtime in such cases, by direct + framebuffer access, its properties, for example, the resolution, cannot be + modified. The platform driver allows the user to select the preferred GOP + resolution, reboot, and let the guest OS inherit that preferred resolution. + +The platform driver has three access points: the "normal" driver entry point, a +set of HII callbacks, and a GOP installation callback. + +(1) Driver entry point: the PlatformInit() function. + + (a) First, this function loads any available settings, and makes them take + effect. For the preferred graphics resolution in particular, this means + setting the following PCDs: + + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution + + These PCDs influence the GraphicsConsoleDxe driver (located under + MdeModulePkg/Universal/Console), which switches to the preferred + graphics mode, and produces EFI_SIMPLE_TEXT_OUTPUT_PROTOCOLs on GOPs: + + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + [MdeModulePkg/Universal/Console/GraphicsConsoleDxe] + | + EFI_GRAPHICS_OUTPUT_PROTOCOL + [OvmfPkg/QemuVideoDxe] + | + EFI_PCI_IO_PROTOCOL + [MdeModulePkg/Bus/Pci/PciBusDxe] + + (b) Second, the driver entry point registers the user interface, including + HII callbacks. + + (c) Third, the driver entry point registers a GOP installation callback. + +(2) HII callbacks and the user interface. + + The Human Interface Infrastructure (HII) "is a set of protocols that allow + a UEFI driver to provide the ability to register user interface and + configuration content with the platform firmware". + + OVMF's platform driver: + + - provides a static, basic, visual form (PlatformForms.vfr), written in the + Visual Forms Representation language, + + - includes a UCS-16 encoded message catalog (Platform.uni), + + - includes source code that dynamically populates parts of the form, with + the help of MdeModulePkg/Library/UefiHiiLib -- this library simplifies + the handling of IFR (Internal Forms Representation) opcodes, + + - processes form actions that the user takes (Callback() function), + + - loads and saves platform configuration in a private, non-volatile + variable (ExtractConfig() and RouteConfig() functions). + + The ExtractConfig() HII callback implements the following stack of + conversions, for loading configuration and presenting it to the user: + + MultiConfigAltResp -- form engine / HII communication + ^ + | + [BlockToConfig] + | + MAIN_FORM_STATE -- binary representation of form/widget + ^ state + | + [PlatformConfigToFormState] + | + PLATFORM_CONFIG -- accessible to DXE and UEFI drivers + ^ + | + [PlatformConfigLoad] + | + UEFI non-volatile variable -- accessible to external utilities + + The layers are very similar for the reverse direction, ie. when taking + input from the user, and saving the configuration (RouteConfig() HII + callback): + + ConfigResp -- form engine / HII communication + | + [ConfigToBlock] + | + v + MAIN_FORM_STATE -- binary representation of form/widget + | state + [FormStateToPlatformConfig] + | + v + PLATFORM_CONFIG -- accessible to DXE and UEFI drivers + | + [PlatformConfigSave] + | + v + UEFI non-volatile variable -- accessible to external utilities + +(3) When the platform driver starts, a GOP may not be available yet. Thus the + driver entry point registers a callback (the GopInstalled() function) for + GOP installations. + + When the first GOP is produced (usually by QemuVideoDxe, or potentially by + a third party video driver), PlatformDxe retrieves the list of graphics + modes the GOP supports, and dynamically populates the drop-down list of + available resolutions on the form. The GOP installation callback is then + removed. + +Video driver +............ + +OvmfPkg/QemuVideoDxe is OVMF's built-in video driver. We can divide its +services in two parts: graphics output protocol (primary), and Int10h (VBE) +shim (secondary). + +(1) QemuVideoDxe conforms to the UEFI Driver Model; it produces an instance of + the EFI_GRAPHICS_OUTPUT_PROTOCOL (GOP) on each PCI display that it supports + and is connected to: + + EFI_GRAPHICS_OUTPUT_PROTOCOL + [OvmfPkg/QemuVideoDxe] + | + EFI_PCI_IO_PROTOCOL + [MdeModulePkg/Bus/Pci/PciBusDxe] + + It supports the following QEMU video cards: + + - Cirrus 5430 ("-device cirrus-vga"), + - Standard VGA ("-device VGA"), + - QXL VGA ("-device qxl-vga", "-device qxl"). + + For Cirrus the following resolutions and color depths are available: + 640x480x32, 800x600x32, 1024x768x24. On stdvga and QXL a long list of + resolutions is available. The list is filtered against the frame buffer + size during initialization. + + The size of the QXL VGA compatibility framebuffer can be changed with the + + -device qxl-vga,vgamem_mb=$NUM_MB + + QEMU option. If $NUM_MB exceeds 32, then the following is necessary + instead: + + -device qxl-vga,vgamem_mb=$NUM_MB,ram_size_mb=$((NUM_MB*2)) + + because the compatibility framebuffer can't cover more than half of PCI BAR + #0. The latter defaults to 64MB in size, and is controlled by the + "ram_size_mb" property. + +(2) When QemuVideoDxe binds the first Standard VGA or QXL VGA device, and there + is no real VGA BIOS present in the C to F segments (which could originate + from a legacy PCI option ROM -- refer to "Compatibility Support Module + (CSM)"), then QemuVideoDxe installs a minimal, "fake" VGA BIOS -- an Int10h + (VBE) "shim". + + The shim is implemented in 16-bit assembly in + "OvmfPkg/QemuVideoDxe/VbeShim.asm". The "VbeShim.sh" shell script assembles + it and formats it as a C array ("VbeShim.h") with the help of the "nasm" + utility. The driver's InstallVbeShim() function copies the shim in place + (the C segment), and fills in the VBE Info and VBE Mode Info structures. + The real-mode 10h interrupt vector is pointed to the shim's handler. + + The shim is (correctly) irrelevant and invisible for all UEFI operating + systems we know about -- except Windows Server 2008 R2 and other Windows + operating systems in that family. + + Namely, the Windows 2008 R2 SP1 (and Windows 7) UEFI guest's default video + driver dereferences the real mode Int10h vector, loads the pointed-to + handler code, and executes what it thinks to be VGA BIOS services in an + internal real-mode emulator. Consequently, video mode switching used not to + work in Windows 2008 R2 SP1 when it ran on the "pure UEFI" build of OVMF, + making the guest uninstallable. Hence the (otherwise optional, non-default) + Compatibility Support Module (CSM) ended up a requirement for running such + guests. + + The hard dependency on the sophisticated SeaBIOS CSM and the complex + supporting edk2 infrastructure, for enabling this family of guests, was + considered suboptimal by some members of the upstream community, + + [RHEL] and was certainly considered a serious maintenance disadvantage for + Red Hat Enterprise Linux 7.1 hosts. + + Thus, the shim has been collaboratively developed for the Windows 7 / + Windows Server 2008 R2 family. The shim provides a real stdvga / QXL + implementation for the few services that are in fact necessary for the + Windows 2008 R2 SP1 (and Windows 7) UEFI guest, plus some "fakes" that the + guest invokes but whose effect is not important. The only supported mode is + 1024x768x32, which is enough to install the guest and then upgrade its + video driver to the full-featured QXL XDDM one. + + The C segment is not present in the UEFI memory map prepared by OVMF. + Memory space that would cover it is never added (either in PEI, in the form + of memory resource descriptor HOBs, or in DXE, via gDS->AddMemorySpace()). + This way the handler body is invisible to all other UEFI guests, and the + rest of edk2. + + The Int10h real-mode IVT entry is covered with a Boot Services Code page, + making that too inaccessible to the rest of edk2. Due to the allocation + type, UEFI guest OSes different from the Windows Server 2008 family can + reclaim the page at zero. (The Windows 2008 family accesses that page + regardless of the allocation type.) + +Afterword +--------- + +After the bulk of this document was written in July 2014, OVMF development has +not stopped. To name two significant code contributions from the community: in +January 2015, OVMF runs on the "q35" machine type of QEMU, and it features a +driver for Xen paravirtual block devices (and another for the underlying Xen +bus). + +Furthermore, a dedicated virtualization platform has been contributed to +ArmPlatformPkg that plays a role parallel to OvmfPkg's. It targets the "virt" +machine type of qemu-system-arm and qemu-system-aarch64. Parts of OvmfPkg are +being refactored and modularized so they can be reused in +"ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc". diff --git a/sources b/sources index 03dfd2b..993de36 100644 --- a/sources +++ b/sources @@ -1,2 +1,3 @@ -SHA512 (openssl-1.0.2j-hobbled.tar.xz) = 87c7c4e45f83c49b36154f4c66d3799fdc63286f9841b4dd71d4bdc3b26206be6009e33462533f0c1cc0efd9ef6aa05b772728ed0ee3e88f952586cdcf513003 -SHA512 (edk2-20170209-296153c5.tar.xz) = b9b1936bde197712fe0f5dc3cf227095c08803486866967703959f4adc131c48b1b5f3bcdd8a4a40fe234eba5a7fdf887087d4d522db01a0920eb85cc7ab9454 +SHA512 (qemu-ovmf-secureboot-1.1.3.tar.gz) = f830a525f66379e8e3c61d006fab49547e6709f7aa0f95e70f23c7d26407cc804a0ced9dcfd26af63391d603e9cb5a0714c222c7cdca8599e41852e22e13be80 +SHA512 (openssl-1.1.0h-hobbled.tar.xz) = 6b544a5560a0a3d59b368e3f216284e79389112c87bb34289f8f6644a2454407161a1755b292e8045ff7c172237b070973b03610fd1da3d5204f4118a8644724 +SHA512 (edk2-20180815-cb5f4f45ce.tar.xz) = 2912bb30b5be1d7efc1b7aa6d337fd1403fc9ea7cfc580c22dd770d82273ce4c801eba2d60a6f2fda4bc1c6e49747be606de4acfdcca286c10e44b11369cde9d diff --git a/update-tarball.sh b/update-tarball.sh index b61d758..e414329 100644 --- a/update-tarball.sh +++ b/update-tarball.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash
user="tianocore" repo="edk2" @@ -8,21 +8,30 @@ uri="https://github.com/$%7Buser%7D/$%7Brepo%7D" api="${uri/github.com/api.github.com/repos}" tar="${uri/github.com/codeload.github.com}/legacy.tar.gz"
-hash=$(curl -s "${api}/git/refs/heads/${branch}" | grep '"sha"' | cut -d'"' -f4) -if test "$hash" = ""; then +if test $# -ge 1; then + hash=$1 + short=$1 +else + hash=$(curl -s "${api}/git/refs/heads/${branch}" | grep '"sha"' | cut -d'"' -f4) + if test "$hash" = ""; then echo "# failed to fetch $branch hash" exit 1 + fi + short=$(echo $hash | sed -e 's/^(.......).*/\1/') fi -short=$(echo $hash | sed -e 's/^(.......).*/\1/')
-date=$(curl -s "${api}/git/commits/$hash" | awk ' - /"committer"/ { c=1 } - /"date"/ { if (c) { print } } -' | cut -d'"' -f4) -date="${date%T*}" -date="${date//-/}" +if test $# = 2; then + date=$2 +else + date=$(curl -s "${api}/git/commits/$hash" | awk ' + /"committer"/ { c=1 } + /"date"/ { if (c) { print } } + ' | cut -d'"' -f4) + date="${date%T*}" + date="${date//-/}" +fi
-name="${repo}-${date}-${short}.tar.gz" +name="${repo}-${date}-${short}.tar.xz"
if test -f "$name"; then echo "# exists: $name" @@ -41,5 +50,5 @@ echo echo "# cleanup ..." rm -vf ${repo}-*.tar* echo "# fetching $name ..." -curl "$tar/$hash" > "$name" +curl "$tar/$hash" | zcat | xz -9e > "$name" exit 0
arch-excludes@lists.fedoraproject.org