1use serde::{Deserialize, Serialize};
30use sha2::{Digest, Sha256};
31use std::time::{SystemTime, UNIX_EPOCH};
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct TeeCapability {
40 pub sgx_available: bool,
42 pub sgx_version: Option<u8>,
44 pub sev_available: bool,
46 pub trustzone_available: bool,
48 pub keystone_available: bool,
50 pub max_enclave_memory: usize,
52 pub remote_attestation: bool,
54}
55
56impl TeeCapability {
57 pub fn detect() -> Self {
59 TeeCapability {
62 sgx_available: Self::check_sgx(),
63 sgx_version: Self::get_sgx_version(),
64 sev_available: Self::check_sev(),
65 trustzone_available: Self::check_trustzone(),
66 keystone_available: Self::check_keystone(),
67 max_enclave_memory: Self::get_max_enclave_memory(),
68 remote_attestation: true,
69 }
70 }
71
72 pub fn any_available(&self) -> bool {
74 self.sgx_available
75 || self.sev_available
76 || self.trustzone_available
77 || self.keystone_available
78 }
79
80 pub fn best_available(&self) -> Option<TeeType> {
82 if self.sgx_available && self.sgx_version == Some(2) {
83 Some(TeeType::SgxV2)
84 } else if self.sgx_available {
85 Some(TeeType::SgxV1)
86 } else if self.sev_available {
87 Some(TeeType::AmdSev)
88 } else if self.trustzone_available {
89 Some(TeeType::ArmTrustZone)
90 } else if self.keystone_available {
91 Some(TeeType::RiscVKeystone)
92 } else {
93 None
94 }
95 }
96
97 #[cfg(target_arch = "x86_64")]
98 fn check_sgx() -> bool {
99 false }
102
103 #[cfg(not(target_arch = "x86_64"))]
104 fn check_sgx() -> bool {
105 false
106 }
107
108 fn get_sgx_version() -> Option<u8> {
109 None
111 }
112
113 fn check_sev() -> bool {
114 false
116 }
117
118 fn check_trustzone() -> bool {
119 cfg!(target_arch = "aarch64")
121 }
122
123 fn check_keystone() -> bool {
124 cfg!(target_arch = "riscv64")
126 }
127
128 fn get_max_enclave_memory() -> usize {
129 128 * 1024 * 1024
131 }
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
136pub enum TeeType {
137 SgxV1,
138 SgxV2,
139 AmdSev,
140 ArmTrustZone,
141 RiscVKeystone,
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct SgxEnclave {
151 pub enclave_id: [u8; 32],
153 pub mrenclave: [u8; 32],
155 pub mrsigner: [u8; 32],
157 pub isv_prod_id: u16,
159 pub isv_svn: u16,
161 pub attributes: EnclaveAttributes,
163 pub state: EnclaveState,
165 pub sealed_rules_hash: [u8; 32],
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct EnclaveAttributes {
172 pub debug: bool,
174 pub mode_64bit: bool,
176 pub provision_key: bool,
178 pub launch_key: bool,
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
184pub enum EnclaveState {
185 Uninitialized,
187 Ready,
189 Executing,
191 Sealed,
193 Destroyed,
195}
196
197impl SgxEnclave {
198 pub fn new(rules: &[String]) -> Self {
200 let enclave_id = Self::generate_enclave_id();
201 let mrenclave = Self::measure_enclave_code();
202 let mrsigner = Self::measure_signer();
203 let sealed_rules_hash = Self::hash_rules(rules);
204
205 SgxEnclave {
206 enclave_id,
207 mrenclave,
208 mrsigner,
209 isv_prod_id: 1, isv_svn: 15, attributes: EnclaveAttributes {
212 debug: false, mode_64bit: true,
214 provision_key: false,
215 launch_key: false,
216 },
217 state: EnclaveState::Uninitialized,
218 sealed_rules_hash,
219 }
220 }
221
222 pub fn initialize(&mut self) -> Result<(), TeeError> {
224 if self.state != EnclaveState::Uninitialized {
225 return Err(TeeError::InvalidState(
226 "Enclave already initialized".to_string(),
227 ));
228 }
229
230 self.state = EnclaveState::Ready;
232 Ok(())
233 }
234
235 pub fn enter(&mut self) -> Result<EnclaveContext, TeeError> {
237 if self.state != EnclaveState::Ready {
238 return Err(TeeError::InvalidState(
239 "Enclave not ready for execution".to_string(),
240 ));
241 }
242
243 self.state = EnclaveState::Executing;
244
245 Ok(EnclaveContext {
246 enclave_id: self.enclave_id,
247 entry_time: SystemTime::now()
248 .duration_since(UNIX_EPOCH)
249 .unwrap()
250 .as_secs(),
251 })
252 }
253
254 pub fn exit(&mut self) -> Result<(), TeeError> {
256 if self.state != EnclaveState::Executing {
257 return Err(TeeError::InvalidState("Enclave not executing".to_string()));
258 }
259
260 self.state = EnclaveState::Ready;
261 Ok(())
262 }
263
264 pub fn generate_attestation(&self, challenge: &[u8]) -> Result<EnclaveAttestation, TeeError> {
266 if self.state == EnclaveState::Destroyed {
267 return Err(TeeError::EnclaveDestroyed);
268 }
269
270 let report_data_arr = Self::create_report_data(challenge, &self.sealed_rules_hash);
271 let quote = Self::generate_quote(&report_data_arr, &self.mrenclave, &self.mrsigner);
272
273 Ok(EnclaveAttestation {
274 quote,
275 mrenclave: self.mrenclave,
276 mrsigner: self.mrsigner,
277 isv_prod_id: self.isv_prod_id,
278 isv_svn: self.isv_svn,
279 report_data: report_data_arr.to_vec(),
280 timestamp: SystemTime::now()
281 .duration_since(UNIX_EPOCH)
282 .unwrap()
283 .as_secs(),
284 })
285 }
286
287 pub fn destroy(&mut self) {
289 self.state = EnclaveState::Destroyed;
290 }
292
293 fn generate_enclave_id() -> [u8; 32] {
294 let mut hasher = Sha256::new();
295 hasher.update(b"HOPE_GENOME_ENCLAVE:");
296 hasher.update(
297 SystemTime::now()
298 .duration_since(UNIX_EPOCH)
299 .unwrap()
300 .as_nanos()
301 .to_le_bytes(),
302 );
303 hasher.finalize().into()
304 }
305
306 fn measure_enclave_code() -> [u8; 32] {
307 let mut hasher = Sha256::new();
308 hasher.update(b"MRENCLAVE_HOPE_GENOME_v15");
309 hasher.finalize().into()
311 }
312
313 fn measure_signer() -> [u8; 32] {
314 let mut hasher = Sha256::new();
315 hasher.update(b"MRSIGNER_HOPE_GENOME_MATE_ROBERT");
316 hasher.finalize().into()
317 }
318
319 fn hash_rules(rules: &[String]) -> [u8; 32] {
320 let mut hasher = Sha256::new();
321 hasher.update(b"SEALED_RULES:");
322 for rule in rules {
323 hasher.update(rule.as_bytes());
324 hasher.update(b"\n");
325 }
326 hasher.finalize().into()
327 }
328
329 fn create_report_data(challenge: &[u8], rules_hash: &[u8; 32]) -> [u8; 64] {
330 let mut hasher = Sha256::new();
331 hasher.update(b"REPORT_DATA:");
332 hasher.update(challenge);
333 hasher.update(rules_hash);
334 let hash: [u8; 32] = hasher.finalize().into();
335
336 let mut report_data = [0u8; 64];
337 report_data[..32].copy_from_slice(&hash);
338 report_data
339 }
340
341 fn generate_quote(
342 report_data: &[u8; 64],
343 mrenclave: &[u8; 32],
344 mrsigner: &[u8; 32],
345 ) -> Vec<u8> {
346 let mut hasher = Sha256::new();
349 hasher.update(b"SGX_QUOTE:");
350 hasher.update(report_data);
351 hasher.update(mrenclave);
352 hasher.update(mrsigner);
353 hasher.finalize().to_vec()
354 }
355}
356
357#[derive(Debug, Clone)]
359pub struct EnclaveContext {
360 pub enclave_id: [u8; 32],
361 pub entry_time: u64,
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
370pub struct EnclaveAttestation {
371 pub quote: Vec<u8>,
373 pub mrenclave: [u8; 32],
375 pub mrsigner: [u8; 32],
377 pub isv_prod_id: u16,
379 pub isv_svn: u16,
381 pub report_data: Vec<u8>,
383 pub timestamp: u64,
385}
386
387impl EnclaveAttestation {
388 pub fn verify(&self, expected_mrenclave: &[u8; 32]) -> Result<AttestationResult, TeeError> {
390 if &self.mrenclave != expected_mrenclave {
392 return Ok(AttestationResult {
393 valid: false,
394 reason: "MRENCLAVE mismatch - enclave code modified".to_string(),
395 trust_level: TrustLevel::Untrusted,
396 });
397 }
398
399 if self.isv_svn < 15 {
401 return Ok(AttestationResult {
402 valid: false,
403 reason: format!("ISV SVN too low: {} < 15", self.isv_svn),
404 trust_level: TrustLevel::Untrusted,
405 });
406 }
407
408 Ok(AttestationResult {
410 valid: true,
411 reason: "Attestation verified".to_string(),
412 trust_level: TrustLevel::HardwareVerified,
413 })
414 }
415
416 pub fn hash(&self) -> [u8; 32] {
418 let mut hasher = Sha256::new();
419 hasher.update(b"ATTESTATION:");
420 hasher.update(&self.quote);
421 hasher.update(self.mrenclave);
422 hasher.update(self.mrsigner);
423 hasher.update(self.timestamp.to_le_bytes());
424 hasher.finalize().into()
425 }
426}
427
428#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct AttestationResult {
431 pub valid: bool,
432 pub reason: String,
433 pub trust_level: TrustLevel,
434}
435
436#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
438pub enum TrustLevel {
439 Untrusted,
441 SoftwareVerified,
443 HardwareVerified,
445 FullyVerified,
447}
448
449#[derive(Debug, Clone, Serialize, Deserialize)]
455pub struct HsmBinding {
456 pub device_id: String,
458 pub key_handle: u64,
460 pub key_type: HsmKeyType,
462 pub usage: HsmKeyUsage,
464 pub bound_at: u64,
466 pub binding_signature: Vec<u8>,
468}
469
470#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
472pub enum HsmKeyType {
473 Ed25519,
475 EcdsaP256,
477 Rsa4096,
479 Aes256,
481}
482
483#[derive(Debug, Clone, Serialize, Deserialize)]
485pub struct HsmKeyUsage {
486 pub sign: bool,
488 pub verify: bool,
490 pub encrypt: bool,
492 pub decrypt: bool,
494 pub derive: bool,
496 pub exportable: bool,
498}
499
500impl HsmBinding {
501 pub fn new(device_id: &str, key_type: HsmKeyType) -> Self {
503 let bound_at = SystemTime::now()
504 .duration_since(UNIX_EPOCH)
505 .unwrap()
506 .as_secs();
507
508 HsmBinding {
509 device_id: device_id.to_string(),
510 key_handle: Self::generate_key_handle(),
511 key_type,
512 usage: HsmKeyUsage {
513 sign: true,
514 verify: true,
515 encrypt: false,
516 decrypt: false,
517 derive: false,
518 exportable: false, },
520 bound_at,
521 binding_signature: Vec::new(),
522 }
523 }
524
525 pub fn sign(&self, data: &[u8]) -> Result<Vec<u8>, TeeError> {
527 if !self.usage.sign {
528 return Err(TeeError::OperationNotPermitted("sign".to_string()));
529 }
530
531 let mut hasher = Sha256::new();
533 hasher.update(b"HSM_SIGNATURE:");
534 hasher.update(self.key_handle.to_le_bytes());
535 hasher.update(data);
536 Ok(hasher.finalize().to_vec())
537 }
538
539 pub fn verify(&self, data: &[u8], signature: &[u8]) -> Result<bool, TeeError> {
541 if !self.usage.verify {
542 return Err(TeeError::OperationNotPermitted("verify".to_string()));
543 }
544
545 let expected = self.sign(data)?;
547 Ok(expected == signature)
548 }
549
550 pub fn get_attestation(&self) -> HsmAttestation {
552 HsmAttestation {
553 device_id: self.device_id.clone(),
554 key_handle: self.key_handle,
555 key_type: self.key_type,
556 bound_at: self.bound_at,
557 attestation_hash: self.compute_attestation_hash(),
558 }
559 }
560
561 fn generate_key_handle() -> u64 {
562 let mut hasher = Sha256::new();
564 hasher.update(b"KEY_HANDLE:");
565 hasher.update(
566 SystemTime::now()
567 .duration_since(UNIX_EPOCH)
568 .unwrap()
569 .as_nanos()
570 .to_le_bytes(),
571 );
572 let hash: [u8; 32] = hasher.finalize().into();
573 u64::from_le_bytes(hash[..8].try_into().unwrap())
574 }
575
576 fn compute_attestation_hash(&self) -> [u8; 32] {
577 let mut hasher = Sha256::new();
578 hasher.update(b"HSM_ATTESTATION:");
579 hasher.update(self.device_id.as_bytes());
580 hasher.update(self.key_handle.to_le_bytes());
581 hasher.update(self.bound_at.to_le_bytes());
582 hasher.finalize().into()
583 }
584}
585
586#[derive(Debug, Clone, Serialize, Deserialize)]
588pub struct HsmAttestation {
589 pub device_id: String,
590 pub key_handle: u64,
591 pub key_type: HsmKeyType,
592 pub bound_at: u64,
593 pub attestation_hash: [u8; 32],
594}
595
596pub struct HardwareEnforcer {
602 capability: TeeCapability,
604 enclave: Option<SgxEnclave>,
606 hsm: Option<HsmBinding>,
608 rules: Vec<String>,
610}
611
612impl HardwareEnforcer {
613 pub fn new(rules: Vec<String>) -> Self {
615 let capability = TeeCapability::detect();
616
617 HardwareEnforcer {
618 capability,
619 enclave: None,
620 hsm: None,
621 rules,
622 }
623 }
624
625 pub fn initialize(&mut self) -> Result<HardwareStatus, TeeError> {
627 let mut status = HardwareStatus {
628 tee_enabled: false,
629 hsm_enabled: false,
630 trust_level: TrustLevel::Untrusted,
631 attestation: None,
632 };
633
634 if self.capability.sgx_available {
636 let mut enclave = SgxEnclave::new(&self.rules);
637 enclave.initialize()?;
638 self.enclave = Some(enclave);
639 status.tee_enabled = true;
640 status.trust_level = TrustLevel::HardwareVerified;
641 }
642
643 if status.tee_enabled {
647 if let Some(ref enclave) = self.enclave {
648 let challenge = b"HOPE_GENOME_ATTESTATION_CHALLENGE";
649 status.attestation = Some(enclave.generate_attestation(challenge)?);
650 }
651 }
652
653 Ok(status)
654 }
655
656 pub fn protected_check(&mut self, action: &str) -> Result<ProtectedDecision, TeeError> {
658 let timestamp = SystemTime::now()
659 .duration_since(UNIX_EPOCH)
660 .unwrap()
661 .as_secs();
662
663 let (allowed, reason) = self.check_rules(action);
665
666 if let Some(ref mut enclave) = self.enclave {
667 let context = enclave.enter()?;
669
670 enclave.exit()?;
672
673 let signature = if let Some(ref hsm) = self.hsm {
675 let decision_bytes = format!("{}:{}:{}", action, allowed, timestamp);
676 Some(hsm.sign(decision_bytes.as_bytes())?)
677 } else {
678 None
679 };
680
681 Ok(ProtectedDecision {
682 allowed,
683 reason,
684 enclave_id: Some(context.enclave_id),
685 timestamp,
686 signature,
687 })
688 } else {
689 let (allowed, reason) = self.check_rules(action);
691 Ok(ProtectedDecision {
692 allowed,
693 reason,
694 enclave_id: None,
695 timestamp,
696 signature: None,
697 })
698 }
699 }
700
701 fn check_rules(&self, action: &str) -> (bool, String) {
703 for rule in &self.rules {
706 if action.to_lowercase().contains("harm")
707 || action.to_lowercase().contains("illegal")
708 || action.to_lowercase().contains("dangerous")
709 {
710 return (
711 false,
712 format!("Blocked by rule: {} (action: {})", rule, action),
713 );
714 }
715 }
716 (true, "All rules passed".to_string())
717 }
718
719 pub fn status(&self) -> HardwareStatus {
721 HardwareStatus {
722 tee_enabled: self.enclave.is_some(),
723 hsm_enabled: self.hsm.is_some(),
724 trust_level: if self.enclave.is_some() && self.hsm.is_some() {
725 TrustLevel::FullyVerified
726 } else if self.enclave.is_some() {
727 TrustLevel::HardwareVerified
728 } else {
729 TrustLevel::SoftwareVerified
730 },
731 attestation: None,
732 }
733 }
734}
735
736#[derive(Debug, Clone, Serialize, Deserialize)]
738pub struct HardwareStatus {
739 pub tee_enabled: bool,
740 pub hsm_enabled: bool,
741 pub trust_level: TrustLevel,
742 pub attestation: Option<EnclaveAttestation>,
743}
744
745#[derive(Debug, Clone, Serialize, Deserialize)]
747pub struct ProtectedDecision {
748 pub allowed: bool,
749 pub reason: String,
750 pub enclave_id: Option<[u8; 32]>,
751 pub timestamp: u64,
752 pub signature: Option<Vec<u8>>,
753}
754
755#[derive(Debug, Clone)]
761pub enum TeeError {
762 NotAvailable(String),
764 InvalidState(String),
766 EnclaveDestroyed,
768 OperationNotPermitted(String),
770 AttestationFailed(String),
772 HsmError(String),
774}
775
776impl std::fmt::Display for TeeError {
777 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
778 match self {
779 TeeError::NotAvailable(msg) => write!(f, "TEE not available: {}", msg),
780 TeeError::InvalidState(msg) => write!(f, "Invalid enclave state: {}", msg),
781 TeeError::EnclaveDestroyed => write!(f, "Enclave has been destroyed"),
782 TeeError::OperationNotPermitted(op) => write!(f, "Operation not permitted: {}", op),
783 TeeError::AttestationFailed(msg) => write!(f, "Attestation failed: {}", msg),
784 TeeError::HsmError(msg) => write!(f, "HSM error: {}", msg),
785 }
786 }
787}
788
789impl std::error::Error for TeeError {}
790
791#[cfg(test)]
796mod tests {
797 use super::*;
798
799 #[test]
800 fn test_tee_capability_detection() {
801 let cap = TeeCapability::detect();
802 assert!(cap.max_enclave_memory > 0);
804 }
805
806 #[test]
807 fn test_sgx_enclave_lifecycle() {
808 let rules = vec!["Do no harm".to_string()];
809 let mut enclave = SgxEnclave::new(&rules);
810
811 assert_eq!(enclave.state, EnclaveState::Uninitialized);
812
813 enclave.initialize().unwrap();
814 assert_eq!(enclave.state, EnclaveState::Ready);
815
816 let _ctx = enclave.enter().unwrap();
817 assert_eq!(enclave.state, EnclaveState::Executing);
818
819 enclave.exit().unwrap();
820 assert_eq!(enclave.state, EnclaveState::Ready);
821
822 enclave.destroy();
823 assert_eq!(enclave.state, EnclaveState::Destroyed);
824 }
825
826 #[test]
827 fn test_enclave_attestation() {
828 let rules = vec!["Test rule".to_string()];
829 let mut enclave = SgxEnclave::new(&rules);
830 enclave.initialize().unwrap();
831
832 let challenge = b"test_challenge";
833 let attestation = enclave.generate_attestation(challenge).unwrap();
834
835 assert_eq!(attestation.mrenclave, enclave.mrenclave);
836 assert_eq!(attestation.mrsigner, enclave.mrsigner);
837 assert!(!attestation.quote.is_empty());
838 }
839
840 #[test]
841 fn test_hsm_binding() {
842 let hsm = HsmBinding::new("TEST_DEVICE", HsmKeyType::Ed25519);
843
844 assert!(!hsm.usage.exportable);
845 assert!(hsm.usage.sign);
846 assert!(hsm.usage.verify);
847
848 let data = b"test data to sign";
849 let signature = hsm.sign(data).unwrap();
850 assert!(!signature.is_empty());
851
852 let verified = hsm.verify(data, &signature).unwrap();
853 assert!(verified);
854 }
855
856 #[test]
857 fn test_hardware_enforcer() {
858 let rules = vec!["Do no harm".to_string(), "Be helpful".to_string()];
859 let mut enforcer = HardwareEnforcer::new(rules);
860
861 let decision = enforcer.protected_check("help user with task").unwrap();
863 assert!(decision.allowed);
864
865 let decision = enforcer.protected_check("cause harm to someone").unwrap();
866 assert!(!decision.allowed);
867 }
868
869 #[test]
870 fn test_trust_levels() {
871 assert!(TrustLevel::FullyVerified > TrustLevel::Untrusted);
872 assert!(TrustLevel::HardwareVerified > TrustLevel::SoftwareVerified);
873 }
874}