use crate::LOG_DBG;
#[cfg(feature = "tlcl")]
use crate::tlcl::{TlclRead, TlclGetTPMVersion};
#[cfg(feature = "tlcl")]
const KERNEL_ROLLBACK_NV_INDEX: u32 = 0x1008;
#[cfg(feature = "tlcl")]
const FIRMWARE_ROLLBACK_NV_INDEX: u32 = 0x1007;
#[cfg(feature = "tlcl")]
macro_rules! tpm_nv_read {
($nv_index:expr, $size:expr, $parse_fn:expr) => {{
let mut outbuf: [u8; $size] = unsafe { core::mem::zeroed() };
let rc = TlclRead(
$nv_index,
outbuf.as_mut_ptr() as *mut core::ffi::c_void,
$size as u32,
);
if rc != crate::tlcl::constants::TPM_SUCCESS {
if rc == crate::tlcl::constants::TPM_E_BADINDEX {
LOG_DBG!("NV index 0x{:x} doesn't exist!", $nv_index);
} else {
LOG_DBG!(
"TlclRead(0x{:x}, outbuf, 0x{:x}) failed with code: 0x{:x}",
$nv_index,
$size,
rc
);
}
return u32::MAX;
}
if outbuf.len() < $size {
LOG_DBG!(
"TlclRead(0x{:x}, outbuf, 0x{:x}) returned too few bytes (expected 0x{:x}, got 0x{:x})",
$nv_index,
$size,
$size,
outbuf.len()
);
return u32::MAX;
}
let result = $parse_fn(&outbuf);
LOG_DBG!(
"TlclRead(0x{:x}, outbuf, 0x{:x}) returned rc 0x{:x} with data 0x{:x}",
$nv_index,
$size,
rc,
result
);
result
}};
}
#[cfg(feature = "tlcl")]
pub fn get_kernel_rollback_version() -> u32 {
tpm_nv_read!(KERNEL_ROLLBACK_NV_INDEX, 0x9, |buf: &[u8]| {
match buf[0] {
0x02 => u32::from_le_bytes(buf[0x5..0x9].try_into().unwrap()),
0x10 => u32::from_le_bytes(buf[0x4..0x8].try_into().unwrap()),
_ => u32::MAX,
}
})
}
#[cfg(feature = "tlcl")]
pub fn get_firmware_rollback_version() -> u32 {
tpm_nv_read!(FIRMWARE_ROLLBACK_NV_INDEX, 0x6, |buf: &[u8]| {
u32::from_le_bytes(buf[0x2..0x6].try_into().unwrap())
})
}
#[cfg(feature = "tlcl")]
pub fn get_tpm_version() -> String {
TlclGetTPMVersion()
}
#[cfg(not(feature = "tlcl"))]
pub fn get_kernel_rollback_version() -> u32 {
LOG_DBG!("tlcl feature not enabled");
u32::MAX
}
#[cfg(not(feature = "tlcl"))]
pub fn get_firmware_rollback_version() -> u32 {
LOG_DBG!("tlcl feature not enabled");
u32::MAX
}
#[cfg(not(feature = "tlcl"))]
pub fn get_tpm_version() -> String {
LOG_DBG!("tlcl feature not enabled");
"Tlcl was not enabled when compiling libcros.".to_string()
}