1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 * Copyright © 2017 Max Resch <resch.max@gmail.com>
6 * Security Policy Handling
7 * Copyright © 2012 <James.Bottomley@HansenPartnership.com>
8 * https://github.com/mjg59/efitools
11 #include "device-path-util.h"
12 #include "secure-boot.h"
16 #if defined(__x86_64__) || defined(__i386__)
17 #define __sysv_abi__ __attribute__((sysv_abi))
23 EFI_STATUS
__sysv_abi__ (*shim_verify
) (const void *buffer
, uint32_t size
);
25 /* context is actually a struct for the PE header, but it isn't needed so void is sufficient just do define the interface
26 * see shim.c/shim.h and PeHeader.h in the github shim repo */
27 EFI_STATUS
__sysv_abi__ (*generate_hash
) (void *data
, uint32_t datasize
, void *context
, uint8_t *sha256hash
, uint8_t *sha1hash
);
29 EFI_STATUS
__sysv_abi__ (*read_header
) (void *data
, uint32_t datasize
, void *context
);
32 #define SHIM_LOCK_GUID \
33 { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }
35 bool shim_loaded(void) {
36 struct ShimLock
*shim_lock
;
38 return BS
->LocateProtocol(MAKE_GUID_PTR(SHIM_LOCK
), NULL
, (void **) &shim_lock
) == EFI_SUCCESS
;
41 static bool shim_validate(
42 const void *ctx
, const EFI_DEVICE_PATH
*device_path
, const void *file_buffer
, size_t file_size
) {
45 _cleanup_free_
char *file_buffer_owned
= NULL
;
51 EFI_HANDLE device_handle
;
52 EFI_DEVICE_PATH
*file_dp
= (EFI_DEVICE_PATH
*) device_path
;
53 err
= BS
->LocateDevicePath(
54 MAKE_GUID_PTR(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
), &file_dp
, &device_handle
);
55 if (err
!= EFI_SUCCESS
)
58 _cleanup_(file_closep
) EFI_FILE
*root
= NULL
;
59 err
= open_volume(device_handle
, &root
);
60 if (err
!= EFI_SUCCESS
)
63 _cleanup_free_ char16_t
*dp_str
= NULL
;
64 err
= device_path_to_str(file_dp
, &dp_str
);
65 if (err
!= EFI_SUCCESS
)
68 err
= file_read(root
, dp_str
, 0, 0, &file_buffer_owned
, &file_size
);
69 if (err
!= EFI_SUCCESS
)
72 file_buffer
= file_buffer_owned
;
75 struct ShimLock
*shim_lock
;
76 err
= BS
->LocateProtocol(MAKE_GUID_PTR(SHIM_LOCK
), NULL
, (void **) &shim_lock
);
77 if (err
!= EFI_SUCCESS
)
80 return shim_lock
->shim_verify(file_buffer
, file_size
) == EFI_SUCCESS
;
83 EFI_STATUS
shim_load_image(EFI_HANDLE parent
, const EFI_DEVICE_PATH
*device_path
, EFI_HANDLE
*ret_image
) {
87 bool have_shim
= shim_loaded();
90 install_security_override(shim_validate
, NULL
);
92 EFI_STATUS ret
= BS
->LoadImage(
93 /*BootPolicy=*/false, parent
, (EFI_DEVICE_PATH
*) device_path
, NULL
, 0, ret_image
);
96 uninstall_security_override();
101 void shim_retain_protocol(void) {
104 /* Ask Shim to avoid uninstalling its security protocol, so that we can use it from sd-stub to
105 * validate PE addons. By default, Shim uninstalls its protocol when calling StartImage().
106 * Requires Shim 15.8. */
107 (void) efivar_set_raw(MAKE_GUID_PTR(SHIM_LOCK
), u
"ShimRetainProtocol", &value
, sizeof(value
), 0);