pub const TEE_SIMULATE_ENV: &str = "A3S_TEE_SIMULATE";
pub fn is_simulate_mode() -> bool {
std::env::var(TEE_SIMULATE_ENV)
.map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
.unwrap_or(false)
}
pub const SIMULATED_REPORT_VERSION: u32 = 0xA3;
pub const SIMULATED_CHIP_ID: [u8; 64] = [0xA3; 64];
pub fn build_simulated_report(report_data: &[u8; 64]) -> Vec<u8> {
const SNP_REPORT_SIZE: usize = 1184;
let mut report = vec![0u8; SNP_REPORT_SIZE];
report[0x00..0x04].copy_from_slice(&SIMULATED_REPORT_VERSION.to_le_bytes());
report[0x04..0x08].copy_from_slice(&1u32.to_le_bytes());
report[0x08..0x10].copy_from_slice(&0u64.to_le_bytes());
report[0x38] = 3; report[0x39] = 0; report[0x3E] = 8; report[0x3F] = 115;
report[0x50..0x90].copy_from_slice(report_data);
for i in 0..48 {
report[0x90 + i] = (i as u8).wrapping_mul(0xA3);
}
report[0x1A0..0x1E0].copy_from_slice(&SIMULATED_CHIP_ID);
report
}
pub fn is_simulated_report(report: &[u8]) -> bool {
if report.len() < 4 {
return false;
}
let version = u32::from_le_bytes(report[0x00..0x04].try_into().unwrap_or([0; 4]));
version == SIMULATED_REPORT_VERSION
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_simulate_mode_default() {
let _ = is_simulate_mode();
}
#[test]
fn test_build_simulated_report_size() {
let data = [0u8; 64];
let report = build_simulated_report(&data);
assert_eq!(report.len(), 1184);
}
#[test]
fn test_build_simulated_report_version() {
let data = [0u8; 64];
let report = build_simulated_report(&data);
let version = u32::from_le_bytes(report[0x00..0x04].try_into().unwrap());
assert_eq!(version, SIMULATED_REPORT_VERSION);
}
#[test]
fn test_build_simulated_report_contains_nonce() {
let mut data = [0u8; 64];
data[0] = 0xDE;
data[1] = 0xAD;
data[2] = 0xBE;
data[3] = 0xEF;
let report = build_simulated_report(&data);
assert_eq!(report[0x50], 0xDE);
assert_eq!(report[0x51], 0xAD);
assert_eq!(report[0x52], 0xBE);
assert_eq!(report[0x53], 0xEF);
}
#[test]
fn test_build_simulated_report_tcb() {
let data = [0u8; 64];
let report = build_simulated_report(&data);
assert_eq!(report[0x38], 3); assert_eq!(report[0x3E], 8); assert_eq!(report[0x3F], 115); }
#[test]
fn test_build_simulated_report_chip_id() {
let data = [0u8; 64];
let report = build_simulated_report(&data);
assert_eq!(&report[0x1A0..0x1E0], &SIMULATED_CHIP_ID);
}
#[test]
fn test_build_simulated_report_zero_signature() {
let data = [0u8; 64];
let report = build_simulated_report(&data);
assert!(report[0x2A0..].iter().all(|&b| b == 0));
}
#[test]
fn test_is_simulated_report_true() {
let data = [0u8; 64];
let report = build_simulated_report(&data);
assert!(is_simulated_report(&report));
}
#[test]
fn test_is_simulated_report_false() {
let mut report = vec![0u8; 1184];
report[0x00..0x04].copy_from_slice(&2u32.to_le_bytes()); assert!(!is_simulated_report(&report));
}
#[test]
fn test_is_simulated_report_too_short() {
assert!(!is_simulated_report(&[0u8; 2]));
}
#[test]
fn test_simulated_report_version_constant() {
assert_eq!(SIMULATED_REPORT_VERSION, 0xA3);
}
}