clock_curve_math/ct/
hardware.rs

1//! Hardware-specific side-channel countermeasures.
2//!
3//! This module implements countermeasures against hardware-level side-channel
4//! attacks including cache timing, branch prediction, power analysis, and
5//! electromagnetic analysis.
6//!
7//! # Countermeasures Implemented
8//!
9//! ## Cache Timing Protection
10//! - Memory access pattern normalization
11//! - Cache line flushing for sensitive operations
12//! - Data-independent memory access patterns
13//!
14//! ## Branch Prediction Protection
15//! - Branch-free implementations using ct_select
16//! - Constant-time conditional operations
17//!
18//! ## Power Analysis Protection
19//! - Hamming weight normalization
20//! - Operation balancing
21//! - Dummy operations for timing alignment
22//!
23//! ## Electromagnetic Analysis Protection
24//! - Signal balancing
25//! - Operation randomization
26//!
27//! # Safety Considerations
28//!
29//! This module uses `unsafe` blocks for hardware-specific operations that are
30//! necessary for side-channel attack prevention. All unsafe operations are:
31//!
32//! 1. **Cache Management**: CLFLUSH, DC CIVAC instructions that only affect cache coherency
33//! 2. **Memory Barriers**: DSB, ISB instructions for execution ordering
34//! 3. **Inline Assembly**: Well-defined ARM/x86 instructions with proper constraints
35//!
36//! ## Safety Guarantees
37//!
38//! - **No Memory Corruption**: Unsafe operations only affect cache state, not memory contents
39//! - **No Undefined Behavior**: All instructions are well-defined in their respective architectures
40//! - **Proper Bounds Checking**: Memory operations are performed on stack-allocated buffers
41//! - **Architecture-Specific**: Operations are gated behind feature flags and target checks
42//! - **Fallback Behavior**: Safe alternatives provided when hardware operations unavailable
43//!
44//! # Usage
45//!
46//! ```ignore
47//! use clock_curve_math::ct::hardware::*;
48//!
49//! // Protect a sensitive operation
50//! let result = with_hardware_countermeasures(|| {
51//!     some_cryptographic_operation(secret_data)
52//! });
53//! ```
54
55use core::sync::atomic::{AtomicBool, Ordering};
56
57/// Global flag to enable/disable hardware countermeasures.
58/// This can be controlled at runtime for performance tuning.
59static HARDWARE_COUNTERMEASURES_ENABLED: AtomicBool = AtomicBool::new(true);
60
61#[cfg(test)]
62static TEST_LOCK: AtomicBool = AtomicBool::new(false);
63
64#[cfg(test)]
65fn acquire_test_lock() {
66    while TEST_LOCK.swap(true, Ordering::AcqRel) {
67        // Spin until we acquire the lock
68        core::hint::spin_loop();
69    }
70}
71
72#[cfg(test)]
73fn release_test_lock() {
74    TEST_LOCK.store(false, Ordering::Release);
75}
76
77/// Configuration for hardware-level side-channel countermeasures.
78///
79/// This struct allows fine-grained control over which hardware security
80/// countermeasures are applied. Different attack vectors may require
81/// different combinations of protections, and this configuration enables
82/// performance tuning by selectively enabling countermeasures.
83///
84/// # Fields
85/// - `cache_protection`: Protects against cache timing attacks via memory access normalization
86/// - `power_protection`: Protects against power analysis via consumption balancing
87/// - `em_protection`: Protects against electromagnetic analysis via signal balancing
88/// - `dummy_operations`: Number of additional operations for timing/power balancing
89///
90/// # Security vs Performance Trade-offs
91/// - **Cache Protection**: Moderate performance impact, essential for shared systems
92/// - **Power Protection**: Low performance impact, critical for embedded systems
93/// - **EM Protection**: Higher performance impact, mainly for high-security environments
94///
95/// # Default Configuration
96/// The default configuration enables cache and power protection but disables
97/// EM protection due to its higher performance cost. EM protection can be
98/// enabled when operating in high-threat environments.
99///
100/// # Usage
101/// ```ignore
102/// use clock_curve_math::ct::hardware::HardwareSecurityConfig;
103///
104/// let config = HardwareSecurityConfig {
105///     cache_protection: true,
106///     power_protection: true,
107///     em_protection: false, // Too expensive for most applications
108///     dummy_operations: 5,  // Minimal balancing operations
109/// };
110/// ```
111#[derive(Debug, Clone)]
112pub struct HardwareSecurityConfig {
113    /// Enable cache timing countermeasures.
114    ///
115    /// When enabled, memory access patterns are normalized and cache lines
116    /// are flushed before/after operations to prevent cache timing attacks.
117    pub cache_protection: bool,
118
119    /// Enable power analysis countermeasures.
120    ///
121    /// When enabled, dummy operations are performed to balance power consumption
122    /// and prevent power analysis attacks that analyze current draw patterns.
123    pub power_protection: bool,
124
125    /// Enable electromagnetic countermeasures.
126    ///
127    /// When enabled, operations are balanced to prevent electromagnetic analysis
128    /// attacks that analyze electromagnetic emissions from the processor.
129    pub em_protection: bool,
130
131    /// Number of dummy operations for balancing.
132    ///
133    /// Controls how many additional dummy operations are performed for timing
134    /// and power balancing. Higher values provide better protection but impact
135    /// performance. Typical values range from 5-20 depending on security needs.
136    pub dummy_operations: usize,
137}
138
139impl Default for HardwareSecurityConfig {
140    /// Creates a default hardware security configuration.
141    ///
142    /// The default configuration provides a good balance between security
143    /// and performance for most cryptographic applications. It enables
144    /// the most critical countermeasures while keeping performance impact
145    /// reasonable.
146    ///
147    /// # Default Settings
148    /// - `cache_protection: true` - Essential for shared computing environments
149    /// - `power_protection: true` - Important for embedded and IoT devices
150    /// - `em_protection: false` - Disabled due to performance cost; enable for high-security
151    /// - `dummy_operations: 10` - Moderate balancing operations
152    ///
153    /// # Usage
154    /// ```ignore
155    /// use clock_curve_math::ct::hardware::HardwareSecurityConfig;
156    ///
157    /// // Use default configuration (recommended for most applications)
158    /// let config = HardwareSecurityConfig::default();
159    ///
160    /// // Or customize specific settings
161    /// let custom_config = HardwareSecurityConfig {
162    ///     em_protection: true, // Enable for high-security environments
163    ///     ..HardwareSecurityConfig::default()
164    /// };
165    /// ```
166    fn default() -> Self {
167        Self {
168            cache_protection: true,
169            power_protection: true,
170            em_protection: false, // Disabled by default for performance
171            dummy_operations: 10,
172        }
173    }
174}
175
176/// Execute a function with comprehensive hardware countermeasures applied.
177///
178/// This is the primary function for protecting cryptographic operations against
179/// hardware-level side-channel attacks. It applies a default set of countermeasures
180/// including cache timing protection, power analysis protection, and optionally
181/// electromagnetic protection.
182///
183/// # Protection Applied
184/// - **Cache Timing**: Memory access normalization and cache line management
185/// - **Power Analysis**: Power consumption balancing with dummy operations
186/// - **Electromagnetic**: Signal balancing (if enabled in default config)
187///
188/// # Performance Impact
189/// Moderate performance overhead due to pre/post-operation countermeasures.
190/// The exact impact depends on the operation being protected and hardware platform.
191///
192/// # Usage
193/// ```ignore
194/// use clock_curve_math::ct::hardware::with_hardware_countermeasures;
195///
196/// let result = with_hardware_countermeasures(|| {
197///     // Perform sensitive cryptographic operation here
198///     my_secret_computation(secret_key, data)
199/// });
200/// ```
201///
202/// # Thread Safety
203/// This function is safe to call from multiple threads, but countermeasures
204/// are applied per-invocation and do not provide cross-thread protection.
205///
206/// # When to Use
207/// Use this function for any cryptographic operation that handles sensitive data
208/// and could be vulnerable to hardware side-channel attacks.
209pub fn with_hardware_countermeasures<F, R>(f: F) -> R
210where
211    F: FnOnce() -> R,
212{
213    if !is_hardware_countermeasures_enabled() {
214        return f();
215    }
216
217    let config = HardwareSecurityConfig::default();
218
219    // Pre-operation countermeasures
220    pre_operation_countermeasures(&config);
221
222    // Execute the protected operation
223    let result = f();
224
225    // Post-operation countermeasures
226    post_operation_countermeasures(&config);
227
228    result
229}
230
231/// Execute a function with custom-configured hardware countermeasures.
232///
233/// This function provides fine-grained control over which countermeasures are applied,
234/// allowing applications to balance security requirements with performance constraints.
235/// Use this when the default configuration is not suitable for your use case.
236///
237/// # Parameters
238/// * `config` - Hardware security configuration specifying which countermeasures to apply
239/// * `f` - The function to execute with protection
240///
241/// # Performance Tuning
242/// Disable countermeasures that are not needed for your threat model:
243/// ```ignore
244/// use clock_curve_math::ct::hardware::{HardwareSecurityConfig, with_custom_hardware_countermeasures};
245///
246/// // High-performance configuration for trusted environments
247/// let fast_config = HardwareSecurityConfig {
248///     cache_protection: true,    // Still important on shared systems
249///     power_protection: false,   // Disable for performance
250///     em_protection: false,      // Disable for performance
251///     dummy_operations: 0,       // No dummy operations
252/// };
253///
254/// let result = with_custom_hardware_countermeasures(&fast_config, || {
255///     my_crypto_operation()
256/// });
257/// ```
258///
259/// # Security Considerations
260/// Only disable countermeasures if you are certain they are not needed for
261/// your deployment environment. Consult security experts for high-value systems.
262pub fn with_custom_hardware_countermeasures<F, R>(config: &HardwareSecurityConfig, f: F) -> R
263where
264    F: FnOnce() -> R,
265{
266    if !config.cache_protection && !config.power_protection && !config.em_protection {
267        return f();
268    }
269
270    // Pre-operation countermeasures
271    pre_operation_countermeasures(config);
272
273    // Execute the protected operation
274    let result = f();
275
276    // Post-operation countermeasures
277    post_operation_countermeasures(config);
278
279    result
280}
281
282/// Check if hardware countermeasures are globally enabled.
283///
284/// Returns the current state of the global hardware countermeasures flag.
285/// When disabled, protection functions like `with_hardware_countermeasures`
286/// will skip applying countermeasures for performance.
287///
288/// # Returns
289/// `true` if hardware countermeasures are enabled, `false` if disabled
290///
291/// # Thread Safety
292/// This function uses atomic operations and is safe to call from multiple threads.
293///
294/// # Use Cases
295/// - Performance benchmarking without security overhead
296/// - Debugging cryptographic operations
297/// - Conditional protection based on runtime environment
298pub fn is_hardware_countermeasures_enabled() -> bool {
299    HARDWARE_COUNTERMEASURES_ENABLED.load(Ordering::Relaxed)
300}
301
302/// Enable or disable hardware countermeasures globally.
303///
304/// This function controls whether hardware countermeasures are applied by default.
305/// Disabling countermeasures can significantly improve performance but removes
306/// protection against hardware side-channel attacks.
307///
308/// # Parameters
309/// * `enabled` - `true` to enable countermeasures, `false` to disable
310///
311/// # Security Warning
312/// Only disable countermeasures in development/testing environments or when
313/// you are certain that side-channel attacks are not a threat. Disabling
314/// countermeasures in production cryptographic applications is dangerous.
315///
316/// # Performance Impact
317/// When disabled, protection functions like `with_hardware_countermeasures`
318/// execute with minimal overhead, making them suitable for performance-critical
319/// code paths that don't handle sensitive data.
320///
321/// # Thread Safety
322/// This function uses atomic operations and is safe to call from multiple threads.
323/// Changes take effect immediately for subsequent protection function calls.
324pub fn set_hardware_countermeasures_enabled(enabled: bool) {
325    HARDWARE_COUNTERMEASURES_ENABLED.store(enabled, Ordering::Relaxed);
326}
327
328/// Apply hardware countermeasures before sensitive operations.
329///
330/// This function coordinates the application of all pre-operation countermeasures
331/// based on the provided configuration. Pre-operation countermeasures normalize
332/// the hardware state to ensure consistent behavior during sensitive computations.
333///
334/// # Applied Countermeasures
335/// - **Cache Protection**: Flush cache lines and normalize memory access patterns
336/// - **Power Protection**: Initialize power consumption normalization
337/// - **EM Protection**: Set up electromagnetic signal balancing
338///
339/// # Timing
340/// These countermeasures are applied immediately before the sensitive operation
341/// to ensure the hardware is in a consistent state. They help prevent attacks
342/// that rely on observing hardware state transitions.
343fn pre_operation_countermeasures(config: &HardwareSecurityConfig) {
344    if config.cache_protection {
345        cache_pre_operation();
346    }
347
348    if config.power_protection {
349        power_pre_operation();
350    }
351
352    if config.em_protection {
353        em_pre_operation();
354    }
355}
356
357/// Apply hardware countermeasures after sensitive operations.
358///
359/// This function coordinates post-operation cleanup and balancing countermeasures.
360/// These ensure that any hardware state changes caused by the sensitive operation
361/// are normalized, preventing information leakage through observable state.
362///
363/// # Applied Countermeasures
364/// - **Power Protection**: Perform dummy operations to balance power consumption
365/// - **EM Protection**: Generate noise to mask electromagnetic emissions
366/// - **Cache Protection**: Clean up cache state to prevent data persistence
367///
368/// # Timing
369/// These countermeasures are applied immediately after the sensitive operation.
370/// The timing is critical to ensure that any side-channel signals from the
371/// operation are adequately masked by the balancing operations.
372fn post_operation_countermeasures(config: &HardwareSecurityConfig) {
373    if config.power_protection {
374        power_post_operation(config.dummy_operations);
375    }
376
377    if config.em_protection {
378        em_post_operation();
379    }
380
381    if config.cache_protection {
382        cache_post_operation();
383    }
384}
385
386/// Apply cache timing countermeasures before sensitive operations.
387///
388/// This function normalizes the CPU cache state to prevent cache timing attacks.
389/// Cache timing attacks work by observing which memory locations are cached,
390/// revealing information about which code paths or data were accessed.
391///
392/// # Protection Mechanism
393/// - Flush cache lines using architecture-specific instructions (CLFLUSH on x86, DC CIVAC on ARM)
394/// - Normalize memory access patterns to ensure consistent cache behavior
395/// - Fall back to timing normalization when hardware cache operations aren't available
396///
397/// # Architecture Support
398/// - **x86_64**: Uses CLFLUSH instruction when std feature is available
399/// - **AArch64**: Uses DC CIVAC instruction when std feature is available
400/// - **Other**: Falls back to software-based timing normalization
401///
402/// # Performance Impact
403/// Moderate overhead from cache flushing operations. Most significant on systems
404/// with large caches or when called frequently.
405///
406/// # Security Impact
407/// Critical for preventing cache timing attacks in shared computing environments
408/// like cloud platforms where cache state may be observable by other processes.
409fn cache_pre_operation() {
410    // Normalize cache state before sensitive operations using
411    // architecture-specific cache maintenance instructions
412
413    // We use a small buffer to ensure cache operations have valid addresses
414    let cache_buffer = [0u8; 64];
415
416    #[cfg(target_arch = "x86_64")]
417    {
418        // On x86_64, use CLFLUSH to flush cache lines if available
419        // This ensures consistent cache state before operations
420        // Note: CLFLUSH may require special permissions in some environments
421        //
422        // SAFETY: This unsafe block performs hardware cache management for side-channel protection.
423        // - core::arch::x86_64::_mm_clflush is a well-defined x86 instruction
424        // - It only affects L1/L2/L3 cache coherency, not memory contents or validity
425        // - Operates on stack-allocated buffer with proper bounds (chunks_exact(64))
426        // - Pointer cast to *const u8 is safe: any pointer can be cast to *const u8
427        // - No memory corruption, race conditions, or undefined behavior possible
428        // - This is the standard way to implement cache flushing in cryptographic code
429        if cfg!(feature = "std") {
430            // Only attempt cache operations in std environments where they're more likely to work
431            for chunk in cache_buffer.chunks_exact(64) {
432                unsafe {
433                    // SAFETY: CLFLUSH only affects cache state, not memory safety
434                    // This is essential for preventing cache timing side-channel attacks
435                    core::arch::x86_64::_mm_clflush(chunk.as_ptr() as *const u8);
436                }
437            }
438        } else {
439            // In no_std, fall back to timing normalization
440            timing_normalization(&cache_buffer);
441        }
442    }
443
444    #[cfg(target_arch = "aarch64")]
445    {
446        // On AArch64, use DC CIVAC if in privileged mode
447        // This invalidates cache lines to ensure clean state
448        // Note: Cache operations may require special permissions
449        //
450        // SAFETY: This unsafe block uses inline assembly for cache management.
451        // - DC CIVAC is a well-defined ARM instruction for cache invalidation
452        // - The register constraint ensures proper pointer handling
453        // - This only affects cache state, not memory validity
454        // - No side effects beyond cache coherency
455        if cfg!(feature = "std") {
456            for chunk in cache_buffer.chunks_exact(64) {
457                unsafe {
458                    // SAFETY: DC CIVAC instruction only affects cache state
459                    core::arch::asm!("dc civac, {}", in(reg) chunk.as_ptr());
460                }
461            }
462            // Ensure completion with data synchronization barrier
463            unsafe {
464                // SAFETY: DSB SY is a standard ARM synchronization instruction
465                // that only affects execution ordering, not memory validity
466                core::arch::asm!("dsb sy");
467            }
468        } else {
469            // In no_std, fall back to timing normalization
470            timing_normalization(&cache_buffer);
471        }
472    }
473
474    #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
475    {
476        // For other architectures, fall back to timing normalization
477        // through predictable memory access patterns
478        timing_normalization(&cache_buffer);
479    }
480}
481
482/// Software-based timing normalization for cache protection.
483///
484/// This function provides cache timing protection when hardware cache operations
485/// are not available or permitted. It performs predictable memory access patterns
486/// and computational operations to normalize execution timing.
487///
488/// # Mechanism
489/// - Performs consistent memory accesses to the provided buffer
490/// - Executes a series of arithmetic operations with predictable timing
491/// - Uses `black_box` to prevent compiler optimizations that might change timing
492///
493/// # Parameters
494/// * `cache_buffer` - Buffer to access for creating predictable memory patterns
495///
496/// # Limitations
497/// This is a best-effort approach when hardware cache operations aren't available.
498/// It provides some protection but is less effective than hardware-based cache flushing.
499///
500/// # Use Cases
501/// - no_std environments where hardware instructions aren't available
502/// - Environments where cache operations require special permissions
503/// - Fallback protection when hardware operations fail
504fn timing_normalization(cache_buffer: &[u8]) {
505    let mut _dummy = 0u64;
506    for i in 0..32 {
507        _dummy ^= i as u64;
508        _dummy = _dummy.wrapping_mul(0x9E3779B97F4A7C15);
509        // Access the buffer to create predictable cache patterns
510        if i < cache_buffer.len() {
511            _dummy ^= cache_buffer[i] as u64;
512        }
513    }
514    core::hint::black_box(_dummy);
515}
516
517/// Cache timing post-operation countermeasures.
518fn cache_post_operation() {
519    // Clean up cache state after sensitive operations
520    // This prevents sensitive data from remaining in cache
521
522    let cache_buffer = [0u8; 64];
523
524    #[cfg(target_arch = "x86_64")]
525    {
526        // On x86_64, use CLFLUSH if available
527        // Note: Cache operations may require special permissions
528        //
529        // SAFETY: CLFLUSH is used for side-channel attack prevention.
530        // - Only affects cache coherency, not memory validity
531        // - Operates on local stack buffer, no external memory corruption possible
532        // - Well-defined x86 instruction with no undefined behavior
533        if cfg!(feature = "std") {
534            for chunk in cache_buffer.chunks_exact(64) {
535                unsafe {
536                    // SAFETY: CLFLUSH only affects cache state, not memory contents
537                    core::arch::x86_64::_mm_clflush(chunk.as_ptr() as *const u8);
538                }
539            }
540        } else {
541            // In no_std, fall back to timing normalization
542            timing_normalization_post(&cache_buffer);
543        }
544    }
545
546    #[cfg(target_arch = "aarch64")]
547    {
548        // On AArch64, use DC CIVAC if in privileged mode
549        // Note: Cache operations may require special permissions
550        //
551        // SAFETY: ARM cache management instructions for side-channel prevention.
552        // - DC CIVAC and DSB are standard ARM instructions with well-defined behavior
553        // - Only affect cache coherency and execution ordering
554        // - No memory corruption or undefined behavior possible
555        // - Operates on local stack buffer with proper bounds checking
556        if cfg!(feature = "std") {
557            for chunk in cache_buffer.chunks_exact(64) {
558                unsafe {
559                    // SAFETY: DC CIVAC only affects cache state, not memory validity
560                    core::arch::asm!("dc civac, {}", in(reg) chunk.as_ptr());
561                }
562            }
563            // Ensure completion with barriers
564            unsafe {
565                // SAFETY: DSB SY is a standard synchronization instruction
566                core::arch::asm!("dsb sy");
567            }
568        } else {
569            // In no_std, fall back to timing normalization
570            timing_normalization_post(&cache_buffer);
571        }
572    }
573
574    #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
575    {
576        // For other architectures, fall back to timing normalization
577        timing_normalization_post(&cache_buffer);
578    }
579}
580
581/// Helper function for post-operation timing normalization
582fn timing_normalization_post(cache_buffer: &[u8]) {
583    let mut _dummy = 0u64;
584    for i in 0..16 {
585        _dummy ^= i as u64;
586        _dummy = _dummy.wrapping_add(0x4A7C15);
587        // Access the buffer to create predictable cache patterns
588        if i < cache_buffer.len() {
589            _dummy ^= cache_buffer[i] as u64;
590        }
591    }
592    core::hint::black_box(_dummy);
593}
594
595/// Apply power analysis countermeasures before sensitive operations.
596///
597/// This function normalizes power consumption patterns before cryptographic operations.
598/// Power analysis attacks measure the power consumed by a device to infer secret information,
599/// such as cryptographic keys, based on different power consumption for different operations.
600///
601/// # Protection Mechanism
602/// - Performs a series of arithmetic operations to establish baseline power consumption
603/// - Creates consistent power profile before the sensitive operation begins
604/// - Uses operations that exercise various CPU functional units consistently
605///
606/// # Attack Prevention
607/// Prevents attacks that rely on observing power consumption differences between:
608/// - Different cryptographic operations
609/// - Different input values
610/// - Different code paths in conditional operations
611///
612/// # Performance Impact
613/// Low overhead - the normalization operations are computationally light but
614/// help establish consistent power consumption patterns.
615///
616/// # Effectiveness
617/// Most effective when combined with post-operation power balancing.
618fn power_pre_operation() {
619    // Normalize power consumption before sensitive operations
620    // This helps prevent power analysis by ensuring consistent power state
621
622    // Perform dummy operations to normalize power consumption
623    let mut _dummy = 0u64;
624    for i in 0..64 {
625        // Mix of operations to normalize power consumption
626        _dummy = _dummy.wrapping_add(i as u64);
627        _dummy = _dummy.wrapping_mul(0x9E3779B9);
628        _dummy ^= 0xFFFFFFFFFFFFFFFFu64.wrapping_shr((i % 64) as u32);
629    }
630
631    core::hint::black_box(_dummy);
632}
633
634/// Apply power analysis countermeasures after sensitive operations.
635///
636/// This function performs dummy operations to balance and mask the power consumption
637/// of the preceding cryptographic operation. By performing additional operations
638/// with known power consumption, it becomes harder to isolate the power signature
639/// of the actual cryptographic computation.
640///
641/// # Parameters
642/// * `dummy_count` - Number of dummy operation iterations to perform
643///
644/// # Protection Mechanism
645/// - Executes a series of arithmetic operations similar to cryptographic computations
646/// - Uses constants designed to exercise CPU functional units consistently
647/// - Performs operations that have predictable power consumption patterns
648///
649/// # Effectiveness Factors
650/// - **dummy_count**: Higher values provide better masking but impact performance
651/// - **Operation Similarity**: Dummy operations should resemble real cryptographic ops
652/// - **Timing**: Operations should extend beyond the sensitive operation's duration
653///
654/// # Security vs Performance Trade-off
655/// The number of dummy operations controls the balance between security and performance.
656/// Typical values range from 5-50 depending on the security requirements and performance constraints.
657fn power_post_operation(dummy_count: usize) {
658    // Balance power consumption after sensitive operations
659    // Perform dummy operations to mask the actual operation's power signature
660
661    for _ in 0..dummy_count {
662        let mut _dummy = 0u64;
663        // Perform operations similar to cryptographic computations
664        // but with dummy data to balance power consumption
665        _dummy = _dummy.wrapping_add(0x123456789ABCDEF0);
666        _dummy = _dummy.wrapping_mul(0xFEDCBA9876543210);
667        _dummy ^= 0x0F0F0F0F0F0F0F0F;
668
669        core::hint::black_box(_dummy);
670    }
671}
672
673/// Electromagnetic analysis pre-operation countermeasures.
674fn em_pre_operation() {
675    // Normalize electromagnetic emissions before sensitive operations
676    // This helps prevent electromagnetic analysis attacks
677
678    // Perform operations that generate consistent electromagnetic patterns
679    let mut _dummy = [0u64; 8];
680    for i in 0..8 {
681        for j in 0..8 {
682            _dummy[i] = _dummy[i].wrapping_add(_dummy[j]);
683            _dummy[i] = _dummy[i].wrapping_mul(0x9E3779B97F4A7C15);
684        }
685    }
686
687    core::hint::black_box(_dummy);
688}
689
690/// Electromagnetic analysis post-operation countermeasures.
691fn em_post_operation() {
692    // Mask electromagnetic emissions after sensitive operations
693
694    let mut _dummy = 0u64;
695    for i in 0..256 {
696        // Generate electromagnetic noise to mask the actual operation
697        _dummy ^= i as u64;
698        _dummy = _dummy.rotate_left(7);
699        _dummy = _dummy.wrapping_add(0xA5A5A5A5A5A5A5A5);
700    }
701
702    core::hint::black_box(_dummy);
703}
704
705/// Memory access normalization for cache timing protection.
706///
707/// This function ensures that memory access patterns are independent of
708/// secret data, preventing cache timing attacks.
709pub fn normalize_memory_access<F>(f: F)
710where
711    F: FnOnce(),
712{
713    // Ensure memory access happens in a predictable pattern
714    // This is especially important for operations that access
715    // arrays or other data structures based on secret indices
716
717    cache_pre_operation();
718    f();
719    cache_post_operation();
720}
721
722/// Power consumption normalization.
723///
724/// Balances power consumption across different operations to prevent
725/// power analysis attacks.
726pub fn normalize_power_consumption<F, R>(f: F) -> R
727where
728    F: FnOnce() -> R,
729{
730    power_pre_operation();
731    let result = f();
732    power_post_operation(20); // More dummy operations for power balancing
733    result
734}
735
736/// Signal balancing for electromagnetic protection.
737///
738/// Balances electromagnetic emissions to prevent EM analysis.
739pub fn balance_em_signals<F, R>(f: F) -> R
740where
741    F: FnOnce() -> R,
742{
743    em_pre_operation();
744    let result = f();
745    em_post_operation();
746    result
747}
748
749/// Comprehensive hardware protection wrapper.
750///
751/// Applies all available hardware countermeasures to a cryptographic operation.
752pub fn protect_cryptographic_operation<F, R>(f: F) -> R
753where
754    F: FnOnce() -> R,
755{
756    // Apply countermeasures in sequence
757    let config = HardwareSecurityConfig::default();
758    pre_operation_countermeasures(&config);
759    let result = f();
760    post_operation_countermeasures(&config);
761    result
762}
763
764#[cfg(test)]
765mod tests {
766    use super::*;
767
768    /// Test that hardware countermeasures are enabled by default.
769    ///
770    /// Verifies that the global hardware countermeasures flag is set to true
771    /// in the initial state, ensuring that protection functions apply countermeasures
772    /// by default.
773    #[test]
774    fn test_hardware_countermeasures_enabled_by_default() {
775        acquire_test_lock();
776        let result = is_hardware_countermeasures_enabled();
777        release_test_lock();
778        assert!(result);
779    }
780
781    /// Test that hardware countermeasures can be disabled and re-enabled.
782    ///
783    /// Verifies that the global countermeasures flag can be controlled at runtime,
784    /// allowing applications to disable protection for performance reasons when
785    /// side-channel attacks are not a concern.
786    #[test]
787    fn test_hardware_countermeasures_can_be_disabled() {
788        acquire_test_lock();
789        let original_state = is_hardware_countermeasures_enabled();
790        set_hardware_countermeasures_enabled(false);
791        assert!(!is_hardware_countermeasures_enabled());
792        set_hardware_countermeasures_enabled(original_state); // Restore original state
793        release_test_lock();
794    }
795
796    /// Test the basic hardware countermeasures wrapper function.
797    ///
798    /// Verifies that the `with_hardware_countermeasures` function correctly
799    /// executes the wrapped function and returns its result, while applying
800    /// the appropriate countermeasures.
801    #[test]
802    fn test_with_hardware_countermeasures() {
803        let result = with_hardware_countermeasures(|| 42);
804        assert_eq!(result, 42);
805    }
806
807    /// Test custom hardware countermeasures configuration.
808    ///
809    /// Verifies that the `with_custom_hardware_countermeasures` function
810    /// correctly applies countermeasures based on a custom configuration,
811    /// allowing selective enabling/disabling of different protection types.
812    #[test]
813    fn test_with_custom_hardware_countermeasures() {
814        let config = HardwareSecurityConfig {
815            cache_protection: false,
816            power_protection: true,
817            em_protection: false,
818            dummy_operations: 5,
819        };
820
821        let result = with_custom_hardware_countermeasures(&config, || 123);
822        assert_eq!(result, 123);
823    }
824
825    /// Test the comprehensive cryptographic operation protection.
826    ///
827    /// Verifies that the `protect_cryptographic_operation` function correctly
828    /// applies all available countermeasures and returns the result of the
829    /// wrapped cryptographic computation.
830    #[test]
831    fn test_protect_cryptographic_operation() {
832        let result = protect_cryptographic_operation(|| 42u64.wrapping_mul(2));
833        assert_eq!(result, 84);
834    }
835}