1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (c) 2025-2026 Federico Hoerth <memparanoid@gmail.com>
// SPDX-License-Identifier: GPL-3.0-only
// See LICENSE in the repository root for full license text.
extern crate alloc;
use Arc;
use ptr;
use ;
use crate::;
/// Runtime verification that zeroization happened before drop.
///
/// `ZeroizeOnDropSentinel` is a guard type used to verify that `.zeroize()` was called
/// before a value is dropped. This provides **runtime enforcement** of zeroization
/// invariants, complementing compile-time checks.
///
/// # Design
///
/// - Wraps a shared boolean flag (`Arc<AtomicBool>`) representing pristine state
/// - Initially `true` (pristine/untouched)
/// - `.zeroize()` sets the flag to `false` (no longer pristine)
/// - Can be cloned to verify zeroization from tests
///
/// # Panics
///
/// Panics on drop if `.zeroize()` was not called before drop. This is intentional:
/// forgetting to zeroize sensitive data is a critical bug that must be caught.
///
/// # Usage
///
/// Typically used as a field in structs to verify zeroization:
///
/// ```rust,ignore
/// use redoubt_zero_core::{ZeroizeOnDropSentinel, FastZeroizable};
///
/// struct Secret {
/// data: Vec<u8>,
/// __sentinel: ZeroizeOnDropSentinel,
/// }
///
/// impl Drop for Secret {
/// fn drop(&mut self) {
/// self.data.fast_zeroize();
/// self.__sentinel.fast_zeroize();
/// }
/// }
/// ```
///
/// The `__sentinel` field tracks whether `.zeroize()` was called before drop.
/// You'll need to implement `FastZeroizable`, `ZeroizationProbe`, and `AssertZeroizeOnDrop`
/// manually, or use the `RedoubtZero` umbrella crate which provides `#[derive(RedoubtZero)]`.
///
/// # Testing
///
/// Clone the sentinel to verify zeroization behavior:
///
/// ```rust
/// use redoubt_zero_core::ZeroizeOnDropSentinel;
/// use redoubt_zero_core::FastZeroizable;
///
/// let mut sentinel = ZeroizeOnDropSentinel::default();
/// let sentinel_clone = sentinel.clone();
///
/// assert!(!sentinel_clone.is_zeroized());
/// sentinel.fast_zeroize();
/// assert!(sentinel_clone.is_zeroized());
/// ```
;