- fix the signature length passed to Authenticode (bsc#991885) OBS-URL: https://build.opensuse.org/request/show/417039 OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=117
66 lines
2.7 KiB
Diff
66 lines
2.7 KiB
Diff
From 6c12c7bf522d032922abb799cdf0d6f525de3c38 Mon Sep 17 00:00:00 2001
|
|
From: Sachin Agrawal <sachin.agrawal@intel.com>
|
|
Date: Tue, 2 Aug 2016 16:46:31 -0700
|
|
Subject: [PATCH] Use authenticode signature length from WIN_CERTIFICATE
|
|
structure.
|
|
|
|
Authenticode Certificate length is available in Certificate Table
|
|
(inside PE header) and also in signature header(WIN_CERTIFICATE) itself.
|
|
Code in 'check_backlist()' method uses length from signature header,
|
|
whereas, AuthenticodeVerify() call inside 'verify_buffer()' method uses
|
|
the length in signature header. This causes a security vulnerability issue :
|
|
|
|
Good Scenario : Assume shim1.crt is used for signing grub.efi and
|
|
shim1.crt is embedded inside shim.efi. Also, assume shim1.crt got
|
|
compromised and therefore it was added in 'dbx' database. Now, when
|
|
shim.efi will attempt to load grub.efi, it will fail loading with
|
|
log message "Binary is blacklisted" because 'check_blacklist' call
|
|
will detect the presence of 'shim1.crt' in 'dbx'.
|
|
|
|
Vulnerable Scenario : Similar as above. Add 'shim1.crt' in dbx database.
|
|
Also, tamper the earlier signed grub.efi file by placing 0x0000 in the
|
|
WIN_CERTIFICATE.dwLength.
|
|
(Open grub.efi/vmlinuz signed binary with hex editor.
|
|
Go to 0x128 address and read out the address from 0x128 until
|
|
0x12B in little Indian order from right to left.
|
|
Jump to the address from 0x128 address area.
|
|
First 8bytes are the signature header area which consist of
|
|
signature size(4bytes), revision(2bytes) and type(2bytes).
|
|
So tamper the first 4 bytes for signature size and save the binary.
|
|
)
|
|
With this tampered grub.efi, shim.efi loads it successfully because
|
|
'check_blacklist()' call fails to detect the presence of shim1.crt in 'dbx'
|
|
database.
|
|
|
|
|
|
Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
|
|
---
|
|
shim.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/shim.c b/shim.c
|
|
index ed01899..03a5604 100644
|
|
--- a/shim.c
|
|
+++ b/shim.c
|
|
@@ -966,7 +966,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|
*/
|
|
if (sizeof(shim_cert) &&
|
|
AuthenticodeVerify(cert->CertData,
|
|
- context->SecDir->Size - sizeof(cert->Hdr),
|
|
+ cert->Hdr.dwLength - sizeof(cert->Hdr),
|
|
shim_cert, sizeof(shim_cert), sha256hash,
|
|
SHA256_DIGEST_SIZE)) {
|
|
status = EFI_SUCCESS;
|
|
@@ -977,7 +977,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|
* And finally, check against shim's built-in key
|
|
*/
|
|
if (vendor_cert_size && AuthenticodeVerify(cert->CertData,
|
|
- context->SecDir->Size - sizeof(cert->Hdr),
|
|
+ cert->Hdr.dwLength - sizeof(cert->Hdr),
|
|
vendor_cert, vendor_cert_size, sha256hash,
|
|
SHA256_DIGEST_SIZE)) {
|
|
status = EFI_SUCCESS;
|
|
--
|
|
2.9.2
|
|
|