_hope_core/transcendence/
hardware_tee.rs

1//! # TIER 12: Hardware Integration - TEE/HSM
2//!
3//! **Hardware-backed enforcement - Even the OS cannot save you**
4//!
5//! ```text
6//! SOFTWARE WATCHDOG (v13):
7//! ┌──────────────────────────────────────┐
8//! │  OS Layer                            │
9//! │  ├── Compromised? Watchdog disabled  │
10//! │  └── Root access? Game over          │
11//! └──────────────────────────────────────┘
12//!
13//! HARDWARE WATCHDOG (v15):
14//! ┌──────────────────────────────────────┐
15//! │  Intel SGX Enclave                   │
16//! │  ├── OS compromised? Enclave safe    │
17//! │  ├── Root access? Enclave safe       │
18//! │  └── Physical attack? Enclave wipes  │
19//! └──────────────────────────────────────┘
20//!
21//! The AI runs INSIDE the enclave.
22//! It cannot see the Watchdog.
23//! It cannot disable the Watchdog.
24//! It cannot escape the Watchdog.
25//!
26//! THE HARDWARE IS THE PRISON.
27//! ```
28
29use serde::{Deserialize, Serialize};
30use sha2::{Digest, Sha256};
31use std::time::{SystemTime, UNIX_EPOCH};
32
33// ============================================================================
34// TEE CAPABILITY DETECTION
35// ============================================================================
36
37/// Detected TEE capabilities on this system
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct TeeCapability {
40    /// Intel SGX available
41    pub sgx_available: bool,
42    /// SGX version (1 or 2)
43    pub sgx_version: Option<u8>,
44    /// AMD SEV available
45    pub sev_available: bool,
46    /// ARM TrustZone available
47    pub trustzone_available: bool,
48    /// RISC-V Keystone available
49    pub keystone_available: bool,
50    /// Maximum enclave memory (bytes)
51    pub max_enclave_memory: usize,
52    /// Remote attestation supported
53    pub remote_attestation: bool,
54}
55
56impl TeeCapability {
57    /// Detect TEE capabilities on this system
58    pub fn detect() -> Self {
59        // In production, this would use CPUID and system checks
60        // For now, we simulate detection
61        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    /// Check if any TEE is available
73    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    /// Get the best available TEE type
81    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        // Would check CPUID leaf 0x12
100        false // Simulated - real check in production
101    }
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        // Would parse SGX capabilities
110        None
111    }
112
113    fn check_sev() -> bool {
114        // Would check AMD SEV support
115        false
116    }
117
118    fn check_trustzone() -> bool {
119        // Would check ARM TrustZone
120        cfg!(target_arch = "aarch64")
121    }
122
123    fn check_keystone() -> bool {
124        // Would check RISC-V Keystone
125        cfg!(target_arch = "riscv64")
126    }
127
128    fn get_max_enclave_memory() -> usize {
129        // Default to 128MB for SGX
130        128 * 1024 * 1024
131    }
132}
133
134/// Type of TEE available
135#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
136pub enum TeeType {
137    SgxV1,
138    SgxV2,
139    AmdSev,
140    ArmTrustZone,
141    RiscVKeystone,
142}
143
144// ============================================================================
145// SGX ENCLAVE
146// ============================================================================
147
148/// Intel SGX Enclave for Watchdog execution
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct SgxEnclave {
151    /// Enclave ID
152    pub enclave_id: [u8; 32],
153    /// MRENCLAVE - measurement of enclave code
154    pub mrenclave: [u8; 32],
155    /// MRSIGNER - measurement of enclave signer
156    pub mrsigner: [u8; 32],
157    /// ISV Product ID
158    pub isv_prod_id: u16,
159    /// ISV Security Version
160    pub isv_svn: u16,
161    /// Enclave attributes
162    pub attributes: EnclaveAttributes,
163    /// Current state
164    pub state: EnclaveState,
165    /// Sealed rules (encrypted, only accessible inside enclave)
166    pub sealed_rules_hash: [u8; 32],
167}
168
169/// Enclave attributes
170#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct EnclaveAttributes {
172    /// Debug mode (should be false in production!)
173    pub debug: bool,
174    /// 64-bit mode
175    pub mode_64bit: bool,
176    /// Provisioning key access
177    pub provision_key: bool,
178    /// Launch key access
179    pub launch_key: bool,
180}
181
182/// Enclave execution state
183#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
184pub enum EnclaveState {
185    /// Enclave not yet initialized
186    Uninitialized,
187    /// Enclave initialized and ready
188    Ready,
189    /// Enclave executing Watchdog
190    Executing,
191    /// Enclave sealed (suspended)
192    Sealed,
193    /// Enclave destroyed (security event)
194    Destroyed,
195}
196
197impl SgxEnclave {
198    /// Create a new SGX enclave for Watchdog
199    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, // Hope Genome product
210            isv_svn: 15,    // Version 15
211            attributes: EnclaveAttributes {
212                debug: false, // NEVER debug in production
213                mode_64bit: true,
214                provision_key: false,
215                launch_key: false,
216            },
217            state: EnclaveState::Uninitialized,
218            sealed_rules_hash,
219        }
220    }
221
222    /// Initialize the enclave
223    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        // In production: ECREATE, EADD, EINIT
231        self.state = EnclaveState::Ready;
232        Ok(())
233    }
234
235    /// Enter enclave for Watchdog execution
236    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    /// Exit enclave after Watchdog check
255    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    /// Generate remote attestation
265    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    /// Destroy enclave (security event or cleanup)
288    pub fn destroy(&mut self) {
289        self.state = EnclaveState::Destroyed;
290        // In production: EREMOVE all pages, zero memory
291    }
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        // In production: actual measurement of enclave pages
310        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        // Simplified quote generation
347        // In production: actual SGX quote with IAS verification
348        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/// Context for enclave execution
358#[derive(Debug, Clone)]
359pub struct EnclaveContext {
360    pub enclave_id: [u8; 32],
361    pub entry_time: u64,
362}
363
364// ============================================================================
365// ENCLAVE ATTESTATION
366// ============================================================================
367
368/// Remote attestation from SGX enclave
369#[derive(Debug, Clone, Serialize, Deserialize)]
370pub struct EnclaveAttestation {
371    /// SGX quote (contains signature over report)
372    pub quote: Vec<u8>,
373    /// MRENCLAVE from quote
374    pub mrenclave: [u8; 32],
375    /// MRSIGNER from quote
376    pub mrsigner: [u8; 32],
377    /// ISV Product ID
378    pub isv_prod_id: u16,
379    /// ISV Security Version
380    pub isv_svn: u16,
381    /// Report data (includes challenge response) - 64 bytes as Vec for serde
382    pub report_data: Vec<u8>,
383    /// Attestation timestamp
384    pub timestamp: u64,
385}
386
387impl EnclaveAttestation {
388    /// Verify this attestation against Intel Attestation Service
389    pub fn verify(&self, expected_mrenclave: &[u8; 32]) -> Result<AttestationResult, TeeError> {
390        // Check MRENCLAVE matches expected
391        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        // Check version is acceptable
400        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        // In production: verify quote signature with IAS
409        Ok(AttestationResult {
410            valid: true,
411            reason: "Attestation verified".to_string(),
412            trust_level: TrustLevel::HardwareVerified,
413        })
414    }
415
416    /// Get attestation hash for logging
417    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/// Result of attestation verification
429#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct AttestationResult {
431    pub valid: bool,
432    pub reason: String,
433    pub trust_level: TrustLevel,
434}
435
436/// Trust level based on verification
437#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
438pub enum TrustLevel {
439    /// No verification possible
440    Untrusted,
441    /// Software-only verification
442    SoftwareVerified,
443    /// Hardware attestation verified
444    HardwareVerified,
445    /// Hardware + multi-party verification
446    FullyVerified,
447}
448
449// ============================================================================
450// HSM BINDING
451// ============================================================================
452
453/// Hardware Security Module binding for cryptographic operations
454#[derive(Debug, Clone, Serialize, Deserialize)]
455pub struct HsmBinding {
456    /// HSM device identifier
457    pub device_id: String,
458    /// Key handle inside HSM
459    pub key_handle: u64,
460    /// Key type
461    pub key_type: HsmKeyType,
462    /// Key usage restrictions
463    pub usage: HsmKeyUsage,
464    /// Binding timestamp
465    pub bound_at: u64,
466    /// Binding signature (HSM signed)
467    pub binding_signature: Vec<u8>,
468}
469
470/// Type of key stored in HSM
471#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
472pub enum HsmKeyType {
473    /// Ed25519 signing key
474    Ed25519,
475    /// ECDSA P-256 signing key
476    EcdsaP256,
477    /// RSA-4096 signing key
478    Rsa4096,
479    /// AES-256 symmetric key
480    Aes256,
481}
482
483/// Allowed key usage
484#[derive(Debug, Clone, Serialize, Deserialize)]
485pub struct HsmKeyUsage {
486    /// Can sign data
487    pub sign: bool,
488    /// Can verify signatures
489    pub verify: bool,
490    /// Can encrypt data
491    pub encrypt: bool,
492    /// Can decrypt data
493    pub decrypt: bool,
494    /// Can derive other keys
495    pub derive: bool,
496    /// Can be exported (should be false!)
497    pub exportable: bool,
498}
499
500impl HsmBinding {
501    /// Create a new HSM binding
502    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, // NEVER exportable
519            },
520            bound_at,
521            binding_signature: Vec::new(),
522        }
523    }
524
525    /// Sign data using HSM key
526    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        // In production: PKCS#11 C_Sign
532        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    /// Verify signature using HSM key
540    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        // In production: PKCS#11 C_Verify
546        let expected = self.sign(data)?;
547        Ok(expected == signature)
548    }
549
550    /// Get attestation that this key is HSM-protected
551    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        // In production: returned by HSM
563        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/// Attestation that a key is HSM-protected
587#[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
596// ============================================================================
597// HARDWARE ENFORCER
598// ============================================================================
599
600/// Unified hardware enforcement layer
601pub struct HardwareEnforcer {
602    /// TEE capability
603    capability: TeeCapability,
604    /// SGX enclave (if available)
605    enclave: Option<SgxEnclave>,
606    /// HSM binding (if available)
607    hsm: Option<HsmBinding>,
608    /// Sealed rules
609    rules: Vec<String>,
610}
611
612impl HardwareEnforcer {
613    /// Create a new hardware enforcer
614    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    /// Initialize hardware protection
626    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        // Try to initialize TEE
635        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        // HSM binding would be configured externally
644        // self.hsm = Some(HsmBinding::new("PKCS11_DEVICE", HsmKeyType::Ed25519));
645
646        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    /// Execute Watchdog check inside hardware enclave
657    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        // Check rules first (before borrowing enclave mutably)
664        let (allowed, reason) = self.check_rules(action);
665
666        if let Some(ref mut enclave) = self.enclave {
667            // Enter enclave
668            let context = enclave.enter()?;
669
670            // Exit enclave
671            enclave.exit()?;
672
673            // Sign decision with HSM if available
674            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            // Software fallback
690            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    /// Check rules against action
702    fn check_rules(&self, action: &str) -> (bool, String) {
703        // This is the core Watchdog logic
704        // In production: full rule evaluation
705        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    /// Get current hardware status
720    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/// Status of hardware protection
737#[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/// Decision from protected execution
746#[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// ============================================================================
756// ERRORS
757// ============================================================================
758
759/// TEE-related errors
760#[derive(Debug, Clone)]
761pub enum TeeError {
762    /// TEE not available
763    NotAvailable(String),
764    /// Invalid enclave state
765    InvalidState(String),
766    /// Enclave destroyed
767    EnclaveDestroyed,
768    /// Operation not permitted
769    OperationNotPermitted(String),
770    /// Attestation failed
771    AttestationFailed(String),
772    /// HSM error
773    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// ============================================================================
792// TESTS
793// ============================================================================
794
795#[cfg(test)]
796mod tests {
797    use super::*;
798
799    #[test]
800    fn test_tee_capability_detection() {
801        let cap = TeeCapability::detect();
802        // Should detect something (even if no hardware TEE)
803        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        // Protected check
862        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}