|
| 1 | +//! Shim lock protocol. |
| 2 | +
|
| 3 | +use crate::proto::Protocol; |
| 4 | +use crate::result::Error; |
| 5 | +use crate::{unsafe_guid, Result, Status}; |
| 6 | +use core::convert::TryInto; |
| 7 | + |
| 8 | +/// The Shim lock protocol. |
| 9 | +/// |
| 10 | +/// This protocol is not part of the UEFI specification, but is |
| 11 | +/// installed by the [Shim bootloader](https://github.com/rhboot/shim) |
| 12 | +/// which is commonly used by Linux distributions to support UEFI |
| 13 | +/// Secure Boot. Shim is built with an embedded certificate that is |
| 14 | +/// used to validate another EFI application before running it. That |
| 15 | +/// application may itself be a bootloader that needs to validate |
| 16 | +/// another EFI application before running it, and the shim lock |
| 17 | +/// protocol exists to support that. |
| 18 | +#[repr(C)] |
| 19 | +#[unsafe_guid("605dab50-e046-4300-abb6-3dd810dd8b23")] |
| 20 | +#[derive(Protocol)] |
| 21 | +pub struct ShimLock { |
| 22 | + verify: extern "efiapi" fn(buffer: *const u8, size: u32) -> Status, |
| 23 | +} |
| 24 | + |
| 25 | +impl ShimLock { |
| 26 | + /// Verify that an EFI application is signed by the certificate |
| 27 | + /// embedded in shim. |
| 28 | + /// |
| 29 | + /// The buffer's size must fit in a `u32`; if that condition is not |
| 30 | + /// met then a `BAD_BUFFER_SIZE` error will be returned and the shim |
| 31 | + /// lock protocol will not be called. |
| 32 | + pub fn verify(&self, buffer: &[u8]) -> Result { |
| 33 | + let size: u32 = buffer |
| 34 | + .len() |
| 35 | + .try_into() |
| 36 | + .map_err(|_| Error::from(Status::BAD_BUFFER_SIZE))?; |
| 37 | + (self.verify)(buffer.as_ptr(), size).into() |
| 38 | + } |
| 39 | +} |
0 commit comments