use super::{
AccountingPosture, AssuranceGenerations, AssuranceLevel, AssuranceToken, CleanupError,
CleanupReport, JournalDisposition, LifecyclePosture, PendingStage, PhysicalProtection,
ProviderHealth, WipeEvidence,
};
use crate::runtime::{CtGatePosture, OperationBackendReport, WipePosture};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum SecretOperation {
NotStarted,
Encode,
Decode,
}
impl SecretOperation {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::NotStarted => "not-started",
Self::Encode => "secret-encode",
Self::Decode => "secret-decode",
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum AttestationPosture {
NotAttested,
Attested,
}
impl AttestationPosture {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::NotAttested => "not-attested",
Self::Attested => "attested",
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum SecretPolicyPosture {
BestEffort,
HighAssuranceAttested,
}
impl SecretPolicyPosture {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::BestEffort => "best-effort",
Self::HighAssuranceAttested => "high-assurance-attested",
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum AllocationPosture {
Present,
Absent,
UnknownNoAddressRetained,
}
impl AllocationPosture {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Present => "present",
Self::Absent => "absent",
Self::UnknownNoAddressRetained => "unknown-no-address-retained",
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct AssuranceReport {
pub encode_backend: OperationBackendReport,
pub strict_decode_backend: OperationBackendReport,
pub secret_decode_backend: OperationBackendReport,
pub generations: AssuranceGenerations,
pub wipe_posture: WipePosture,
pub result_gate_posture: CtGatePosture,
pub attestation_posture: AttestationPosture,
pub secret_policy_posture: SecretPolicyPosture,
pub wasm_artifact_posture: crate::runtime::WasmArtifactPosture,
pub wasm_runtime_posture: crate::runtime::WasmRuntimePosture,
}
impl AssuranceReport {
#[must_use]
pub const fn snapshot(self) -> AssuranceSnapshot {
AssuranceSnapshot {
encode_backend: self.encode_backend.snapshot(),
strict_decode_backend: self.strict_decode_backend.snapshot(),
secret_decode_backend: self.secret_decode_backend.snapshot(),
ordinary_backend_generation: self.generations.ordinary_backend,
secret_algorithm_generation: self.generations.secret_algorithm,
wipe_barrier_generation: self.generations.wipe_barrier,
speculation_generation: self.generations.speculation,
wipe_posture: self.wipe_posture.as_str(),
result_gate_posture: self.result_gate_posture.as_str(),
attestation_posture: self.attestation_posture.as_str(),
secret_policy_posture: self.secret_policy_posture.as_str(),
wasm_artifact_posture: self.wasm_artifact_posture.as_str(),
wasm_runtime_posture: self.wasm_runtime_posture.as_str(),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct AssuranceSnapshot {
pub encode_backend: crate::runtime::OperationBackendSnapshot,
pub strict_decode_backend: crate::runtime::OperationBackendSnapshot,
pub secret_decode_backend: crate::runtime::OperationBackendSnapshot,
pub ordinary_backend_generation: usize,
pub secret_algorithm_generation: usize,
pub wipe_barrier_generation: usize,
pub speculation_generation: usize,
pub wipe_posture: &'static str,
pub result_gate_posture: &'static str,
pub attestation_posture: &'static str,
pub secret_policy_posture: &'static str,
pub wasm_artifact_posture: &'static str,
pub wasm_runtime_posture: &'static str,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ProtectedOperationReport {
pub assurance: AssuranceReport,
pub operation: SecretOperation,
pub wipe: WipeEvidence,
pub physical_protection: PhysicalProtection,
pub accounting: AccountingPosture,
pub lifecycle: LifecyclePosture,
pub allocation: AllocationPosture,
pub provider_health: ProviderHealth,
pub health_generation: usize,
pub protection_generation: usize,
}
impl ProtectedOperationReport {
pub(crate) const fn live(
assurance: AssuranceReport,
operation: SecretOperation,
physical_protection: PhysicalProtection,
provider_health: ProviderHealth,
health_generation: usize,
protection_generation: usize,
) -> Self {
Self {
assurance,
operation,
wipe: WipeEvidence::WipeNotCompleted,
physical_protection,
accounting: AccountingPosture::Charged,
lifecycle: LifecyclePosture::Live,
allocation: AllocationPosture::Present,
provider_health,
health_generation,
protection_generation,
}
}
#[must_use]
pub const fn snapshot(self) -> ProtectedOperationSnapshot {
ProtectedOperationSnapshot {
assurance: self.assurance.snapshot(),
operation: self.operation.as_str(),
wipe: wipe_id(self.wipe),
physical_protection: physical_id(self.physical_protection),
accounting: accounting_id(self.accounting),
lifecycle: lifecycle_id(self.lifecycle),
allocation: self.allocation.as_str(),
provider_health: provider_health_id(self.provider_health),
health_generation: self.health_generation,
protection_generation: self.protection_generation,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ProtectedOperationSnapshot {
pub assurance: AssuranceSnapshot,
pub operation: &'static str,
pub wipe: &'static str,
pub physical_protection: &'static str,
pub accounting: &'static str,
pub lifecycle: &'static str,
pub allocation: &'static str,
pub provider_health: &'static str,
pub health_generation: usize,
pub protection_generation: usize,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CleanupSnapshot {
pub wipe: &'static str,
pub physical_protection: &'static str,
pub accounting: &'static str,
pub lifecycle: &'static str,
pub allocation: &'static str,
pub pending_stage: Option<&'static str>,
pub pending_substage: Option<&'static str>,
pub provider_health: Option<&'static str>,
pub retry_attempt: Option<usize>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ProviderSnapshot {
pub health: &'static str,
pub health_generation: usize,
pub protection_generation: usize,
pub active_and_reserved: usize,
pub quarantined: usize,
pub permanently_quarantined: usize,
pub tombstoned: usize,
pub charged_logical_bytes: usize,
pub charged_effective_pages: usize,
}
impl super::ProviderReport {
#[must_use]
pub const fn snapshot(self) -> ProviderSnapshot {
ProviderSnapshot {
health: provider_health_id(self.health),
health_generation: self.health_generation,
protection_generation: self.protection_generation,
active_and_reserved: self.active_and_reserved,
quarantined: self.quarantined,
permanently_quarantined: self.permanently_quarantined,
tombstoned: self.tombstoned,
charged_logical_bytes: self.charged_logical_bytes,
charged_effective_pages: self.charged_effective_pages,
}
}
}
impl<Level: AssuranceLevel> AssuranceToken<'_, Level> {
#[must_use]
pub fn report(&self) -> AssuranceReport {
let runtime = crate::runtime::backend_report();
let mut encode_backend = runtime.encode_backend;
let mut strict_decode_backend = runtime.strict_decode_backend;
let mut secret_decode_backend = runtime.secret_decode_backend;
let generations = self.generations();
encode_backend.health_generation = generations.ordinary_backend;
strict_decode_backend.health_generation = generations.ordinary_backend;
secret_decode_backend.health_generation = generations.secret_algorithm;
let evidence = self.evidence();
AssuranceReport {
encode_backend,
strict_decode_backend,
secret_decode_backend,
generations,
wipe_posture: evidence.map_or(
runtime.wipe_posture,
super::context::AttestationEvidence::wipe_posture,
),
result_gate_posture: evidence.map_or(
runtime.ct_gate_posture,
super::context::AttestationEvidence::speculation_posture,
),
attestation_posture: if evidence.is_some() {
AttestationPosture::Attested
} else {
AttestationPosture::NotAttested
},
secret_policy_posture: if Self::requires_attestation() {
SecretPolicyPosture::HighAssuranceAttested
} else {
SecretPolicyPosture::BestEffort
},
wasm_artifact_posture: runtime.wasm_artifact_posture,
wasm_runtime_posture: runtime.wasm_runtime_posture,
}
}
}
impl CleanupReport {
#[must_use]
pub const fn snapshot(self) -> CleanupSnapshot {
CleanupSnapshot {
wipe: wipe_id(self.wipe),
physical_protection: physical_id(self.physical_protection),
accounting: accounting_id(self.accounting),
lifecycle: lifecycle_id(self.lifecycle),
allocation: AllocationPosture::Absent.as_str(),
pending_stage: None,
pending_substage: None,
provider_health: None,
retry_attempt: None,
}
}
}
impl CleanupError {
#[must_use]
pub const fn snapshot(self) -> CleanupSnapshot {
let allocation = if matches!(self.lifecycle, LifecyclePosture::Tombstoned { .. }) {
AllocationPosture::UnknownNoAddressRetained
} else {
AllocationPosture::Present
};
CleanupSnapshot {
wipe: wipe_id(self.wipe),
physical_protection: physical_id(self.physical_protection),
accounting: accounting_id(self.accounting),
lifecycle: lifecycle_id(self.lifecycle),
allocation: allocation.as_str(),
pending_stage: Some(pending_stage_id(self.pending_stage)),
pending_substage: Some(journal_id(self.pending_substage)),
provider_health: Some(provider_health_id(self.provider_health)),
retry_attempt: Some(self.retry_attempt),
}
}
}
const fn wipe_id(value: WipeEvidence) -> &'static str {
match value {
WipeEvidence::WipeNotCompleted => "wipe-not-completed",
WipeEvidence::WipedBestEffort => "wiped-best-effort",
WipeEvidence::WipedAttested => "wiped-attested",
}
}
const fn physical_id(value: PhysicalProtection) -> &'static str {
match value {
PhysicalProtection::ProtectionAttested => "protection-attested",
PhysicalProtection::ProtectionConfirmedAbsent => "protection-confirmed-absent",
PhysicalProtection::ProtectionUnknown => "protection-unknown",
}
}
const fn accounting_id(value: AccountingPosture) -> &'static str {
match value {
AccountingPosture::Charged => "charged",
AccountingPosture::Reconciled => "reconciled",
}
}
const fn lifecycle_id(value: LifecyclePosture) -> &'static str {
match value {
LifecyclePosture::Live => "live",
LifecyclePosture::Closing { .. } => "closing",
LifecyclePosture::Quarantined { .. } => "quarantined",
LifecyclePosture::PermanentlyQuarantined { .. } => "permanently-quarantined",
LifecyclePosture::Tombstoned { .. } => "tombstoned",
LifecyclePosture::Closed => "closed",
}
}
const fn pending_stage_id(value: PendingStage) -> &'static str {
match value {
PendingStage::Wipe => "wipe",
PendingStage::ProtectionRemoval => "protection-removal",
PendingStage::AccountingReconciliation => "accounting-reconciliation",
PendingStage::Disposal => "disposal",
}
}
const fn journal_id(value: JournalDisposition) -> &'static str {
match value {
JournalDisposition::NotApplied => "not-applied",
JournalDisposition::Applied => "applied",
JournalDisposition::Indeterminate => "indeterminate",
}
}
const fn provider_health_id(value: ProviderHealth) -> &'static str {
match value {
ProviderHealth::Healthy => "healthy",
ProviderHealth::Degraded => "degraded",
ProviderHealth::Exhausted => "exhausted",
ProviderHealth::Shutdown => "shutdown",
}
}