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
//! The [`HardwareProvider`] seam — the whole contract a platform binding must
//! satisfy.
//!
//! # Why the seam is this narrow
//!
//! A hardware trusted component cannot wrap a keystore blob directly. A TPM 2.0
//! key reached through CNG is asymmetric (RSA/ECC) and bounded by the modulus
//! size; a Secure Enclave key is a P-256 key that never leaves the chip. So the
//! envelope is **hybrid**: a random 32-byte content key encrypts the blob with
//! AES-256-GCM in this crate, and the hardware only ever wraps *that key*.
//!
//! Keeping the trait to two 32-byte operations means each platform binding is a
//! few dozen lines of FFI instead of a second envelope format, and every
//! platform shares one audited AEAD path.
//!
//! # Where implementations will live
//!
//! **No platform provider ships yet** — this release contains the trait and the
//! envelope, and nothing that binds to real hardware. Passing no provider
//! resolves [`Software(NotRequested)`](super::DegradeReason::NotRequested).
//!
//! This package sets `unsafe_code = "forbid"` as a spec-pinned security property
//! (`SPEC.md` §12/§13.2, conformance C-15), so raw CNG / Security Framework FFI
//! cannot live here. Real bindings are therefore *planned* for a separate
//! `hardware/` workspace member (`dig-keystore-hardware`) that will mirror the
//! existing `wasm/` split, tracked as **dig_ecosystem #1693**; they will be
//! injected through this trait.
use Zeroizing;
use ;
use crateResult;
/// Length of the symmetric content key a provider wraps.
pub const CONTENT_KEY_LEN: usize = 32;
/// The content key that a hardware provider wraps and unwraps.
///
/// Zeroized on drop: this is the only plaintext key material that transits the
/// provider boundary.
pub type ContentKey = ;
/// Where a provider's wrapping key physically lives.
///
/// This is the property hardware binding actually buys, so it is reported
/// explicitly rather than inferred from the provider's name.
/// A binding to one OS hardware trusted component.
///
/// Implementations are injected into
/// [`HardwareBoundBackend`](super::HardwareBoundBackend), which probes and
/// self-tests them before claiming a hardware tier — an implementation is never
/// taken at its word.