use crate::error::{PqcError, Result};
use core::sync::atomic::{AtomicU8, Ordering};
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FipsState {
Uninitialized = 0,
POST = 1,
Operational = 2,
Error = 3,
}
static FIPS_STATE: AtomicU8 = AtomicU8::new(FipsState::Uninitialized as u8);
pub fn get_fips_state() -> FipsState {
FipsState::from(FIPS_STATE.load(Ordering::Acquire))
}
pub fn is_operational() -> bool {
get_fips_state() == FipsState::Operational
}
pub fn check_operational() -> Result<()> {
match get_fips_state() {
FipsState::Operational => Ok(()),
FipsState::Uninitialized => Err(PqcError::FipsNotInitialized),
FipsState::POST => Err(PqcError::FipsPostInProgress),
FipsState::Error => Err(PqcError::FipsErrorState),
}
}
pub fn reset_fips_state() {
FIPS_STATE.store(FipsState::Uninitialized as u8, Ordering::Release);
}
pub(crate) fn enter_post_state() {
FIPS_STATE.store(FipsState::POST as u8, Ordering::Release);
}
pub(crate) fn enter_operational_state() {
FIPS_STATE.store(FipsState::Operational as u8, Ordering::Release);
}
pub(crate) fn enter_error_state() {
FIPS_STATE.store(FipsState::Error as u8, Ordering::Release);
}
impl From<u8> for FipsState {
fn from(val: u8) -> Self {
match val {
0 => FipsState::Uninitialized,
1 => FipsState::POST,
2 => FipsState::Operational,
_ => FipsState::Error,
}
}
}