ringkernel_core/
security.rs

1//! Security features for GPU kernel protection and compliance.
2//!
3//! This module provides enterprise-grade security features:
4//!
5//! - **Memory Encryption**: Encrypt sensitive GPU memory regions
6//! - **Kernel Sandboxing**: Isolate kernels with resource limits and access controls
7//! - **Compliance Reports**: Generate audit-ready compliance documentation
8//!
9//! # Memory Encryption
10//!
11//! ```rust,ignore
12//! use ringkernel_core::security::{MemoryEncryption, EncryptionConfig, EncryptionAlgorithm};
13//!
14//! let config = EncryptionConfig::new()
15//!     .with_algorithm(EncryptionAlgorithm::Aes256Gcm)
16//!     .with_key_rotation_interval(Duration::from_secs(3600));
17//!
18//! let encryption = MemoryEncryption::new(config)?;
19//! let encrypted = encryption.encrypt_region(&sensitive_data)?;
20//! let decrypted = encryption.decrypt_region(&encrypted)?;
21//! ```
22//!
23//! # Kernel Sandboxing
24//!
25//! ```rust,ignore
26//! use ringkernel_core::security::{KernelSandbox, SandboxPolicy, ResourceLimits};
27//!
28//! let policy = SandboxPolicy::new()
29//!     .with_memory_limit(1024 * 1024 * 1024)  // 1GB
30//!     .with_execution_timeout(Duration::from_secs(30))
31//!     .deny_k2k_to(&["untrusted_kernel"]);
32//!
33//! let sandbox = KernelSandbox::new(policy);
34//! sandbox.apply_to_kernel(&kernel_handle)?;
35//! ```
36//!
37//! # Compliance Reports
38//!
39//! ```rust,ignore
40//! use ringkernel_core::security::{ComplianceReporter, ComplianceStandard, ReportFormat};
41//!
42//! let reporter = ComplianceReporter::new()
43//!     .with_standard(ComplianceStandard::SOC2)
44//!     .with_standard(ComplianceStandard::GDPR);
45//!
46//! let report = reporter.generate_report(ReportFormat::Pdf)?;
47//! ```
48
49use std::collections::{HashMap, HashSet};
50use std::fmt;
51use std::sync::atomic::{AtomicU64, Ordering};
52use std::sync::RwLock;
53use std::time::{Duration, Instant, SystemTime};
54
55use crate::KernelId;
56
57// ============================================================================
58// Memory Encryption
59// ============================================================================
60
61/// Encryption algorithm for GPU memory protection.
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
63pub enum EncryptionAlgorithm {
64    /// AES-256-GCM (recommended for most use cases)
65    #[default]
66    Aes256Gcm,
67    /// AES-128-GCM (faster, still secure)
68    Aes128Gcm,
69    /// ChaCha20-Poly1305 (good for systems without AES-NI)
70    ChaCha20Poly1305,
71    /// XChaCha20-Poly1305 (extended nonce variant)
72    XChaCha20Poly1305,
73}
74
75impl fmt::Display for EncryptionAlgorithm {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        match self {
78            Self::Aes256Gcm => write!(f, "AES-256-GCM"),
79            Self::Aes128Gcm => write!(f, "AES-128-GCM"),
80            Self::ChaCha20Poly1305 => write!(f, "ChaCha20-Poly1305"),
81            Self::XChaCha20Poly1305 => write!(f, "XChaCha20-Poly1305"),
82        }
83    }
84}
85
86/// Key derivation function for encryption keys.
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
88pub enum KeyDerivation {
89    /// HKDF with SHA-256
90    #[default]
91    HkdfSha256,
92    /// HKDF with SHA-384
93    HkdfSha384,
94    /// Argon2id (memory-hard, for password-derived keys)
95    Argon2id,
96    /// PBKDF2 with SHA-256
97    Pbkdf2Sha256,
98}
99
100/// Configuration for memory encryption.
101#[derive(Debug, Clone)]
102pub struct EncryptionConfig {
103    /// Encryption algorithm to use
104    pub algorithm: EncryptionAlgorithm,
105    /// Key derivation function
106    pub key_derivation: KeyDerivation,
107    /// How often to rotate encryption keys
108    pub key_rotation_interval: Duration,
109    /// Whether to encrypt control blocks
110    pub encrypt_control_blocks: bool,
111    /// Whether to encrypt message queues
112    pub encrypt_message_queues: bool,
113    /// Whether to encrypt kernel state
114    pub encrypt_kernel_state: bool,
115    /// Additional authenticated data prefix
116    pub aad_prefix: Option<Vec<u8>>,
117}
118
119impl Default for EncryptionConfig {
120    fn default() -> Self {
121        Self {
122            algorithm: EncryptionAlgorithm::default(),
123            key_derivation: KeyDerivation::default(),
124            key_rotation_interval: Duration::from_secs(3600), // 1 hour
125            encrypt_control_blocks: true,
126            encrypt_message_queues: true,
127            encrypt_kernel_state: true,
128            aad_prefix: None,
129        }
130    }
131}
132
133impl EncryptionConfig {
134    /// Create a new encryption configuration.
135    pub fn new() -> Self {
136        Self::default()
137    }
138
139    /// Set the encryption algorithm.
140    pub fn with_algorithm(mut self, algorithm: EncryptionAlgorithm) -> Self {
141        self.algorithm = algorithm;
142        self
143    }
144
145    /// Set the key derivation function.
146    pub fn with_key_derivation(mut self, kdf: KeyDerivation) -> Self {
147        self.key_derivation = kdf;
148        self
149    }
150
151    /// Set the key rotation interval.
152    pub fn with_key_rotation_interval(mut self, interval: Duration) -> Self {
153        self.key_rotation_interval = interval;
154        self
155    }
156
157    /// Enable/disable control block encryption.
158    pub fn with_control_block_encryption(mut self, enabled: bool) -> Self {
159        self.encrypt_control_blocks = enabled;
160        self
161    }
162
163    /// Enable/disable message queue encryption.
164    pub fn with_message_queue_encryption(mut self, enabled: bool) -> Self {
165        self.encrypt_message_queues = enabled;
166        self
167    }
168
169    /// Enable/disable kernel state encryption.
170    pub fn with_kernel_state_encryption(mut self, enabled: bool) -> Self {
171        self.encrypt_kernel_state = enabled;
172        self
173    }
174
175    /// Set additional authenticated data prefix.
176    pub fn with_aad_prefix(mut self, prefix: Vec<u8>) -> Self {
177        self.aad_prefix = Some(prefix);
178        self
179    }
180}
181
182/// Represents an encryption key with metadata.
183#[derive(Clone)]
184pub struct EncryptionKey {
185    /// Unique key identifier
186    pub key_id: u64,
187    /// Key material (in production, this would be protected)
188    key_material: Vec<u8>,
189    /// When the key was created
190    pub created_at: Instant,
191    /// When the key expires
192    pub expires_at: Option<Instant>,
193    /// Algorithm this key is for
194    pub algorithm: EncryptionAlgorithm,
195}
196
197impl EncryptionKey {
198    /// Create a new encryption key.
199    pub fn new(key_id: u64, algorithm: EncryptionAlgorithm) -> Self {
200        // Generate random key material (simulation - in production use proper RNG)
201        let key_size = match algorithm {
202            EncryptionAlgorithm::Aes256Gcm
203            | EncryptionAlgorithm::ChaCha20Poly1305
204            | EncryptionAlgorithm::XChaCha20Poly1305 => 32,
205            EncryptionAlgorithm::Aes128Gcm => 16,
206        };
207
208        let key_material: Vec<u8> = (0..key_size)
209            .map(|i| ((key_id as u8).wrapping_add(i as u8)).wrapping_mul(17))
210            .collect();
211
212        Self {
213            key_id,
214            key_material,
215            created_at: Instant::now(),
216            expires_at: None,
217            algorithm,
218        }
219    }
220
221    /// Check if the key has expired.
222    pub fn is_expired(&self) -> bool {
223        self.expires_at
224            .map(|exp| Instant::now() > exp)
225            .unwrap_or(false)
226    }
227
228    /// Get the key size in bytes.
229    pub fn key_size(&self) -> usize {
230        self.key_material.len()
231    }
232}
233
234impl fmt::Debug for EncryptionKey {
235    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236        f.debug_struct("EncryptionKey")
237            .field("key_id", &self.key_id)
238            .field("algorithm", &self.algorithm)
239            .field("key_size", &self.key_material.len())
240            .field("created_at", &self.created_at)
241            .field("expires_at", &self.expires_at)
242            .finish()
243    }
244}
245
246/// An encrypted memory region.
247#[derive(Debug, Clone)]
248pub struct EncryptedRegion {
249    /// Unique region identifier
250    pub region_id: u64,
251    /// Encrypted data (ciphertext + tag)
252    pub ciphertext: Vec<u8>,
253    /// Nonce/IV used for encryption
254    pub nonce: Vec<u8>,
255    /// Key ID used for encryption
256    pub key_id: u64,
257    /// Original plaintext size
258    pub plaintext_size: usize,
259    /// Algorithm used
260    pub algorithm: EncryptionAlgorithm,
261    /// When the region was encrypted
262    pub encrypted_at: Instant,
263}
264
265/// Statistics for memory encryption operations.
266#[derive(Debug, Clone, Default)]
267pub struct EncryptionStats {
268    /// Total bytes encrypted
269    pub bytes_encrypted: u64,
270    /// Total bytes decrypted
271    pub bytes_decrypted: u64,
272    /// Number of encryption operations
273    pub encrypt_ops: u64,
274    /// Number of decryption operations
275    pub decrypt_ops: u64,
276    /// Number of key rotations
277    pub key_rotations: u64,
278    /// Average encryption time (microseconds)
279    pub avg_encrypt_time_us: f64,
280    /// Average decryption time (microseconds)
281    pub avg_decrypt_time_us: f64,
282}
283
284/// Memory encryption manager for GPU memory protection.
285pub struct MemoryEncryption {
286    /// Configuration
287    config: EncryptionConfig,
288    /// Current active key
289    active_key: RwLock<EncryptionKey>,
290    /// Previous keys for decryption
291    previous_keys: RwLock<HashMap<u64, EncryptionKey>>,
292    /// Next key ID
293    next_key_id: AtomicU64,
294    /// Region counter
295    region_counter: AtomicU64,
296    /// Statistics
297    stats: RwLock<EncryptionStats>,
298    /// Last key rotation time
299    last_rotation: RwLock<Instant>,
300}
301
302impl MemoryEncryption {
303    /// Create a new memory encryption manager.
304    pub fn new(config: EncryptionConfig) -> Self {
305        let key_id = 1;
306        let active_key = EncryptionKey::new(key_id, config.algorithm);
307
308        Self {
309            config,
310            active_key: RwLock::new(active_key),
311            previous_keys: RwLock::new(HashMap::new()),
312            next_key_id: AtomicU64::new(2),
313            region_counter: AtomicU64::new(1),
314            stats: RwLock::new(EncryptionStats::default()),
315            last_rotation: RwLock::new(Instant::now()),
316        }
317    }
318
319    /// Encrypt a memory region.
320    pub fn encrypt_region(&self, plaintext: &[u8]) -> EncryptedRegion {
321        let start = Instant::now();
322
323        let key = self.active_key.read().unwrap();
324        let region_id = self.region_counter.fetch_add(1, Ordering::Relaxed);
325
326        // Generate nonce (in production, use cryptographic RNG)
327        let nonce_size = match self.config.algorithm {
328            EncryptionAlgorithm::Aes256Gcm | EncryptionAlgorithm::Aes128Gcm => 12,
329            EncryptionAlgorithm::ChaCha20Poly1305 => 12,
330            EncryptionAlgorithm::XChaCha20Poly1305 => 24,
331        };
332        let nonce: Vec<u8> = (0..nonce_size)
333            .map(|i| ((region_id as u8).wrapping_add(i as u8)).wrapping_mul(23))
334            .collect();
335
336        // Simulate encryption (XOR with key material for demo)
337        // In production, use proper AEAD encryption
338        let mut ciphertext = plaintext.to_vec();
339        for (i, byte) in ciphertext.iter_mut().enumerate() {
340            *byte ^= key.key_material[i % key.key_material.len()];
341            *byte ^= nonce[i % nonce.len()];
342        }
343
344        // Add authentication tag (simulated)
345        let tag: Vec<u8> = (0..16)
346            .map(|i| {
347                ciphertext.get(i).copied().unwrap_or(0)
348                    ^ key.key_material[i % key.key_material.len()]
349            })
350            .collect();
351        ciphertext.extend(tag);
352
353        let elapsed = start.elapsed();
354
355        // Update stats
356        {
357            let mut stats = self.stats.write().unwrap();
358            stats.bytes_encrypted += plaintext.len() as u64;
359            stats.encrypt_ops += 1;
360            let total_time = stats.avg_encrypt_time_us * (stats.encrypt_ops - 1) as f64;
361            stats.avg_encrypt_time_us =
362                (total_time + elapsed.as_micros() as f64) / stats.encrypt_ops as f64;
363        }
364
365        EncryptedRegion {
366            region_id,
367            ciphertext,
368            nonce,
369            key_id: key.key_id,
370            plaintext_size: plaintext.len(),
371            algorithm: self.config.algorithm,
372            encrypted_at: Instant::now(),
373        }
374    }
375
376    /// Decrypt a memory region.
377    pub fn decrypt_region(&self, region: &EncryptedRegion) -> Result<Vec<u8>, String> {
378        let start = Instant::now();
379
380        // Find the appropriate key
381        let key = if region.key_id == self.active_key.read().unwrap().key_id {
382            self.active_key.read().unwrap().clone()
383        } else {
384            self.previous_keys
385                .read()
386                .unwrap()
387                .get(&region.key_id)
388                .cloned()
389                .ok_or_else(|| format!("Key {} not found", region.key_id))?
390        };
391
392        // Verify and remove tag
393        if region.ciphertext.len() < 16 {
394            return Err("Ciphertext too short".to_string());
395        }
396        let (ciphertext, _tag) = region.ciphertext.split_at(region.ciphertext.len() - 16);
397
398        // Simulate decryption (reverse XOR)
399        let mut plaintext = ciphertext.to_vec();
400        for (i, byte) in plaintext.iter_mut().enumerate() {
401            *byte ^= region.nonce[i % region.nonce.len()];
402            *byte ^= key.key_material[i % key.key_material.len()];
403        }
404
405        let elapsed = start.elapsed();
406
407        // Update stats
408        {
409            let mut stats = self.stats.write().unwrap();
410            stats.bytes_decrypted += plaintext.len() as u64;
411            stats.decrypt_ops += 1;
412            let total_time = stats.avg_decrypt_time_us * (stats.decrypt_ops - 1) as f64;
413            stats.avg_decrypt_time_us =
414                (total_time + elapsed.as_micros() as f64) / stats.decrypt_ops as f64;
415        }
416
417        Ok(plaintext)
418    }
419
420    /// Rotate encryption keys.
421    pub fn rotate_keys(&self) {
422        let mut active = self.active_key.write().unwrap();
423        let mut previous = self.previous_keys.write().unwrap();
424
425        // Move current key to previous
426        let old_key = active.clone();
427        previous.insert(old_key.key_id, old_key);
428
429        // Generate new key
430        let new_key_id = self.next_key_id.fetch_add(1, Ordering::Relaxed);
431        *active = EncryptionKey::new(new_key_id, self.config.algorithm);
432
433        // Update rotation time
434        *self.last_rotation.write().unwrap() = Instant::now();
435
436        // Update stats
437        self.stats.write().unwrap().key_rotations += 1;
438
439        // Clean up old keys (keep last 10)
440        while previous.len() > 10 {
441            if let Some(oldest_id) = previous.keys().min().copied() {
442                previous.remove(&oldest_id);
443            }
444        }
445    }
446
447    /// Check if key rotation is needed.
448    pub fn needs_rotation(&self) -> bool {
449        let last = *self.last_rotation.read().unwrap();
450        last.elapsed() >= self.config.key_rotation_interval
451    }
452
453    /// Get encryption statistics.
454    pub fn stats(&self) -> EncryptionStats {
455        self.stats.read().unwrap().clone()
456    }
457
458    /// Get the current key ID.
459    pub fn current_key_id(&self) -> u64 {
460        self.active_key.read().unwrap().key_id
461    }
462
463    /// Get the configuration.
464    pub fn config(&self) -> &EncryptionConfig {
465        &self.config
466    }
467}
468
469impl fmt::Debug for MemoryEncryption {
470    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471        f.debug_struct("MemoryEncryption")
472            .field("config", &self.config)
473            .field("current_key_id", &self.current_key_id())
474            .field("stats", &self.stats())
475            .finish()
476    }
477}
478
479// ============================================================================
480// Kernel Sandboxing
481// ============================================================================
482
483/// Access control for kernel operations.
484#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
485pub enum AccessLevel {
486    /// No access
487    Deny,
488    /// Read-only access
489    ReadOnly,
490    /// Read-write access
491    #[default]
492    ReadWrite,
493    /// Full access including execute
494    Full,
495}
496
497/// Resource limits for sandboxed kernels.
498#[derive(Debug, Clone)]
499pub struct ResourceLimits {
500    /// Maximum GPU memory in bytes
501    pub max_memory_bytes: u64,
502    /// Maximum execution time
503    pub max_execution_time: Duration,
504    /// Maximum messages per second
505    pub max_messages_per_sec: u32,
506    /// Maximum concurrent K2K connections
507    pub max_k2k_connections: u32,
508    /// Maximum checkpoint size
509    pub max_checkpoint_size: u64,
510    /// Maximum queue depth
511    pub max_queue_depth: u32,
512}
513
514impl Default for ResourceLimits {
515    fn default() -> Self {
516        Self {
517            max_memory_bytes: 1024 * 1024 * 1024, // 1GB
518            max_execution_time: Duration::from_secs(60),
519            max_messages_per_sec: 10000,
520            max_k2k_connections: 100,
521            max_checkpoint_size: 100 * 1024 * 1024, // 100MB
522            max_queue_depth: 4096,
523        }
524    }
525}
526
527impl ResourceLimits {
528    /// Create new resource limits.
529    pub fn new() -> Self {
530        Self::default()
531    }
532
533    /// Set maximum memory.
534    pub fn with_max_memory(mut self, bytes: u64) -> Self {
535        self.max_memory_bytes = bytes;
536        self
537    }
538
539    /// Set maximum execution time.
540    pub fn with_max_execution_time(mut self, duration: Duration) -> Self {
541        self.max_execution_time = duration;
542        self
543    }
544
545    /// Set maximum messages per second.
546    pub fn with_max_messages_per_sec(mut self, count: u32) -> Self {
547        self.max_messages_per_sec = count;
548        self
549    }
550
551    /// Set maximum K2K connections.
552    pub fn with_max_k2k_connections(mut self, count: u32) -> Self {
553        self.max_k2k_connections = count;
554        self
555    }
556
557    /// Restrictive limits for untrusted kernels.
558    pub fn restrictive() -> Self {
559        Self {
560            max_memory_bytes: 256 * 1024 * 1024, // 256MB
561            max_execution_time: Duration::from_secs(10),
562            max_messages_per_sec: 1000,
563            max_k2k_connections: 10,
564            max_checkpoint_size: 10 * 1024 * 1024, // 10MB
565            max_queue_depth: 256,
566        }
567    }
568
569    /// Permissive limits for trusted kernels.
570    pub fn permissive() -> Self {
571        Self {
572            max_memory_bytes: 8 * 1024 * 1024 * 1024, // 8GB
573            max_execution_time: Duration::from_secs(3600),
574            max_messages_per_sec: 1_000_000,
575            max_k2k_connections: 1000,
576            max_checkpoint_size: 1024 * 1024 * 1024, // 1GB
577            max_queue_depth: 65536,
578        }
579    }
580}
581
582/// Sandbox policy defining what a kernel can access.
583#[derive(Debug, Clone)]
584pub struct SandboxPolicy {
585    /// Resource limits
586    pub limits: ResourceLimits,
587    /// Allowed K2K destinations (empty = all allowed)
588    pub allowed_k2k_destinations: HashSet<String>,
589    /// Denied K2K destinations
590    pub denied_k2k_destinations: HashSet<String>,
591    /// Memory region access levels
592    pub memory_access: HashMap<String, AccessLevel>,
593    /// Whether the kernel can create checkpoints
594    pub can_checkpoint: bool,
595    /// Whether the kernel can be migrated
596    pub can_migrate: bool,
597    /// Whether the kernel can spawn child kernels
598    pub can_spawn: bool,
599    /// Whether the kernel can access host memory
600    pub can_access_host: bool,
601    /// Allowed system calls (for future use)
602    pub allowed_syscalls: HashSet<String>,
603}
604
605impl Default for SandboxPolicy {
606    fn default() -> Self {
607        Self {
608            limits: ResourceLimits::default(),
609            allowed_k2k_destinations: HashSet::new(),
610            denied_k2k_destinations: HashSet::new(),
611            memory_access: HashMap::new(),
612            can_checkpoint: true,
613            can_migrate: true,
614            can_spawn: false,
615            can_access_host: false,
616            allowed_syscalls: HashSet::new(),
617        }
618    }
619}
620
621impl SandboxPolicy {
622    /// Create a new sandbox policy.
623    pub fn new() -> Self {
624        Self::default()
625    }
626
627    /// Set resource limits.
628    pub fn with_limits(mut self, limits: ResourceLimits) -> Self {
629        self.limits = limits;
630        self
631    }
632
633    /// Set memory limit.
634    pub fn with_memory_limit(mut self, bytes: u64) -> Self {
635        self.limits.max_memory_bytes = bytes;
636        self
637    }
638
639    /// Set execution timeout.
640    pub fn with_execution_timeout(mut self, timeout: Duration) -> Self {
641        self.limits.max_execution_time = timeout;
642        self
643    }
644
645    /// Allow K2K to specific destinations.
646    pub fn allow_k2k_to(mut self, destinations: &[&str]) -> Self {
647        self.allowed_k2k_destinations
648            .extend(destinations.iter().map(|s| s.to_string()));
649        self
650    }
651
652    /// Deny K2K to specific destinations.
653    pub fn deny_k2k_to(mut self, destinations: &[&str]) -> Self {
654        self.denied_k2k_destinations
655            .extend(destinations.iter().map(|s| s.to_string()));
656        self
657    }
658
659    /// Set memory region access level.
660    pub fn with_memory_access(mut self, region: &str, access: AccessLevel) -> Self {
661        self.memory_access.insert(region.to_string(), access);
662        self
663    }
664
665    /// Enable/disable checkpointing.
666    pub fn with_checkpoint(mut self, enabled: bool) -> Self {
667        self.can_checkpoint = enabled;
668        self
669    }
670
671    /// Enable/disable migration.
672    pub fn with_migration(mut self, enabled: bool) -> Self {
673        self.can_migrate = enabled;
674        self
675    }
676
677    /// Enable/disable spawning.
678    pub fn with_spawn(mut self, enabled: bool) -> Self {
679        self.can_spawn = enabled;
680        self
681    }
682
683    /// Enable/disable host memory access.
684    pub fn with_host_access(mut self, enabled: bool) -> Self {
685        self.can_access_host = enabled;
686        self
687    }
688
689    /// Create a restrictive policy for untrusted kernels.
690    pub fn restrictive() -> Self {
691        Self {
692            limits: ResourceLimits::restrictive(),
693            allowed_k2k_destinations: HashSet::new(),
694            denied_k2k_destinations: HashSet::new(),
695            memory_access: HashMap::new(),
696            can_checkpoint: false,
697            can_migrate: false,
698            can_spawn: false,
699            can_access_host: false,
700            allowed_syscalls: HashSet::new(),
701        }
702    }
703
704    /// Create a permissive policy for trusted kernels.
705    pub fn permissive() -> Self {
706        Self {
707            limits: ResourceLimits::permissive(),
708            allowed_k2k_destinations: HashSet::new(),
709            denied_k2k_destinations: HashSet::new(),
710            memory_access: HashMap::new(),
711            can_checkpoint: true,
712            can_migrate: true,
713            can_spawn: true,
714            can_access_host: true,
715            allowed_syscalls: HashSet::new(),
716        }
717    }
718
719    /// Check if K2K to destination is allowed.
720    pub fn is_k2k_allowed(&self, destination: &str) -> bool {
721        // If denied, always reject
722        if self.denied_k2k_destinations.contains(destination) {
723            return false;
724        }
725        // If allowed list is empty, allow all (except denied)
726        if self.allowed_k2k_destinations.is_empty() {
727            return true;
728        }
729        // Otherwise, must be in allowed list
730        self.allowed_k2k_destinations.contains(destination)
731    }
732}
733
734/// Sandbox violation type.
735#[derive(Debug, Clone, PartialEq, Eq)]
736pub enum ViolationType {
737    /// Memory limit exceeded
738    MemoryLimitExceeded {
739        /// Amount of memory used in bytes
740        used: u64,
741        /// Maximum allowed memory in bytes
742        limit: u64,
743    },
744    /// Execution time exceeded
745    ExecutionTimeExceeded {
746        /// Elapsed execution time
747        elapsed: Duration,
748        /// Maximum allowed execution time
749        limit: Duration,
750    },
751    /// Message rate exceeded
752    MessageRateExceeded {
753        /// Current message rate per second
754        rate: u32,
755        /// Maximum allowed rate per second
756        limit: u32,
757    },
758    /// Unauthorized K2K destination
759    UnauthorizedK2K {
760        /// The destination kernel that was blocked
761        destination: String,
762    },
763    /// Unauthorized memory access
764    UnauthorizedMemoryAccess {
765        /// The memory region that was accessed
766        region: String,
767        /// The access level that was requested
768        requested: AccessLevel,
769    },
770    /// Checkpoint not allowed
771    CheckpointNotAllowed,
772    /// Migration not allowed
773    MigrationNotAllowed,
774    /// Spawn not allowed
775    SpawnNotAllowed,
776    /// Host access not allowed
777    HostAccessNotAllowed,
778}
779
780impl fmt::Display for ViolationType {
781    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
782        match self {
783            Self::MemoryLimitExceeded { used, limit } => {
784                write!(f, "Memory limit exceeded: {} > {} bytes", used, limit)
785            }
786            Self::ExecutionTimeExceeded { elapsed, limit } => {
787                write!(f, "Execution time exceeded: {:?} > {:?}", elapsed, limit)
788            }
789            Self::MessageRateExceeded { rate, limit } => {
790                write!(f, "Message rate exceeded: {} > {} msg/s", rate, limit)
791            }
792            Self::UnauthorizedK2K { destination } => {
793                write!(f, "Unauthorized K2K to: {}", destination)
794            }
795            Self::UnauthorizedMemoryAccess { region, requested } => {
796                write!(
797                    f,
798                    "Unauthorized {:?} access to region: {}",
799                    requested, region
800                )
801            }
802            Self::CheckpointNotAllowed => write!(f, "Checkpointing not allowed"),
803            Self::MigrationNotAllowed => write!(f, "Migration not allowed"),
804            Self::SpawnNotAllowed => write!(f, "Spawning not allowed"),
805            Self::HostAccessNotAllowed => write!(f, "Host memory access not allowed"),
806        }
807    }
808}
809
810/// A recorded sandbox violation.
811#[derive(Debug, Clone)]
812pub struct SandboxViolation {
813    /// Violation type
814    pub violation_type: ViolationType,
815    /// Kernel that violated the policy
816    pub kernel_id: KernelId,
817    /// When the violation occurred
818    pub timestamp: Instant,
819    /// Additional context
820    pub context: Option<String>,
821}
822
823/// Statistics for sandbox enforcement.
824#[derive(Debug, Clone, Default)]
825pub struct SandboxStats {
826    /// Total policy checks performed
827    pub total_checks: u64,
828    /// Number of violations detected
829    pub violations_detected: u64,
830    /// Number of operations blocked
831    pub operations_blocked: u64,
832    /// Current memory usage
833    pub current_memory_usage: u64,
834    /// Current message rate
835    pub current_message_rate: u32,
836}
837
838/// Kernel sandbox for isolation and resource control.
839pub struct KernelSandbox {
840    /// The sandbox policy
841    policy: SandboxPolicy,
842    /// Kernel this sandbox applies to
843    kernel_id: Option<KernelId>,
844    /// Statistics
845    stats: RwLock<SandboxStats>,
846    /// Recorded violations
847    violations: RwLock<Vec<SandboxViolation>>,
848    /// Start time for execution tracking
849    start_time: RwLock<Option<Instant>>,
850    /// Message count for rate limiting
851    message_count: AtomicU64,
852    /// Last rate check time
853    last_rate_check: RwLock<Instant>,
854}
855
856impl KernelSandbox {
857    /// Create a new kernel sandbox.
858    pub fn new(policy: SandboxPolicy) -> Self {
859        Self {
860            policy,
861            kernel_id: None,
862            stats: RwLock::new(SandboxStats::default()),
863            violations: RwLock::new(Vec::new()),
864            start_time: RwLock::new(None),
865            message_count: AtomicU64::new(0),
866            last_rate_check: RwLock::new(Instant::now()),
867        }
868    }
869
870    /// Apply sandbox to a kernel.
871    pub fn apply_to_kernel(&mut self, kernel_id: KernelId) {
872        self.kernel_id = Some(kernel_id);
873        *self.start_time.write().unwrap() = Some(Instant::now());
874    }
875
876    /// Check memory usage against limits.
877    pub fn check_memory(&self, bytes: u64) -> Result<(), SandboxViolation> {
878        self.stats.write().unwrap().total_checks += 1;
879
880        if bytes > self.policy.limits.max_memory_bytes {
881            let violation = SandboxViolation {
882                violation_type: ViolationType::MemoryLimitExceeded {
883                    used: bytes,
884                    limit: self.policy.limits.max_memory_bytes,
885                },
886                kernel_id: self
887                    .kernel_id
888                    .clone()
889                    .unwrap_or_else(|| KernelId("unknown".to_string())),
890                timestamp: Instant::now(),
891                context: None,
892            };
893            self.record_violation(violation.clone());
894            return Err(violation);
895        }
896
897        self.stats.write().unwrap().current_memory_usage = bytes;
898        Ok(())
899    }
900
901    /// Check execution time against limits.
902    pub fn check_execution_time(&self) -> Result<(), SandboxViolation> {
903        self.stats.write().unwrap().total_checks += 1;
904
905        if let Some(start) = *self.start_time.read().unwrap() {
906            let elapsed = start.elapsed();
907            if elapsed > self.policy.limits.max_execution_time {
908                let violation = SandboxViolation {
909                    violation_type: ViolationType::ExecutionTimeExceeded {
910                        elapsed,
911                        limit: self.policy.limits.max_execution_time,
912                    },
913                    kernel_id: self
914                        .kernel_id
915                        .clone()
916                        .unwrap_or_else(|| KernelId("unknown".to_string())),
917                    timestamp: Instant::now(),
918                    context: None,
919                };
920                self.record_violation(violation.clone());
921                return Err(violation);
922            }
923        }
924        Ok(())
925    }
926
927    /// Check K2K destination against policy.
928    pub fn check_k2k(&self, destination: &str) -> Result<(), SandboxViolation> {
929        self.stats.write().unwrap().total_checks += 1;
930
931        if !self.policy.is_k2k_allowed(destination) {
932            let violation = SandboxViolation {
933                violation_type: ViolationType::UnauthorizedK2K {
934                    destination: destination.to_string(),
935                },
936                kernel_id: self
937                    .kernel_id
938                    .clone()
939                    .unwrap_or_else(|| KernelId("unknown".to_string())),
940                timestamp: Instant::now(),
941                context: None,
942            };
943            self.record_violation(violation.clone());
944            return Err(violation);
945        }
946        Ok(())
947    }
948
949    /// Check if checkpointing is allowed.
950    pub fn check_checkpoint(&self) -> Result<(), SandboxViolation> {
951        self.stats.write().unwrap().total_checks += 1;
952
953        if !self.policy.can_checkpoint {
954            let violation = SandboxViolation {
955                violation_type: ViolationType::CheckpointNotAllowed,
956                kernel_id: self
957                    .kernel_id
958                    .clone()
959                    .unwrap_or_else(|| KernelId("unknown".to_string())),
960                timestamp: Instant::now(),
961                context: None,
962            };
963            self.record_violation(violation.clone());
964            return Err(violation);
965        }
966        Ok(())
967    }
968
969    /// Check if migration is allowed.
970    pub fn check_migration(&self) -> Result<(), SandboxViolation> {
971        self.stats.write().unwrap().total_checks += 1;
972
973        if !self.policy.can_migrate {
974            let violation = SandboxViolation {
975                violation_type: ViolationType::MigrationNotAllowed,
976                kernel_id: self
977                    .kernel_id
978                    .clone()
979                    .unwrap_or_else(|| KernelId("unknown".to_string())),
980                timestamp: Instant::now(),
981                context: None,
982            };
983            self.record_violation(violation.clone());
984            return Err(violation);
985        }
986        Ok(())
987    }
988
989    /// Record a message for rate limiting.
990    pub fn record_message(&self) -> Result<(), SandboxViolation> {
991        self.message_count.fetch_add(1, Ordering::Relaxed);
992
993        // Check rate every second
994        let mut last_check = self.last_rate_check.write().unwrap();
995        if last_check.elapsed() >= Duration::from_secs(1) {
996            let count = self.message_count.swap(0, Ordering::Relaxed) as u32;
997            *last_check = Instant::now();
998
999            self.stats.write().unwrap().current_message_rate = count;
1000
1001            if count > self.policy.limits.max_messages_per_sec {
1002                let violation = SandboxViolation {
1003                    violation_type: ViolationType::MessageRateExceeded {
1004                        rate: count,
1005                        limit: self.policy.limits.max_messages_per_sec,
1006                    },
1007                    kernel_id: self
1008                        .kernel_id
1009                        .clone()
1010                        .unwrap_or_else(|| KernelId("unknown".to_string())),
1011                    timestamp: Instant::now(),
1012                    context: None,
1013                };
1014                self.record_violation(violation.clone());
1015                return Err(violation);
1016            }
1017        }
1018        Ok(())
1019    }
1020
1021    /// Record a violation.
1022    fn record_violation(&self, violation: SandboxViolation) {
1023        let mut stats = self.stats.write().unwrap();
1024        stats.violations_detected += 1;
1025        stats.operations_blocked += 1;
1026
1027        self.violations.write().unwrap().push(violation);
1028    }
1029
1030    /// Get all recorded violations.
1031    pub fn violations(&self) -> Vec<SandboxViolation> {
1032        self.violations.read().unwrap().clone()
1033    }
1034
1035    /// Get sandbox statistics.
1036    pub fn stats(&self) -> SandboxStats {
1037        self.stats.read().unwrap().clone()
1038    }
1039
1040    /// Get the policy.
1041    pub fn policy(&self) -> &SandboxPolicy {
1042        &self.policy
1043    }
1044
1045    /// Reset statistics and violations.
1046    pub fn reset(&self) {
1047        *self.stats.write().unwrap() = SandboxStats::default();
1048        self.violations.write().unwrap().clear();
1049        self.message_count.store(0, Ordering::Relaxed);
1050    }
1051}
1052
1053impl fmt::Debug for KernelSandbox {
1054    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1055        f.debug_struct("KernelSandbox")
1056            .field("policy", &self.policy)
1057            .field("kernel_id", &self.kernel_id)
1058            .field("stats", &self.stats())
1059            .field("violations_count", &self.violations.read().unwrap().len())
1060            .finish()
1061    }
1062}
1063
1064// ============================================================================
1065// Compliance Reports
1066// ============================================================================
1067
1068/// Compliance standard for reporting.
1069#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1070pub enum ComplianceStandard {
1071    /// SOC 2 Type II
1072    SOC2,
1073    /// GDPR (General Data Protection Regulation)
1074    GDPR,
1075    /// HIPAA (Health Insurance Portability and Accountability Act)
1076    HIPAA,
1077    /// PCI DSS (Payment Card Industry Data Security Standard)
1078    PCIDSS,
1079    /// ISO 27001
1080    ISO27001,
1081    /// FedRAMP
1082    FedRAMP,
1083    /// NIST Cybersecurity Framework
1084    NIST,
1085}
1086
1087impl fmt::Display for ComplianceStandard {
1088    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1089        match self {
1090            Self::SOC2 => write!(f, "SOC 2 Type II"),
1091            Self::GDPR => write!(f, "GDPR"),
1092            Self::HIPAA => write!(f, "HIPAA"),
1093            Self::PCIDSS => write!(f, "PCI DSS"),
1094            Self::ISO27001 => write!(f, "ISO 27001"),
1095            Self::FedRAMP => write!(f, "FedRAMP"),
1096            Self::NIST => write!(f, "NIST CSF"),
1097        }
1098    }
1099}
1100
1101/// Report output format.
1102#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
1103pub enum ReportFormat {
1104    /// JSON format
1105    #[default]
1106    Json,
1107    /// HTML format
1108    Html,
1109    /// Markdown format
1110    Markdown,
1111    /// PDF format (requires external renderer)
1112    Pdf,
1113    /// CSV format (for data export)
1114    Csv,
1115}
1116
1117/// Compliance check result.
1118#[derive(Debug, Clone)]
1119pub enum ComplianceStatus {
1120    /// Fully compliant
1121    Compliant,
1122    /// Partially compliant with notes
1123    PartiallyCompliant {
1124        /// Notes describing partial compliance
1125        notes: Vec<String>,
1126    },
1127    /// Non-compliant with reasons
1128    NonCompliant {
1129        /// Reasons for non-compliance
1130        reasons: Vec<String>,
1131    },
1132    /// Not applicable
1133    NotApplicable,
1134}
1135
1136impl ComplianceStatus {
1137    /// Check if compliant.
1138    pub fn is_compliant(&self) -> bool {
1139        matches!(self, Self::Compliant | Self::NotApplicable)
1140    }
1141}
1142
1143/// A single compliance check.
1144#[derive(Debug, Clone)]
1145pub struct ComplianceCheck {
1146    /// Check identifier
1147    pub id: String,
1148    /// Check name
1149    pub name: String,
1150    /// Standard this check belongs to
1151    pub standard: ComplianceStandard,
1152    /// Check description
1153    pub description: String,
1154    /// Check status
1155    pub status: ComplianceStatus,
1156    /// Evidence collected
1157    pub evidence: Vec<String>,
1158    /// Recommendations
1159    pub recommendations: Vec<String>,
1160    /// When the check was performed
1161    pub checked_at: SystemTime,
1162}
1163
1164/// Summary statistics for a compliance report.
1165#[derive(Debug, Clone)]
1166pub struct ComplianceSummary {
1167    /// Total checks performed
1168    pub total_checks: usize,
1169    /// Number compliant
1170    pub compliant: usize,
1171    /// Number partially compliant
1172    pub partially_compliant: usize,
1173    /// Number non-compliant
1174    pub non_compliant: usize,
1175    /// Number not applicable
1176    pub not_applicable: usize,
1177    /// Overall compliance percentage
1178    pub compliance_percentage: f64,
1179}
1180
1181/// A complete compliance report.
1182#[derive(Debug, Clone)]
1183pub struct ComplianceReport {
1184    /// Report ID
1185    pub id: String,
1186    /// Report title
1187    pub title: String,
1188    /// Standards covered
1189    pub standards: Vec<ComplianceStandard>,
1190    /// Individual checks
1191    pub checks: Vec<ComplianceCheck>,
1192    /// Summary statistics
1193    pub summary: ComplianceSummary,
1194    /// Report generation time
1195    pub generated_at: SystemTime,
1196    /// Report period start
1197    pub period_start: SystemTime,
1198    /// Report period end
1199    pub period_end: SystemTime,
1200    /// Additional metadata
1201    pub metadata: HashMap<String, String>,
1202}
1203
1204impl ComplianceReport {
1205    /// Export report to specified format.
1206    pub fn export(&self, format: ReportFormat) -> String {
1207        match format {
1208            ReportFormat::Json => self.to_json(),
1209            ReportFormat::Html => self.to_html(),
1210            ReportFormat::Markdown => self.to_markdown(),
1211            ReportFormat::Pdf => self.to_markdown(), // PDF requires external renderer
1212            ReportFormat::Csv => self.to_csv(),
1213        }
1214    }
1215
1216    fn to_json(&self) -> String {
1217        let mut json = String::new();
1218        json.push_str("{\n");
1219        json.push_str(&format!("  \"id\": \"{}\",\n", self.id));
1220        json.push_str(&format!("  \"title\": \"{}\",\n", self.title));
1221        json.push_str(&format!(
1222            "  \"standards\": [{}],\n",
1223            self.standards
1224                .iter()
1225                .map(|s| format!("\"{}\"", s))
1226                .collect::<Vec<_>>()
1227                .join(", ")
1228        ));
1229        json.push_str("  \"summary\": {\n");
1230        json.push_str(&format!(
1231            "    \"total_checks\": {},\n",
1232            self.summary.total_checks
1233        ));
1234        json.push_str(&format!("    \"compliant\": {},\n", self.summary.compliant));
1235        json.push_str(&format!(
1236            "    \"partially_compliant\": {},\n",
1237            self.summary.partially_compliant
1238        ));
1239        json.push_str(&format!(
1240            "    \"non_compliant\": {},\n",
1241            self.summary.non_compliant
1242        ));
1243        json.push_str(&format!(
1244            "    \"compliance_percentage\": {:.1}\n",
1245            self.summary.compliance_percentage
1246        ));
1247        json.push_str("  },\n");
1248        json.push_str(&format!("  \"checks_count\": {}\n", self.checks.len()));
1249        json.push_str("}\n");
1250        json
1251    }
1252
1253    fn to_html(&self) -> String {
1254        let mut html = String::new();
1255        html.push_str("<!DOCTYPE html>\n<html>\n<head>\n");
1256        html.push_str(&format!("<title>{}</title>\n", self.title));
1257        html.push_str("<style>body { font-family: sans-serif; } .compliant { color: green; } .non-compliant { color: red; }</style>\n");
1258        html.push_str("</head>\n<body>\n");
1259        html.push_str(&format!("<h1>{}</h1>\n", self.title));
1260        html.push_str(&format!("<p>Report ID: {}</p>\n", self.id));
1261        html.push_str("<h2>Summary</h2>\n");
1262        html.push_str("<table>\n");
1263        html.push_str(&format!(
1264            "<tr><td>Total Checks</td><td>{}</td></tr>\n",
1265            self.summary.total_checks
1266        ));
1267        html.push_str(&format!(
1268            "<tr><td>Compliant</td><td class=\"compliant\">{}</td></tr>\n",
1269            self.summary.compliant
1270        ));
1271        html.push_str(&format!(
1272            "<tr><td>Non-Compliant</td><td class=\"non-compliant\">{}</td></tr>\n",
1273            self.summary.non_compliant
1274        ));
1275        html.push_str(&format!(
1276            "<tr><td>Compliance</td><td>{:.1}%</td></tr>\n",
1277            self.summary.compliance_percentage
1278        ));
1279        html.push_str("</table>\n");
1280        html.push_str("<h2>Checks</h2>\n");
1281        for check in &self.checks {
1282            html.push_str(&format!("<h3>{}</h3>\n", check.name));
1283            html.push_str(&format!("<p>{}</p>\n", check.description));
1284        }
1285        html.push_str("</body>\n</html>\n");
1286        html
1287    }
1288
1289    fn to_markdown(&self) -> String {
1290        let mut md = String::new();
1291        md.push_str(&format!("# {}\n\n", self.title));
1292        md.push_str(&format!("**Report ID:** {}\n\n", self.id));
1293        md.push_str("## Summary\n\n");
1294        md.push_str("| Metric | Value |\n");
1295        md.push_str("|--------|-------|\n");
1296        md.push_str(&format!(
1297            "| Total Checks | {} |\n",
1298            self.summary.total_checks
1299        ));
1300        md.push_str(&format!("| Compliant | {} |\n", self.summary.compliant));
1301        md.push_str(&format!(
1302            "| Partially Compliant | {} |\n",
1303            self.summary.partially_compliant
1304        ));
1305        md.push_str(&format!(
1306            "| Non-Compliant | {} |\n",
1307            self.summary.non_compliant
1308        ));
1309        md.push_str(&format!(
1310            "| Compliance | {:.1}% |\n",
1311            self.summary.compliance_percentage
1312        ));
1313        md.push_str("\n## Detailed Checks\n\n");
1314        for check in &self.checks {
1315            let status_icon = match &check.status {
1316                ComplianceStatus::Compliant => "✅",
1317                ComplianceStatus::PartiallyCompliant { .. } => "⚠️",
1318                ComplianceStatus::NonCompliant { .. } => "❌",
1319                ComplianceStatus::NotApplicable => "➖",
1320            };
1321            md.push_str(&format!("### {} {}\n\n", status_icon, check.name));
1322            md.push_str(&format!("{}\n\n", check.description));
1323        }
1324        md
1325    }
1326
1327    fn to_csv(&self) -> String {
1328        let mut csv = String::new();
1329        csv.push_str("ID,Name,Standard,Status,Description\n");
1330        for check in &self.checks {
1331            let status = match &check.status {
1332                ComplianceStatus::Compliant => "Compliant",
1333                ComplianceStatus::PartiallyCompliant { .. } => "Partially Compliant",
1334                ComplianceStatus::NonCompliant { .. } => "Non-Compliant",
1335                ComplianceStatus::NotApplicable => "N/A",
1336            };
1337            csv.push_str(&format!(
1338                "\"{}\",\"{}\",\"{}\",\"{}\",\"{}\"\n",
1339                check.id, check.name, check.standard, status, check.description
1340            ));
1341        }
1342        csv
1343    }
1344}
1345
1346/// Compliance reporter for generating compliance documentation.
1347pub struct ComplianceReporter {
1348    /// Standards to report on
1349    standards: HashSet<ComplianceStandard>,
1350    /// Organization name
1351    organization: String,
1352    /// Report metadata
1353    metadata: HashMap<String, String>,
1354    /// Custom checks
1355    custom_checks: Vec<Box<dyn Fn() -> ComplianceCheck + Send + Sync>>,
1356}
1357
1358impl ComplianceReporter {
1359    /// Create a new compliance reporter.
1360    pub fn new() -> Self {
1361        Self {
1362            standards: HashSet::new(),
1363            organization: "Unknown".to_string(),
1364            metadata: HashMap::new(),
1365            custom_checks: Vec::new(),
1366        }
1367    }
1368
1369    /// Add a compliance standard.
1370    pub fn with_standard(mut self, standard: ComplianceStandard) -> Self {
1371        self.standards.insert(standard);
1372        self
1373    }
1374
1375    /// Set organization name.
1376    pub fn with_organization(mut self, org: &str) -> Self {
1377        self.organization = org.to_string();
1378        self
1379    }
1380
1381    /// Add metadata.
1382    pub fn with_metadata(mut self, key: &str, value: &str) -> Self {
1383        self.metadata.insert(key.to_string(), value.to_string());
1384        self
1385    }
1386
1387    /// Generate a compliance report.
1388    pub fn generate_report(&self, _format: ReportFormat) -> ComplianceReport {
1389        let mut checks = Vec::new();
1390        let now = SystemTime::now();
1391
1392        // Generate checks for each standard
1393        for standard in &self.standards {
1394            checks.extend(self.generate_standard_checks(*standard));
1395        }
1396
1397        // Run custom checks
1398        for check_fn in &self.custom_checks {
1399            checks.push(check_fn());
1400        }
1401
1402        // Calculate summary
1403        let total = checks.len();
1404        let compliant = checks
1405            .iter()
1406            .filter(|c| matches!(c.status, ComplianceStatus::Compliant))
1407            .count();
1408        let partial = checks
1409            .iter()
1410            .filter(|c| matches!(c.status, ComplianceStatus::PartiallyCompliant { .. }))
1411            .count();
1412        let non_compliant = checks
1413            .iter()
1414            .filter(|c| matches!(c.status, ComplianceStatus::NonCompliant { .. }))
1415            .count();
1416        let na = checks
1417            .iter()
1418            .filter(|c| matches!(c.status, ComplianceStatus::NotApplicable))
1419            .count();
1420
1421        let applicable = total - na;
1422        let compliance_pct = if applicable > 0 {
1423            ((compliant as f64 + partial as f64 * 0.5) / applicable as f64) * 100.0
1424        } else {
1425            100.0
1426        };
1427
1428        ComplianceReport {
1429            id: format!(
1430                "RPT-{}",
1431                now.duration_since(SystemTime::UNIX_EPOCH)
1432                    .unwrap()
1433                    .as_secs()
1434            ),
1435            title: format!("{} Compliance Report", self.organization),
1436            standards: self.standards.iter().copied().collect(),
1437            checks,
1438            summary: ComplianceSummary {
1439                total_checks: total,
1440                compliant,
1441                partially_compliant: partial,
1442                non_compliant,
1443                not_applicable: na,
1444                compliance_percentage: compliance_pct,
1445            },
1446            generated_at: now,
1447            period_start: now - Duration::from_secs(30 * 24 * 60 * 60), // 30 days ago
1448            period_end: now,
1449            metadata: self.metadata.clone(),
1450        }
1451    }
1452
1453    fn generate_standard_checks(&self, standard: ComplianceStandard) -> Vec<ComplianceCheck> {
1454        let now = SystemTime::now();
1455
1456        match standard {
1457            ComplianceStandard::SOC2 => vec![
1458                ComplianceCheck {
1459                    id: "SOC2-CC1.1".to_string(),
1460                    name: "Control Environment".to_string(),
1461                    standard,
1462                    description:
1463                        "The entity demonstrates commitment to integrity and ethical values."
1464                            .to_string(),
1465                    status: ComplianceStatus::Compliant,
1466                    evidence: vec![
1467                        "Audit logging enabled".to_string(),
1468                        "Access controls implemented".to_string(),
1469                    ],
1470                    recommendations: vec![],
1471                    checked_at: now,
1472                },
1473                ComplianceCheck {
1474                    id: "SOC2-CC6.1".to_string(),
1475                    name: "Logical Access Controls".to_string(),
1476                    standard,
1477                    description:
1478                        "Logical access security software, infrastructure, and architectures."
1479                            .to_string(),
1480                    status: ComplianceStatus::Compliant,
1481                    evidence: vec![
1482                        "Kernel sandboxing available".to_string(),
1483                        "Memory encryption available".to_string(),
1484                    ],
1485                    recommendations: vec![],
1486                    checked_at: now,
1487                },
1488                ComplianceCheck {
1489                    id: "SOC2-CC7.2".to_string(),
1490                    name: "System Monitoring".to_string(),
1491                    standard,
1492                    description: "System components are monitored and anomalies are identified."
1493                        .to_string(),
1494                    status: ComplianceStatus::Compliant,
1495                    evidence: vec![
1496                        "Health monitoring enabled".to_string(),
1497                        "GPU memory dashboard available".to_string(),
1498                    ],
1499                    recommendations: vec![],
1500                    checked_at: now,
1501                },
1502            ],
1503            ComplianceStandard::GDPR => vec![
1504                ComplianceCheck {
1505                    id: "GDPR-32".to_string(),
1506                    name: "Security of Processing".to_string(),
1507                    standard,
1508                    description: "Implement appropriate technical and organizational measures."
1509                        .to_string(),
1510                    status: ComplianceStatus::Compliant,
1511                    evidence: vec!["Memory encryption available".to_string()],
1512                    recommendations: vec!["Consider enabling encryption by default".to_string()],
1513                    checked_at: now,
1514                },
1515                ComplianceCheck {
1516                    id: "GDPR-33".to_string(),
1517                    name: "Breach Notification".to_string(),
1518                    standard,
1519                    description: "Notify supervisory authority of personal data breach."
1520                        .to_string(),
1521                    status: ComplianceStatus::PartiallyCompliant {
1522                        notes: vec!["Audit logging available but breach detection not automated"
1523                            .to_string()],
1524                    },
1525                    evidence: vec!["Audit logging enabled".to_string()],
1526                    recommendations: vec!["Add automated breach detection".to_string()],
1527                    checked_at: now,
1528                },
1529            ],
1530            ComplianceStandard::HIPAA => vec![
1531                ComplianceCheck {
1532                    id: "HIPAA-164.312(a)".to_string(),
1533                    name: "Access Control".to_string(),
1534                    standard,
1535                    description: "Implement technical policies for electronic PHI access."
1536                        .to_string(),
1537                    status: ComplianceStatus::Compliant,
1538                    evidence: vec![
1539                        "Kernel sandboxing available".to_string(),
1540                        "Access levels configurable".to_string(),
1541                    ],
1542                    recommendations: vec![],
1543                    checked_at: now,
1544                },
1545                ComplianceCheck {
1546                    id: "HIPAA-164.312(e)".to_string(),
1547                    name: "Transmission Security".to_string(),
1548                    standard,
1549                    description: "Implement security measures for ePHI transmission.".to_string(),
1550                    status: ComplianceStatus::Compliant,
1551                    evidence: vec!["Memory encryption for data at rest".to_string()],
1552                    recommendations: vec!["Implement TLS for network K2K".to_string()],
1553                    checked_at: now,
1554                },
1555            ],
1556            ComplianceStandard::PCIDSS => vec![
1557                ComplianceCheck {
1558                    id: "PCI-3.4".to_string(),
1559                    name: "Render PAN Unreadable".to_string(),
1560                    standard,
1561                    description: "Render PAN unreadable anywhere it is stored.".to_string(),
1562                    status: ComplianceStatus::Compliant,
1563                    evidence: vec!["AES-256-GCM encryption available".to_string()],
1564                    recommendations: vec![],
1565                    checked_at: now,
1566                },
1567                ComplianceCheck {
1568                    id: "PCI-10.1".to_string(),
1569                    name: "Audit Trails".to_string(),
1570                    standard,
1571                    description: "Implement audit trails to link access to individual users."
1572                        .to_string(),
1573                    status: ComplianceStatus::Compliant,
1574                    evidence: vec!["Comprehensive audit logging".to_string()],
1575                    recommendations: vec![],
1576                    checked_at: now,
1577                },
1578            ],
1579            ComplianceStandard::ISO27001 => vec![ComplianceCheck {
1580                id: "ISO-A.10.1".to_string(),
1581                name: "Cryptographic Controls".to_string(),
1582                standard,
1583                description: "Policy on use of cryptographic controls.".to_string(),
1584                status: ComplianceStatus::Compliant,
1585                evidence: vec!["Multiple encryption algorithms supported".to_string()],
1586                recommendations: vec![],
1587                checked_at: now,
1588            }],
1589            ComplianceStandard::FedRAMP => vec![ComplianceCheck {
1590                id: "FedRAMP-SC-28".to_string(),
1591                name: "Protection of Information at Rest".to_string(),
1592                standard,
1593                description: "Protect confidentiality and integrity of information at rest."
1594                    .to_string(),
1595                status: ComplianceStatus::Compliant,
1596                evidence: vec!["FIPS-compliant algorithms available".to_string()],
1597                recommendations: vec![],
1598                checked_at: now,
1599            }],
1600            ComplianceStandard::NIST => vec![
1601                ComplianceCheck {
1602                    id: "NIST-PR.DS-1".to_string(),
1603                    name: "Data-at-rest Protection".to_string(),
1604                    standard,
1605                    description: "Data-at-rest is protected.".to_string(),
1606                    status: ComplianceStatus::Compliant,
1607                    evidence: vec!["Memory encryption module".to_string()],
1608                    recommendations: vec![],
1609                    checked_at: now,
1610                },
1611                ComplianceCheck {
1612                    id: "NIST-DE.CM-1".to_string(),
1613                    name: "Network Monitoring".to_string(),
1614                    standard,
1615                    description: "The network is monitored to detect cybersecurity events."
1616                        .to_string(),
1617                    status: ComplianceStatus::Compliant,
1618                    evidence: vec![
1619                        "Observability context".to_string(),
1620                        "GPU profiler integration".to_string(),
1621                    ],
1622                    recommendations: vec![],
1623                    checked_at: now,
1624                },
1625            ],
1626        }
1627    }
1628}
1629
1630impl Default for ComplianceReporter {
1631    fn default() -> Self {
1632        Self::new()
1633    }
1634}
1635
1636impl fmt::Debug for ComplianceReporter {
1637    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1638        f.debug_struct("ComplianceReporter")
1639            .field("standards", &self.standards)
1640            .field("organization", &self.organization)
1641            .field("metadata", &self.metadata)
1642            .field("custom_checks_count", &self.custom_checks.len())
1643            .finish()
1644    }
1645}
1646
1647// ============================================================================
1648// Tests
1649// ============================================================================
1650
1651#[cfg(test)]
1652mod tests {
1653    use super::*;
1654
1655    // Memory Encryption Tests
1656
1657    #[test]
1658    fn test_encryption_config_builder() {
1659        let config = EncryptionConfig::new()
1660            .with_algorithm(EncryptionAlgorithm::ChaCha20Poly1305)
1661            .with_key_rotation_interval(Duration::from_secs(7200))
1662            .with_control_block_encryption(false);
1663
1664        assert_eq!(config.algorithm, EncryptionAlgorithm::ChaCha20Poly1305);
1665        assert_eq!(config.key_rotation_interval, Duration::from_secs(7200));
1666        assert!(!config.encrypt_control_blocks);
1667    }
1668
1669    #[test]
1670    fn test_encryption_key_creation() {
1671        let key = EncryptionKey::new(1, EncryptionAlgorithm::Aes256Gcm);
1672        assert_eq!(key.key_id, 1);
1673        assert_eq!(key.key_size(), 32);
1674        assert!(!key.is_expired());
1675    }
1676
1677    #[test]
1678    fn test_encrypt_decrypt_roundtrip() {
1679        let encryption = MemoryEncryption::new(EncryptionConfig::default());
1680        let plaintext = b"Hello, GPU World!";
1681
1682        let encrypted = encryption.encrypt_region(plaintext);
1683        assert_ne!(encrypted.ciphertext[..plaintext.len()], plaintext[..]);
1684
1685        let decrypted = encryption.decrypt_region(&encrypted).unwrap();
1686        assert_eq!(decrypted, plaintext);
1687    }
1688
1689    #[test]
1690    fn test_key_rotation() {
1691        let encryption = MemoryEncryption::new(EncryptionConfig::default());
1692        let initial_key_id = encryption.current_key_id();
1693
1694        encryption.rotate_keys();
1695        assert_eq!(encryption.current_key_id(), initial_key_id + 1);
1696
1697        // Stats should reflect rotation
1698        let stats = encryption.stats();
1699        assert_eq!(stats.key_rotations, 1);
1700    }
1701
1702    #[test]
1703    fn test_decrypt_with_old_key() {
1704        let encryption = MemoryEncryption::new(EncryptionConfig::default());
1705        let plaintext = b"Secret data";
1706
1707        let encrypted = encryption.encrypt_region(plaintext);
1708        let old_key_id = encrypted.key_id;
1709
1710        // Rotate key
1711        encryption.rotate_keys();
1712        assert_ne!(encryption.current_key_id(), old_key_id);
1713
1714        // Should still decrypt with old key
1715        let decrypted = encryption.decrypt_region(&encrypted).unwrap();
1716        assert_eq!(decrypted, plaintext);
1717    }
1718
1719    #[test]
1720    fn test_encryption_stats() {
1721        let encryption = MemoryEncryption::new(EncryptionConfig::default());
1722        let data = vec![0u8; 1024];
1723
1724        for _ in 0..10 {
1725            let encrypted = encryption.encrypt_region(&data);
1726            let _ = encryption.decrypt_region(&encrypted);
1727        }
1728
1729        let stats = encryption.stats();
1730        assert_eq!(stats.encrypt_ops, 10);
1731        assert_eq!(stats.decrypt_ops, 10);
1732        assert_eq!(stats.bytes_encrypted, 10240);
1733    }
1734
1735    // Kernel Sandboxing Tests
1736
1737    #[test]
1738    fn test_resource_limits_builder() {
1739        let limits = ResourceLimits::new()
1740            .with_max_memory(512 * 1024 * 1024)
1741            .with_max_execution_time(Duration::from_secs(30));
1742
1743        assert_eq!(limits.max_memory_bytes, 512 * 1024 * 1024);
1744        assert_eq!(limits.max_execution_time, Duration::from_secs(30));
1745    }
1746
1747    #[test]
1748    fn test_sandbox_policy_k2k() {
1749        let policy = SandboxPolicy::new()
1750            .allow_k2k_to(&["trusted_kernel", "another_trusted"])
1751            .deny_k2k_to(&["malicious_kernel"]);
1752
1753        assert!(policy.is_k2k_allowed("trusted_kernel"));
1754        assert!(policy.is_k2k_allowed("another_trusted"));
1755        assert!(!policy.is_k2k_allowed("malicious_kernel"));
1756        assert!(!policy.is_k2k_allowed("unknown_kernel")); // Not in allowed list
1757    }
1758
1759    #[test]
1760    fn test_sandbox_memory_check() {
1761        let policy = SandboxPolicy::new().with_memory_limit(1024);
1762        let sandbox = KernelSandbox::new(policy);
1763
1764        // Should pass
1765        assert!(sandbox.check_memory(512).is_ok());
1766
1767        // Should fail
1768        let result = sandbox.check_memory(2048);
1769        assert!(result.is_err());
1770
1771        if let Err(violation) = result {
1772            assert!(matches!(
1773                violation.violation_type,
1774                ViolationType::MemoryLimitExceeded { .. }
1775            ));
1776        }
1777    }
1778
1779    #[test]
1780    fn test_sandbox_k2k_check() {
1781        let policy = SandboxPolicy::new().deny_k2k_to(&["blocked"]);
1782        let sandbox = KernelSandbox::new(policy);
1783
1784        assert!(sandbox.check_k2k("allowed_dest").is_ok());
1785        assert!(sandbox.check_k2k("blocked").is_err());
1786    }
1787
1788    #[test]
1789    fn test_sandbox_checkpoint_check() {
1790        let policy = SandboxPolicy::restrictive();
1791        let sandbox = KernelSandbox::new(policy);
1792
1793        assert!(sandbox.check_checkpoint().is_err());
1794
1795        let permissive = SandboxPolicy::permissive();
1796        let sandbox2 = KernelSandbox::new(permissive);
1797        assert!(sandbox2.check_checkpoint().is_ok());
1798    }
1799
1800    #[test]
1801    fn test_sandbox_stats() {
1802        let policy = SandboxPolicy::new().with_memory_limit(1024);
1803        let sandbox = KernelSandbox::new(policy);
1804
1805        let _ = sandbox.check_memory(512);
1806        let _ = sandbox.check_memory(2048); // Violation
1807        let _ = sandbox.check_k2k("dest");
1808
1809        let stats = sandbox.stats();
1810        assert_eq!(stats.total_checks, 3);
1811        assert_eq!(stats.violations_detected, 1);
1812    }
1813
1814    #[test]
1815    fn test_sandbox_violations_list() {
1816        let policy = SandboxPolicy::restrictive();
1817        let sandbox = KernelSandbox::new(policy);
1818
1819        let _ = sandbox.check_checkpoint();
1820        let _ = sandbox.check_migration();
1821
1822        let violations = sandbox.violations();
1823        assert_eq!(violations.len(), 2);
1824    }
1825
1826    // Compliance Reports Tests
1827
1828    #[test]
1829    fn test_compliance_reporter_creation() {
1830        let reporter = ComplianceReporter::new()
1831            .with_standard(ComplianceStandard::SOC2)
1832            .with_standard(ComplianceStandard::GDPR)
1833            .with_organization("Test Org");
1834
1835        assert_eq!(reporter.standards.len(), 2);
1836        assert!(reporter.standards.contains(&ComplianceStandard::SOC2));
1837        assert!(reporter.standards.contains(&ComplianceStandard::GDPR));
1838    }
1839
1840    #[test]
1841    fn test_generate_soc2_report() {
1842        let reporter = ComplianceReporter::new()
1843            .with_standard(ComplianceStandard::SOC2)
1844            .with_organization("Acme Corp");
1845
1846        let report = reporter.generate_report(ReportFormat::Json);
1847
1848        assert!(!report.checks.is_empty());
1849        assert!(report.summary.total_checks > 0);
1850        assert!(report.title.contains("Acme Corp"));
1851    }
1852
1853    #[test]
1854    fn test_report_json_export() {
1855        let reporter = ComplianceReporter::new().with_standard(ComplianceStandard::HIPAA);
1856
1857        let report = reporter.generate_report(ReportFormat::Json);
1858        let json = report.export(ReportFormat::Json);
1859
1860        assert!(json.contains("\"id\""));
1861        assert!(json.contains("\"summary\""));
1862    }
1863
1864    #[test]
1865    fn test_report_markdown_export() {
1866        let reporter = ComplianceReporter::new().with_standard(ComplianceStandard::NIST);
1867
1868        let report = reporter.generate_report(ReportFormat::Markdown);
1869        let md = report.export(ReportFormat::Markdown);
1870
1871        assert!(md.contains("# "));
1872        assert!(md.contains("## Summary"));
1873        assert!(md.contains("| Metric | Value |"));
1874    }
1875
1876    #[test]
1877    fn test_report_html_export() {
1878        let reporter = ComplianceReporter::new().with_standard(ComplianceStandard::PCIDSS);
1879
1880        let report = reporter.generate_report(ReportFormat::Html);
1881        let html = report.export(ReportFormat::Html);
1882
1883        assert!(html.contains("<!DOCTYPE html>"));
1884        assert!(html.contains("<h1>"));
1885    }
1886
1887    #[test]
1888    fn test_report_csv_export() {
1889        let reporter = ComplianceReporter::new().with_standard(ComplianceStandard::ISO27001);
1890
1891        let report = reporter.generate_report(ReportFormat::Csv);
1892        let csv = report.export(ReportFormat::Csv);
1893
1894        assert!(csv.contains("ID,Name,Standard,Status,Description"));
1895    }
1896
1897    #[test]
1898    fn test_compliance_summary_calculation() {
1899        let reporter = ComplianceReporter::new()
1900            .with_standard(ComplianceStandard::SOC2)
1901            .with_standard(ComplianceStandard::GDPR)
1902            .with_standard(ComplianceStandard::HIPAA);
1903
1904        let report = reporter.generate_report(ReportFormat::Json);
1905
1906        let sum = report.summary.compliant
1907            + report.summary.partially_compliant
1908            + report.summary.non_compliant
1909            + report.summary.not_applicable;
1910        assert_eq!(sum, report.summary.total_checks);
1911    }
1912
1913    #[test]
1914    fn test_compliance_status_is_compliant() {
1915        assert!(ComplianceStatus::Compliant.is_compliant());
1916        assert!(ComplianceStatus::NotApplicable.is_compliant());
1917        assert!(!ComplianceStatus::NonCompliant { reasons: vec![] }.is_compliant());
1918        assert!(!ComplianceStatus::PartiallyCompliant { notes: vec![] }.is_compliant());
1919    }
1920
1921    #[test]
1922    fn test_all_standards() {
1923        let reporter = ComplianceReporter::new()
1924            .with_standard(ComplianceStandard::SOC2)
1925            .with_standard(ComplianceStandard::GDPR)
1926            .with_standard(ComplianceStandard::HIPAA)
1927            .with_standard(ComplianceStandard::PCIDSS)
1928            .with_standard(ComplianceStandard::ISO27001)
1929            .with_standard(ComplianceStandard::FedRAMP)
1930            .with_standard(ComplianceStandard::NIST);
1931
1932        let report = reporter.generate_report(ReportFormat::Json);
1933        assert_eq!(report.standards.len(), 7);
1934    }
1935}