1#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
5#[non_exhaustive]
6pub enum WipeEvidence {
7 WipeNotCompleted,
9 WipedBestEffort,
11 WipedAttested,
13}
14
15#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
17#[non_exhaustive]
18pub enum PhysicalProtection {
19 ProtectionAttested,
21 ProtectionConfirmedAbsent,
23 ProtectionUnknown,
25}
26
27#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
29#[non_exhaustive]
30pub enum AccountingPosture {
31 Charged,
33 Reconciled,
35}
36
37#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
39#[non_exhaustive]
40pub enum PendingStage {
41 Wipe,
43 ProtectionRemoval,
45 AccountingReconciliation,
47 Disposal,
49}
50
51#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
53#[non_exhaustive]
54pub enum LifecyclePosture {
55 Live,
57 Closing {
59 stage: PendingStage,
61 },
62 Quarantined {
64 pending_stage: PendingStage,
66 },
67 PermanentlyQuarantined {
69 pending_stage: PendingStage,
71 },
72 Tombstoned {
74 last_stage: PendingStage,
76 disposition: AllocationPresence,
78 },
79 Closed,
81}
82
83#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
85#[non_exhaustive]
86pub enum AllocationPresence {
87 Unknown,
89}
90
91#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
93#[non_exhaustive]
94pub enum ProviderHealth {
95 Healthy,
97 Degraded,
99 Exhausted,
101 Shutdown,
103}
104
105#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
107#[non_exhaustive]
108pub enum ResourceKind {
109 Identities,
111 LogicalBytes,
113 EffectivePages,
115 RegistryEntries,
117 RetryAttempts,
119 MaintenanceWork,
121}
122
123#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
125pub struct ProviderLimits {
126 pub max_identities: usize,
128 pub max_logical_bytes: usize,
130 pub max_effective_pages: usize,
132 pub max_registry_entries: usize,
134 pub max_retry_attempts: usize,
136 pub max_maintenance_work: usize,
138 pub page_size: usize,
140}
141
142#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
144pub struct ProtectionRequest {
145 logical_bytes: usize,
146 reserved_pages: usize,
147 attested: bool,
148}
149
150impl ProtectionRequest {
151 pub(crate) fn new(
152 logical_bytes: usize,
153 page_size: usize,
154 attested: bool,
155 ) -> Result<Self, ProtectionError> {
156 if page_size == 0 {
157 return Err(ProtectionError::InvalidLimits);
158 }
159 let reserved_pages = if logical_bytes == 0 {
160 0
161 } else {
162 logical_bytes
163 .checked_add(page_size - 1)
164 .and_then(|len| len.checked_add(page_size - 1))
165 .map(|worst_case| worst_case / page_size)
166 .ok_or(ProtectionError::LengthOverflow)?
167 };
168 Ok(Self {
169 logical_bytes,
170 reserved_pages,
171 attested,
172 })
173 }
174
175 #[must_use]
177 pub const fn logical_bytes(self) -> usize {
178 self.logical_bytes
179 }
180
181 #[must_use]
183 pub const fn reserved_pages(self) -> usize {
184 self.reserved_pages
185 }
186
187 #[must_use]
189 pub const fn requires_attestation(self) -> bool {
190 self.attested
191 }
192}
193
194#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
196#[non_exhaustive]
197pub enum ProtectionError {
198 StaleAssurance,
200 ProtectionUnavailable,
202 ProviderUnavailable,
204 ProtectionResourceExhausted(ResourceKind),
206 LengthOverflow,
208 InvalidLimits,
210 ActualRangeExceededReservation,
212}
213
214impl core::fmt::Display for ProtectionError {
215 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
216 formatter.write_str(match self {
217 Self::StaleAssurance => "stale assurance evidence",
218 Self::ProtectionUnavailable => "required protected storage is unavailable",
219 Self::ProviderUnavailable => "protected-memory provider is unavailable",
220 Self::ProtectionResourceExhausted(_) => "protected-memory resource exhausted",
221 Self::LengthOverflow => "protected-memory length overflow",
222 Self::InvalidLimits => "invalid protected-memory limits",
223 Self::ActualRangeExceededReservation => {
224 "actual protected range exceeded its reservation"
225 }
226 })
227 }
228}
229
230#[cfg(feature = "std")]
231impl std::error::Error for ProtectionError {}
232
233#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
235#[non_exhaustive]
236pub enum TeardownOperation {
237 Wipe,
239 ProtectionRemoval,
241 AccountingReconciliation,
243 Disposal,
245}
246
247#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
249#[non_exhaustive]
250pub enum JournalDisposition {
251 NotApplied,
253 Applied,
255 Indeterminate,
257}
258
259#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
261pub struct TeardownCursor {
262 pub operation: TeardownOperation,
264 pub disposition: JournalDisposition,
266 pub progress: usize,
268}
269
270impl TeardownCursor {
271 pub(crate) const fn new() -> Self {
272 Self {
273 operation: TeardownOperation::Wipe,
274 disposition: JournalDisposition::NotApplied,
275 progress: 0,
276 }
277 }
278
279 pub(crate) fn begin(&mut self, operation: TeardownOperation) {
280 self.operation = operation;
281 self.disposition = JournalDisposition::NotApplied;
282 self.progress = 0;
283 }
284}
285
286#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
288#[non_exhaustive]
289pub enum DisposalDisposition {
290 Applied,
292 NotApplied,
294 AllocationPresenceUnknown,
296}
297
298#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
300#[non_exhaustive]
301pub enum CleanupOutcome {
302 Closed,
304}
305
306#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
308pub struct CleanupReport {
309 pub outcome: CleanupOutcome,
311 pub wipe: WipeEvidence,
313 pub physical_protection: PhysicalProtection,
315 pub accounting: AccountingPosture,
317 pub lifecycle: LifecyclePosture,
319}
320
321#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
323pub struct CleanupError {
324 pub pending_stage: PendingStage,
326 pub wipe: WipeEvidence,
328 pub physical_protection: PhysicalProtection,
330 pub accounting: AccountingPosture,
332 pub lifecycle: LifecyclePosture,
334 pub pending_substage: JournalDisposition,
336 pub retry_attempt: usize,
338 pub provider_health: ProviderHealth,
340}
341
342impl core::fmt::Display for CleanupError {
343 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
344 write!(
345 formatter,
346 "protected cleanup stopped at {:?}",
347 self.pending_stage
348 )
349 }
350}
351
352#[cfg(feature = "std")]
353impl std::error::Error for CleanupError {}
354
355#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
357pub struct ProviderReport {
358 pub health: ProviderHealth,
360 pub health_generation: usize,
362 pub protection_generation: usize,
364 pub active_and_reserved: usize,
366 pub quarantined: usize,
368 pub permanently_quarantined: usize,
370 pub tombstoned: usize,
372 pub charged_logical_bytes: usize,
374 pub charged_effective_pages: usize,
376}