feat(prodtest): restrict access to 64 MAC-and-destroy slots
What changed, and why it matters
This commit tightens access permissions in the Trezor production-test firmware for a secure chip feature called 'MAC-and-destroy' slots. It removes Pairing Key 1's ability to use the first 64 of these one-time slots, leaving only Pairing Key 2 (and in some configurations Pairing Key 3) with access. MAC-and-destroy slots are designed to be permanently destroyed after use, so restricting who can reach them reduces the risk that a less-trusted key could waste or misuse them during manufacturing tests.
Treat as a routine hardening improvement. If this commit is being backported or audited, verify that Pairing Key 1 genuinely does not need MAC-and-destroy slots 0-63 in the factory workflow, and confirm the change is applied consistently across all relevant provisioning configurations and product revisions.
Security signals we found
Principle-of-least-privilege hardening for one-time secure-element slots
Change is in prodtest (factory/production test) code, not end-user firmware
MAC-and-destroy slots are irreversible resources; misuse can permanently exhaust them
No CVE, advisory, or researcher attribution present in commit materials
Evidence from the diff
The change updates two lt_config_t structures (irreversible_configuration and reversible_configuration) in core/embed/projects/prodtest/cmd/prodtest_tropic.c. The CFG_UAP_MAC_AND_DESTROY (0x160) bitmask is modified so that Pairing Key 1 no longer has access to MACANDD_0_31 and MACANDD_32_63. In the irreversible config, bits 1 and 9 are now cleared; in the reversible config, bits 1 and 9 are removed from the explicit allow mask. This is a hardening change in factory-provisioning tooling, not a runtime wallet fix.
Changed components
core/embed/projects/prodtest/cmd/prodtest_tropic.cTropic secure-element provisioning configuration (CFG_UAP_MAC_AND_DESTROY)Trezor production-test / factory-provisioning toolingInspect captured patch +7 / −6
diff --git a/core/embed/projects/prodtest/.changelog.d/5845.changed b/core/embed/projects/prodtest/.changelog.d/5845.changed
new file mode 100644
index 000000000..27808fdbd
--- /dev/null
+++ b/core/embed/projects/prodtest/.changelog.d/5845.changed
@@ -0,0 +1 @@
+Make `tropic-lock()` restrict access to 64 MAC-and-destroy slots.
diff --git a/core/embed/projects/prodtest/cmd/prodtest_tropic.c b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
index fb3bae91c..7a2bb0f7b 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_tropic.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
@@ -265,11 +265,11 @@ static struct lt_config_t irreversible_configuration = {
// # CFG_UAP_MAC_AND_DESTROY (0x160)
// | Setting | Pairing Key 0 | Pairing Key 1 | Pairing Key 2 | Pairing Key 3 |
// |--------------------------|---------------|---------------|---------------|---------------|
- // | MACANDD_0_31 | 0 (bit 0) | 1 (bit 1) | 1 (bit 2) | 1 (bit 3) |
- // | MACANDD_32_63 | 0 (bit 8) | 1 (bit 9) | 1 (bit 10) | 1 (bit 11) |
+ // | MACANDD_0_31 | 0 (bit 0) | 0 (bit 1) | 1 (bit 2) | 1 (bit 3) |
+ // | MACANDD_32_63 | 0 (bit 8) | 0 (bit 9) | 1 (bit 10) | 1 (bit 11) |
// | MACANDD_64_95 | 0 (bit 16) | 1 (bit 17) | 1 (bit 18) | 1 (bit 19) |
// | MACANDD_96_127 | 0 (bit 24) | 1 (bit 25) | 1 (bit 26) | 1 (bit 27) |
- ~0U & ~BIT(0) & ~BIT(8) & ~BIT(16) & ~BIT(24),
+ ~0U & ~BIT(0) & ~BIT(1) & ~BIT(8) & ~BIT(9) & ~BIT(16) & ~BIT(24),
}};
// TODO: Adjust the configuration to match the revision of the provisioned
@@ -474,11 +474,11 @@ static struct lt_config_t reversible_configuration = {
// # CFG_UAP_MAC_AND_DESTROY (0x160)
// | Setting | Pairing Key 0 | Pairing Key 1 | Pairing Key 2 | Pairing Key 3 |
// |--------------------------|---------------|---------------|---------------|---------------|
- // | MACANDD_0_31 | 0 (bit 0) | 1 (bit 1) | 1 (bit 2) | 0 (bit 3) |
- // | MACANDD_32_63 | 0 (bit 8) | 1 (bit 9) | 1 (bit 10) | 0 (bit 11) |
+ // | MACANDD_0_31 | 0 (bit 0) | 0 (bit 1) | 1 (bit 2) | 0 (bit 3) |
+ // | MACANDD_32_63 | 0 (bit 8) | 0 (bit 9) | 1 (bit 10) | 0 (bit 11) |
// | MACANDD_64_95 | 0 (bit 16) | 1 (bit 17) | 1 (bit 18) | 0 (bit 19) |
// | MACANDD_96_127 | 0 (bit 24) | 1 (bit 25) | 1 (bit 26) | 0 (bit 27) |
- BIT(1) | BIT(2) | BIT(9) | BIT(10) | BIT(17) | BIT(18) | BIT(25) | BIT(26),
+ BIT(2) | BIT(10) | BIT(17) | BIT(18) | BIT(25) | BIT(26),
}};
// clang-format on
Why this scored 42/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.