pub mod constant_time;
pub mod memory;
pub mod nonce;
pub mod side_channel;
pub mod stack_buffer;
pub mod timing;
pub mod validation;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SecurityConfig {
pub constant_time: bool,
pub side_channel_protection: bool,
pub secure_memory: bool,
pub strict_validation: bool,
pub timing_protection: bool,
pub fault_injection_protection: bool,
}
impl Default for SecurityConfig {
fn default() -> Self {
Self {
constant_time: true,
side_channel_protection: true,
secure_memory: true,
strict_validation: true,
timing_protection: true,
fault_injection_protection: true,
}
}
}
impl SecurityConfig {
pub fn strict() -> Self {
Self {
constant_time: true,
side_channel_protection: true,
secure_memory: true,
strict_validation: true,
timing_protection: true,
fault_injection_protection: true,
}
}
pub fn permissive() -> Self {
Self {
constant_time: false,
side_channel_protection: false,
secure_memory: false,
strict_validation: false,
timing_protection: false,
fault_injection_protection: false,
}
}
pub fn balanced() -> Self {
Self {
constant_time: true,
side_channel_protection: true,
secure_memory: true,
strict_validation: true,
timing_protection: false,
fault_injection_protection: false,
}
}
}
static mut SECURITY_CONFIG: SecurityConfig = SecurityConfig {
constant_time: true,
side_channel_protection: true,
secure_memory: true,
strict_validation: true,
timing_protection: true,
fault_injection_protection: true,
};
pub fn get_security_config() -> SecurityConfig {
unsafe { SECURITY_CONFIG }
}
pub fn set_security_config(config: SecurityConfig) {
unsafe {
SECURITY_CONFIG = config;
}
}
pub struct SecurityContext {
config: SecurityConfig,
operation_id: u64,
start_time: u64,
}
impl SecurityContext {
pub fn new() -> Self {
Self {
config: get_security_config(),
operation_id: Self::generate_operation_id(),
start_time: Self::get_timestamp(),
}
}
pub fn with_config(config: SecurityConfig) -> Self {
Self {
config,
operation_id: Self::generate_operation_id(),
start_time: Self::get_timestamp(),
}
}
pub fn operation_id(&self) -> u64 {
self.operation_id
}
pub fn elapsed_time(&self) -> u64 {
Self::get_timestamp() - self.start_time
}
pub fn constant_time_enabled(&self) -> bool {
self.config.constant_time
}
pub fn side_channel_protection_enabled(&self) -> bool {
self.config.side_channel_protection
}
pub fn secure_memory_enabled(&self) -> bool {
self.config.secure_memory
}
pub fn strict_validation_enabled(&self) -> bool {
self.config.strict_validation
}
pub fn timing_protection_enabled(&self) -> bool {
self.config.timing_protection
}
pub fn fault_injection_protection_enabled(&self) -> bool {
self.config.fault_injection_protection
}
fn generate_operation_id() -> u64 {
static mut COUNTER: u64 = 0;
unsafe {
COUNTER += 1;
COUNTER
}
}
fn get_timestamp() -> u64 {
#[cfg(all(feature = "std", not(target_arch = "wasm32")))]
{
use std::time::{
SystemTime,
UNIX_EPOCH,
};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_nanos() as u64
}
#[cfg(any(not(feature = "std"), target_arch = "wasm32"))]
{
use core::sync::atomic::{
AtomicU64,
Ordering,
};
static COUNTER: AtomicU64 = AtomicU64::new(0);
COUNTER.fetch_add(1, Ordering::SeqCst)
}
}
}
impl Default for SecurityContext {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_security_config_defaults() {
let config = SecurityConfig::default();
assert!(config.constant_time);
assert!(config.side_channel_protection);
assert!(config.secure_memory);
assert!(config.strict_validation);
assert!(config.timing_protection);
assert!(config.fault_injection_protection);
}
#[test]
fn test_security_config_strict() {
let config = SecurityConfig::strict();
assert!(config.constant_time);
assert!(config.side_channel_protection);
assert!(config.secure_memory);
assert!(config.strict_validation);
assert!(config.timing_protection);
assert!(config.fault_injection_protection);
}
#[test]
fn test_security_config_permissive() {
let config = SecurityConfig::permissive();
assert!(!config.constant_time);
assert!(!config.side_channel_protection);
assert!(!config.secure_memory);
assert!(!config.strict_validation);
assert!(!config.timing_protection);
assert!(!config.fault_injection_protection);
}
#[test]
fn test_security_config_balanced() {
let config = SecurityConfig::balanced();
assert!(config.constant_time);
assert!(config.side_channel_protection);
assert!(config.secure_memory);
assert!(config.strict_validation);
assert!(!config.timing_protection);
assert!(!config.fault_injection_protection);
}
#[test]
fn test_security_context_creation() {
let ctx = SecurityContext::new();
assert!(ctx.operation_id() > 0);
let _elapsed = ctx.elapsed_time();
assert!(ctx.constant_time_enabled());
}
#[test]
fn test_security_context_with_config() {
let config = SecurityConfig::permissive();
let ctx = SecurityContext::with_config(config);
assert!(!ctx.constant_time_enabled());
assert!(!ctx.side_channel_protection_enabled());
assert!(!ctx.secure_memory_enabled());
assert!(!ctx.strict_validation_enabled());
assert!(!ctx.timing_protection_enabled());
assert!(!ctx.fault_injection_protection_enabled());
}
#[test]
fn test_global_security_config() {
let original_config = get_security_config();
let new_config = SecurityConfig::permissive();
set_security_config(new_config);
let retrieved_config = get_security_config();
assert_eq!(retrieved_config, new_config);
set_security_config(original_config);
}
}