osdp/secure/mod.rs
1//! Secure Channel — Annex D.
2//!
3//! # Spec: Annex D
4//!
5//! Three layers:
6//!
7//! 1. [`crypto`] — primitives: AES-128, key derivation, cryptograms.
8//! 2. [`mac`] — CBC-MAC with the S-MAC1/S-MAC2 swap on the final block.
9//! 3. [`session`] — type-state machine wrapping the above into a usable API.
10//!
11//! Padding is described in [`pad`]. The full handshake is rendered in
12//! [`handshake`].
13
14pub mod cipher;
15pub mod crypto;
16pub mod frame;
17pub mod mac;
18pub mod pad;
19pub mod session;
20
21/// Annex D.4 secure-channel handshake.
22///
23/// Both sides start out sharing only the SCBK (out-of-band install key, or a
24/// previously-keyset session key). The handshake derives matching session
25/// keys, proves possession to each end, and seeds the rolling-ICV chain that
26/// every subsequent SCS_15..=18 frame uses.
27///
28#[cfg_attr(feature = "_docs", aquamarine::aquamarine)]
29/// ```mermaid
30/// sequenceDiagram
31/// participant ACU
32/// participant PD
33/// Note over ACU,PD: Both share SCBK out-of-band
34/// ACU->>PD: osdp_CHLNG (RND.A)
35/// PD->>PD: derive S-ENC, S-MAC1, S-MAC2 from SCBK ⊕ RND.A
36/// PD->>PD: pick RND.B; compute ClientCryptogram
37/// PD->>ACU: osdp_CCRYPT (cUID, RND.B, ClientCryptogram)
38/// ACU->>ACU: derive same keys; verify ClientCryptogram
39/// ACU->>ACU: compute ServerCryptogram
40/// ACU->>PD: osdp_SCRYPT (ServerCryptogram)
41/// PD->>PD: verify ServerCryptogram; compute initial R-MAC
42/// PD->>ACU: osdp_RMAC_I (initial R-MAC)
43/// ACU->>ACU: verify R-MAC matches own
44/// Note over ACU,PD: Session is Secure;<br/>SCS_15..=18 frames carry rolling ICV
45/// ```
46pub mod handshake {}
47
48pub use frame::{Direction, seal, unseal};
49pub use session::{Challenged, Cryptogrammed, Disconnected, Secure, Session};
50
51/// Default install key (`SCBK-D`): bytes `0x30..=0x3F`.
52///
53/// # Spec: Annex D.8
54pub const SCBK_D: [u8; 16] = [
55 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
56];