use crate::error::{CryptoError, Result};
use crate::i18n::translate;
use std::collections::VecDeque;
use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
use std::time::{Duration, Instant};
#[allow(dead_code)]
pub struct ErrorInjectionDetector {
start_time: Instant,
checksum: AtomicU64,
counter: AtomicU32,
redundancy_checks: Vec<RedundancyCheck>,
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct RedundancyCheck {
_name: String,
_expected_value: u64,
_tolerance: f64,
}
impl Default for ErrorInjectionDetector {
fn default() -> Self {
Self {
start_time: Instant::now(),
checksum: AtomicU64::new(0),
counter: AtomicU32::new(0),
redundancy_checks: Vec::new(),
}
}
}
#[allow(dead_code)]
impl ErrorInjectionDetector {
pub fn new() -> Self {
Self::default()
}
pub fn add_redundancy_check(&mut self, name: String, expected_value: u64, tolerance: f64) {
self.redundancy_checks.push(RedundancyCheck {
_name: name,
_expected_value: expected_value,
_tolerance: tolerance,
});
}
pub fn update(&self, data: u64) {
self.counter.fetch_add(1, Ordering::SeqCst);
let old_checksum = self.checksum.load(Ordering::SeqCst);
let new_checksum = old_checksum.wrapping_add(data);
self.checksum.store(new_checksum, Ordering::SeqCst);
}
pub fn detect_fault(&self) -> bool {
if self.detect_timing_anomaly() {
return true;
}
if self.detect_checksum_fault() {
return true;
}
if self.detect_counter_fault() {
return true;
}
false
}
fn detect_timing_anomaly(&self) -> bool {
let elapsed = self.start_time.elapsed();
if elapsed < Duration::from_nanos(100) || elapsed > Duration::from_secs(10) {
return true;
}
false
}
fn detect_checksum_fault(&self) -> bool {
let _checksum = self.checksum.load(Ordering::SeqCst);
let counter = self.counter.load(Ordering::SeqCst);
counter > 1_000_000_000
}
fn detect_counter_fault(&self) -> bool {
let counter = self.counter.load(Ordering::SeqCst);
counter > 10_000_000 || counter == u32::MAX
}
}
pub struct TripleModularRedundancy<T> {
value1: T,
value2: T,
value3: T,
}
#[allow(dead_code)]
impl<T: Clone + PartialEq> TripleModularRedundancy<T> {
pub fn new(value: T) -> Self {
Self {
value1: value.clone(),
value2: value.clone(),
value3: value,
}
}
pub fn vote(&self) -> Result<&T> {
if self.value1 == self.value2 || self.value1 == self.value3 {
Ok(&self.value1)
} else if self.value2 == self.value3 {
Ok(&self.value2)
} else {
Err(CryptoError::SideChannelError(
"Triple modular redundancy failed".into(),
))
}
}
pub fn update(&mut self, value: T) {
self.value1 = value.clone();
self.value2 = value.clone();
self.value3 = value;
}
}
pub struct ErrorCorrectionCode {
data: Vec<u8>,
parity: Vec<u8>,
}
#[allow(dead_code)]
impl ErrorCorrectionCode {
pub fn new(data: Vec<u8>) -> Self {
let parity = Self::calculate_parity(&data);
Self { data, parity }
}
fn calculate_parity(data: &[u8]) -> Vec<u8> {
let mut parity = vec![0u8; data.len().div_ceil(8)];
for (i, &byte) in data.iter().enumerate() {
let parity_byte = i / 8;
let parity_bit = i % 8;
let bit_count = byte.count_ones() as u8;
if bit_count % 2 == 1 {
parity[parity_byte] ^= 1 << parity_bit;
}
}
parity
}
pub fn verify(&self) -> Result<()> {
let calculated_parity = Self::calculate_parity(&self.data);
if calculated_parity != self.parity {
return Err(CryptoError::SideChannelError("Parity check failed".into()));
}
Ok(())
}
pub fn correct_single_error(&mut self) -> Result<bool> {
let calculated_parity = Self::calculate_parity(&self.data);
if calculated_parity == self.parity {
return Ok(false); }
let mut mismatch_count = 0;
let mut first_mismatch_index = None;
for (i, &_byte) in self.data.iter().enumerate() {
let parity_byte = i / 8;
let parity_bit = i % 8;
if parity_byte < calculated_parity.len() && parity_byte < self.parity.len() {
let expected_bit = (calculated_parity[parity_byte] >> parity_bit) & 1;
let actual_bit = (self.parity[parity_byte] >> parity_bit) & 1;
if expected_bit != actual_bit {
mismatch_count += 1;
if first_mismatch_index.is_none() {
first_mismatch_index = Some(i);
}
}
}
}
if mismatch_count > 1 {
return Err(CryptoError::SideChannelError(
"Multiple errors detected - cannot correct reliably".into(),
));
}
if let Some(index) = first_mismatch_index {
let original_byte = self.data[index];
for bit_pos in 0..8 {
self.data[index] = original_byte ^ (1 << bit_pos);
let test_parity = Self::calculate_parity(&self.data);
if test_parity == self.parity {
return Ok(true);
}
}
self.data[index] = original_byte; return Err(CryptoError::SideChannelError(
"Uncorrectable error detected".into(),
));
}
Err(CryptoError::SideChannelError(translate(
"error.unknown_error_condition",
)))
}
}
pub struct ClockGlitchDetector {
timestamps: VecDeque<Instant>,
threshold: Duration,
}
impl ClockGlitchDetector {
#[allow(dead_code)]
pub fn new(threshold: Duration) -> Self {
Self {
timestamps: VecDeque::with_capacity(10),
threshold,
}
}
#[allow(dead_code)]
pub fn check(&mut self) -> Result<()> {
let now = Instant::now();
if let Some(&last_timestamp) = self.timestamps.back() {
let delta = now - last_timestamp;
if self.threshold > Duration::from_micros(1) {
if delta < self.threshold || delta > self.threshold * 100 {
return Err(CryptoError::SideChannelError(translate(
"error.clock_glitch_detected",
)));
}
}
}
self.timestamps.push_back(now);
if self.timestamps.len() > 10 {
self.timestamps.pop_front();
}
Ok(())
}
}
#[allow(dead_code)]
pub struct VoltageFaultDetector {
sensor_readings: VecDeque<u16>,
baseline: u16,
tolerance: u16,
}
#[allow(dead_code)]
impl VoltageFaultDetector {
pub fn new(baseline: u16, tolerance: u16) -> Self {
Self {
sensor_readings: VecDeque::with_capacity(20),
baseline,
tolerance,
}
}
pub fn add_reading(&mut self, reading: u16) -> Result<()> {
self.sensor_readings.push_back(reading);
if self.sensor_readings.len() > 20 {
self.sensor_readings.pop_front();
}
if reading.abs_diff(self.baseline) > self.tolerance {
return Err(CryptoError::SideChannelError(
"Voltage fault detected".into(),
));
}
Ok(())
}
}
#[allow(dead_code)]
pub struct ElectromagneticPulseDetector {
em_readings: VecDeque<u32>,
threshold: u32,
}
#[allow(dead_code)]
impl ElectromagneticPulseDetector {
pub fn new(threshold: u32) -> Self {
Self {
em_readings: VecDeque::with_capacity(15),
threshold,
}
}
pub fn add_reading(&mut self, reading: u32) -> Result<()> {
self.em_readings.push_back(reading);
if self.em_readings.len() > 15 {
self.em_readings.pop_front();
}
if reading > self.threshold {
return Err(CryptoError::SideChannelError(
"Electromagnetic pulse detected".into(),
));
}
Ok(())
}
}
#[allow(dead_code)]
pub struct FaultInjectionShield {
error_detector: ErrorInjectionDetector,
clock_detector: ClockGlitchDetector,
voltage_detector: Option<VoltageFaultDetector>,
em_detector: Option<ElectromagneticPulseDetector>,
redundancy: TripleModularRedundancy<bool>,
}
impl Default for FaultInjectionShield {
fn default() -> Self {
Self {
error_detector: ErrorInjectionDetector::default(),
clock_detector: ClockGlitchDetector::new(Duration::from_nanos(100)), voltage_detector: None,
em_detector: None,
redundancy: TripleModularRedundancy::new(false),
}
}
}
#[allow(dead_code)]
impl FaultInjectionShield {
#[allow(dead_code)]
pub fn new() -> Self {
Self::default()
}
#[allow(dead_code)]
pub fn enable_voltage_detection(&mut self, baseline: u16, tolerance: u16) {
self.voltage_detector = Some(VoltageFaultDetector::new(baseline, tolerance));
}
#[allow(dead_code)]
pub fn enable_em_detection(&mut self, threshold: u32) {
self.em_detector = Some(ElectromagneticPulseDetector::new(threshold));
}
#[allow(dead_code)]
pub fn check_all(&mut self) -> Result<()> {
self.clock_detector.check()?;
if let Some(ref mut detector) = self.voltage_detector {
let simulated_reading = 3300u16; detector.add_reading(simulated_reading)?;
}
if let Some(ref mut detector) = self.em_detector {
let simulated_reading = 100u32;
detector.add_reading(simulated_reading)?;
}
if self.error_detector.detect_fault() {
return Err(CryptoError::SideChannelError(translate(
"error.fault_injection_detected",
)));
}
self.redundancy.update(true);
self.redundancy.vote()?;
Ok(())
}
#[allow(dead_code)]
pub fn add_sensor_reading(&mut self, sensor_type: SensorType, reading: u32) -> Result<()> {
match sensor_type {
SensorType::Voltage => {
if let Some(ref mut detector) = self.voltage_detector {
detector.add_reading(reading as u16)?;
}
}
SensorType::Electromagnetic => {
if let Some(ref mut detector) = self.em_detector {
detector.add_reading(reading)?;
}
}
SensorType::Clock => {
}
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(dead_code)]
pub enum SensorType {
Voltage,
Electromagnetic,
Clock,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_triple_modular_redundancy() {
let mut tmr = TripleModularRedundancy::new(42u32);
assert_eq!(*tmr.vote().unwrap(), 42);
tmr.update(43);
assert_eq!(*tmr.vote().unwrap(), 43);
}
#[test]
fn test_error_correction_code() {
let data = vec![0x01, 0x02, 0x03, 0x04];
let mut ecc = ErrorCorrectionCode::new(data.clone());
assert!(ecc.verify().is_ok());
ecc.data[1] ^= 0x01;
assert!(ecc.verify().is_err());
assert!(ecc.correct_single_error().unwrap());
assert!(ecc.verify().is_ok());
assert_eq!(ecc.data, data);
}
#[test]
fn test_clock_glitch_detector() {
let mut detector = ClockGlitchDetector::new(Duration::from_millis(1));
assert!(detector.check().is_ok());
std::thread::sleep(Duration::from_millis(2));
assert!(detector.check().is_ok());
}
#[test]
fn test_error_injection_detector() {
let detector = ErrorInjectionDetector::new();
detector.update(0x1234567890ABCDEF);
detector.update(0xFEDCBA0987654321);
std::thread::sleep(std::time::Duration::from_micros(10));
assert!(!detector.detect_fault());
for i in 0..1000 {
detector.update(i as u64);
}
assert!(!detector.detect_fault());
}
#[test]
fn test_voltage_fault_detector() {
let mut detector = VoltageFaultDetector::new(3300, 100);
assert!(detector.add_reading(3300).is_ok());
assert!(detector.add_reading(3250).is_ok());
assert!(detector.add_reading(3350).is_ok());
assert!(detector.add_reading(3100).is_err()); assert!(detector.add_reading(3600).is_err()); }
#[test]
fn test_electromagnetic_pulse_detector() {
let mut detector = ElectromagneticPulseDetector::new(1000);
assert!(detector.add_reading(100).is_ok());
assert!(detector.add_reading(500).is_ok());
assert!(detector.add_reading(999).is_ok());
assert!(detector.add_reading(1001).is_err());
assert!(detector.add_reading(2000).is_err());
}
#[test]
fn test_fault_injection_shield() {
let mut shield = FaultInjectionShield::new();
println!("Testing basic check_all()...");
let result1 = shield.check_all();
println!("Basic check result: {:?}", result1);
assert!(result1.is_ok());
println!("Enabling voltage and EM detection...");
shield.enable_voltage_detection(3300, 100);
shield.enable_em_detection(1000);
println!("Testing check_all() with additional detectors...");
let result2 = shield.check_all();
println!("Check with detectors result: {:?}", result2);
assert!(result2.is_ok());
println!("Adding sensor readings...");
let result3 = shield.add_sensor_reading(SensorType::Voltage, 3300);
println!("Voltage sensor result: {:?}", result3);
assert!(result3.is_ok());
let result4 = shield.add_sensor_reading(SensorType::Electromagnetic, 500);
println!("EM sensor result: {:?}", result4);
assert!(result4.is_ok());
}
#[test]
fn test_triple_modular_redundancy_failure() {
let tmr = TripleModularRedundancy {
value1: 1u32,
value2: 2u32,
value3: 3u32,
};
assert!(tmr.vote().is_err());
}
#[test]
fn test_error_correction_multiple_errors() {
let data = vec![0x01, 0x02, 0x03, 0x04];
let mut ecc = ErrorCorrectionCode::new(data);
ecc.data[0] ^= 0x01;
ecc.data[1] ^= 0x01;
assert!(ecc.correct_single_error().is_err());
}
#[test]
fn test_sensor_types() {
assert_eq!(SensorType::Voltage as u8, 0);
assert_eq!(SensorType::Electromagnetic as u8, 1);
assert_eq!(SensorType::Clock as u8, 2);
assert_ne!(SensorType::Voltage, SensorType::Electromagnetic);
assert_ne!(SensorType::Electromagnetic, SensorType::Clock);
assert_ne!(SensorType::Voltage, SensorType::Clock);
}
#[test]
fn test_fault_injection_shield_with_sensor_readings() {
let mut shield = FaultInjectionShield::new();
shield.enable_voltage_detection(3300, 100);
shield.enable_em_detection(1000);
assert!(shield.add_sensor_reading(SensorType::Voltage, 3300).is_ok());
assert!(shield
.add_sensor_reading(SensorType::Electromagnetic, 500)
.is_ok());
assert!(shield.check_all().is_ok());
assert!(shield
.add_sensor_reading(SensorType::Voltage, 3000)
.is_err());
assert!(shield
.add_sensor_reading(SensorType::Electromagnetic, 1500)
.is_err());
}
}