use mbedtls::{
Result,
hash::{Hmac, Md, Type},
};
use std::time::{SystemTime, UNIX_EPOCH};
const KYLINOS: &str = "www.kylinos.cn";
const PKG: &str = "rust-libteec"; const TEEC: &str = "libcc_teec";
const TIME_WINDOW_SIZE: u64 = 300;
pub(crate) fn generate_psk() -> Result<[u8; 32]> {
let time_window = get_time_window();
let mut base_key: [u8; 32] = Default::default();
let mut ctx = Md::new(Type::SM3)?;
ctx.update(KYLINOS.as_bytes())?;
ctx.update(PKG.as_bytes())?;
ctx.update(TEEC.as_bytes())?;
ctx.finish(&mut base_key)?;
let mut psk: [u8; 32] = Default::default();
Hmac::hmac(Type::SM3, &base_key, &time_window.to_be_bytes(), &mut psk)?;
Ok(psk)
}
fn get_time_window() -> u64 {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
now / TIME_WINDOW_SIZE
}
pub(crate) const fn get_psk_identity() -> &'static str {
PKG
}
#[cfg(test)]
mod psk_tests {
use super::*;
#[test]
fn test_psk_generation_success() {
generate_psk().expect("生成PSK应该成功");
}
#[test]
fn test_psk_length() {
let psk = generate_psk().expect("生成 PSK 应该成功");
assert_eq!(psk.len(), 32, "PSK 长度应该为 32 字节");
}
#[test]
fn test_psk_not_all_zero() {
let psk = generate_psk().expect("生成 PSK 应该成功");
assert!(psk.iter().any(|&b| b != 0), "PSK 不应该全为零");
}
#[test]
fn test_psk_identity_not_empty() {
let identity = get_psk_identity();
assert!(!identity.is_empty());
}
#[test]
fn test_psk_changes_with_time() {
let psk1 = generate_psk().expect("第一次生成 PSK 应该成功");
let _window1 = get_time_window();
let psk2 = generate_psk().expect("第二次生成 PSK 应该成功");
assert_eq!(psk1, psk2, "同一时间窗口内 PSK 应该相同");
}
#[test]
fn test_time_window_calculation() {
let window = get_time_window();
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
let expected = now / TIME_WINDOW_SIZE;
assert_eq!(window, expected, "时间窗口计算应该正确");
}
#[test]
fn test_hmac_sm3_deterministic() {
let key = [0x42u8; 32];
let message = b"test message";
let mut output1 = [0u8; 32];
let mut output2 = [0u8; 32];
Hmac::hmac(Type::SM3, &key, message, &mut output1).expect("HMAC-SM3 应该成功");
Hmac::hmac(Type::SM3, &key, message, &mut output2).expect("HMAC-SM3 应该成功");
assert_eq!(output1, output2, "相同输入应该产生相同输出");
}
#[test]
fn test_hmac_sm3_different_inputs() {
let key = [0x42u8; 32];
let msg1 = b"message 1";
let msg2 = b"message 2";
let mut output1 = [0u8; 32];
let mut output2 = [0u8; 32];
Hmac::hmac(Type::SM3, &key, msg1, &mut output1).expect("HMAC-SM3 应该成功");
Hmac::hmac(Type::SM3, &key, msg2, &mut output2).expect("HMAC-SM3 应该成功");
assert_ne!(output1, output2, "不同输入应该产生不同输出");
}
}