Skip to main content

hsm_crypto_service/
slots.rs

1// Copyright (c) 2026 Tuloup Simon
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16//! Slot-mapping convention used by this firmware.
17//!
18//! Slot allocation is *project policy*, not a chip primitive. The same chip
19//! could be programmed differently. Putting the convention in one place keeps
20//! it visible and reviewable.
21//!
22//! The authoritative reference is docs/config-zone-layout.md. This module
23//! exposes named constants for the slots the service code references; it
24//! must stay in sync with the configuration zone the chip is provisioned
25//! with.
26//!
27//! | Slot  | Type        | Purpose                                | Policy summary                                                |
28//! |-------|-------------|----------------------------------------|---------------------------------------------------------------|
29//! | 0     | ECC P-256   | Primary identity, GenKey-only          | `ReqAuth`=1, `AuthKey`=5 (PIN-gated). `PrivWrite` forbidden.    |
30//! | 1     | ECC P-256   | Secondary identity, GenKey-only        | Same as slot 0.                                               |
31//! | 2-4   | ECC P-256   | User keys, `GenKey` + encrypted import   | PIN-gated. Lockable individually.                             |
32//! | 5     | Data 32 B   | PIN hash `SHA256(PIN \|\| salt)`       | `EncryptWrite` via slot 8. `LimitedUse` via Counter0 (cap 5).     |
33//! | 6     | Data 32 B   | PUK hash `SHA256(PUK \|\| salt)`       | `EncryptWrite` via slot 8. `LimitedUse` via Counter1 (cap 10).    |
34//! | 7     | ECC P-256   | User key, `GenKey` + encrypted import    | Same as slots 2-4.                                            |
35//! | 8     | Data 32 B   | I/O Protection master key              | Written pre-data-lock, immutable after. Never written again.  |
36//! | 9-15  | ECC P-256   | Reserve for V2                         | Same configuration as slots 2-4/7, kept unused for now.       |
37//!
38//! Notes
39//! -----
40//!
41//! - Slots **2-4 and 7** all share the same configuration as user-rotatable
42//!   ECC keys with PIN gating. They are interchangeable from the policy
43//!   point of view. Project conventions may earmark them for specific
44//!   roles in the future.
45//! - **Slots 9-15** are configured exactly like user slots so they can be
46//!   used in a later iteration without re-provisioning. Treat them as
47//!   reserve, do not rely on their contents until a future revision
48//!   explicitly assigns them.
49
50use atecc608b::Slot;
51
52use crate::pin::PIN_LEN;
53
54/// Slot holding the SHA-256 hash of the PIN.
55pub(crate) const SLOT_PIN_HASH: Slot = Slot::const_new(5);
56/// Slot holding the SHA-256 hash of the PUK.
57pub(crate) const SLOT_PUK_HASH: Slot = Slot::const_new(6);
58/// Slot holding the I/O protection master key.
59pub(crate) const SLOT_IO_KEY: Slot = Slot::const_new(8);
60
61/// Size of one PIN batch on Counter0. The "effective tries" available
62/// to the user inside a batch is `PIN_MAX_RETRIES - 1` (= 4), because
63/// `refresh_counter_batch` lands `count` one past the next multiple so
64/// that `count % PIN_MAX_RETRIES == 0` is an unambiguous saturation
65/// signal usable by `emergency_reset`. See `service::retries_remaining`.
66pub(crate) const PIN_MAX_RETRIES: u8 = 5;
67
68/// Size of one PUK batch on Counter1. Effective tries inside a batch
69/// is `PUK_MAX_RETRIES - 1` (= 9), for the same reason as
70/// [`PIN_MAX_RETRIES`].
71pub(crate) const PUK_MAX_RETRIES: u8 = 10;
72
73/// Default PIN at factory provisioning. Must be changed on first use.
74pub(crate) const PIN_DEFAULT: [u8; PIN_LEN] = *b"0000";