use alloc::vec::Vec;
use uefi::{Error, Status};
use virtfw_libefi::efivar::types::{EfiVar, EfiVarAttr};
use virtfw_libefi::guids;
use crate::store::EfiVarStore;
impl EfiVarStore {
fn set_setup_mode(&mut self, enabled: bool) {
self.set_unchecked_bool(
&guids::EfiGlobalVariable,
"SetupMode",
EfiVarAttr::new_bs_rt(),
enabled,
);
}
fn set_secure_boot(&mut self, enabled: bool) {
self.set_unchecked_bool(
&guids::EfiGlobalVariable,
"SecureBoot",
EfiVarAttr::new_bs_rt(),
enabled,
);
}
fn set_custom_mode(&mut self, enabled: bool) {
self.set_unchecked_bool(
&guids::EfiCustomModeEnable,
"CustomMode",
EfiVarAttr::new_nv_bs(),
enabled,
);
}
fn set_signature_support(&mut self) {
let mut sigs = Vec::new();
sigs.extend_from_slice(&guids::EfiCertSha256.to_bytes());
sigs.extend_from_slice(&guids::EfiCertSha384.to_bytes());
sigs.extend_from_slice(&guids::EfiCertSha512.to_bytes());
sigs.extend_from_slice(&guids::EfiCertRsa2048.to_bytes());
sigs.extend_from_slice(&guids::EfiCertX509.to_bytes());
let var = EfiVar {
guid: guids::EfiGlobalVariable,
name: "SignatureSupport".into(),
attr: EfiVarAttr::new_bs_rt(),
data: sigs,
};
self.set_unchecked(var);
}
fn set_vendor_keys(&mut self) {
self.set_unchecked_bool(
&guids::EfiGlobalVariable,
"VendorKeysNv",
EfiVarAttr::new_nv_bs().with_time_auth_wr_access(true),
false,
);
self.set_unchecked_bool(
&guids::EfiGlobalVariable,
"VendorKeys",
EfiVarAttr::new_bs_rt(),
false,
);
}
fn check_time_auth(&self, _variable: &EfiVar) -> Result<(), Error<&'static str>> {
Err(Error::new(Status::UNSUPPORTED, "time auth bit set"))
}
pub(crate) fn check_auth(&self, variable: &EfiVar) -> Result<(), Error<&'static str>> {
if variable.attr.auth_wr_access() {
return Err(Error::new(Status::UNSUPPORTED, "auth bit set"));
}
if variable.attr.time_auth_wr_access() {
return self.check_time_auth(variable);
}
Ok(())
}
pub(crate) fn auth_init(&mut self) {
let setup = self
.get_unchecked("PK", &guids::EfiGlobalVariable)
.is_none();
self.set_setup_mode(setup);
self.set_signature_support();
let sb = !setup;
self.set_secure_boot(sb);
self.set_custom_mode(false);
self.set_vendor_keys();
}
}