Skip to content

Commit 482c57b

Browse files
yyodsclaude
andcommitted
[docs] amend C3 NVS receipt to raw-slice reopening
The inventory-only post-OI NVS receipt bound only writer-time digests: a hand-written result could carry an arbitrary digest, size, and copied integrity summary that no later stage re-derived from real bytes. Amend the frozen C3.3 and create-result contracts per the v0.6.0 handoff: - capture the raw NVS slice (offset 0x9000, size 0x6000) immediately after the full OI workload, before threshold evaluation or any app/NVS setter; - require the exact fully-erased identity: 24,576 bytes, all 0xff, SHA-256 1df8949b2e345ab8c00cb81fb6b83686e20a4080f969e5cd8b8d520a07cdaba2; - bind the raw slice and acquisition log to the candidate, installed firmware, and exact OI raw digest; - reopen and re-hash the exclusive mode-0600 evidence files during result creation, completion, and finalization; never trust paths or copied summaries from a hand-written result; - a threshold failure may retain a diagnostic capture but must never mint a passing result. Amends the d6d4ccb receipt contract before the corresponding RED is amended. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CAVghCmvKjF4BZFBUjAMwc Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
1 parent befa792 commit 482c57b

2 files changed

Lines changed: 69 additions & 29 deletions

File tree

‎docs/specifications/firmware/browser-flashing.md‎

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,21 +2403,36 @@ The operation does not run a gate, infer a pass from a build, create a
24032403
threshold, or turn pending evidence into a result. This section freezes an
24042404
evidence-writing workflow and records no passed result.
24052405

2406-
For `esp32-c3-4mb`, `create-result` additionally requires one explicit
2407-
post-OI NVS inventory receipt path; Pico rejects that input. The receipt MUST
2408-
be canonical strict JSON in one stable, exclusive mode-`0600` regular file. It
2409-
contains no NVS values or device identity: only namespace/key/type inventory
2410-
and an exact summary with schema/profile, candidate `release.json` and merged
2411-
firmware SHA-256, the verify-mode OI raw-log SHA-256, exactly 10 reset samples,
2412-
NVS partition offset `0x9000` and size `0x6000`, integrity `passed`, and the
2413-
complete sorted written-namespace list. The writer derives the receipt's byte
2414-
length and SHA-256, requires its summary to match the inventory, rejects any
2415-
written `phy` namespace/key, and copies only the summary plus receipt binding
2416-
into the private result. Completion and finalization cross-check the retained
2417-
OI raw-log digest against the completed C3 observation. The public C3 summary
2418-
does not expose this private object; `qualification_result_sha256` binds it.
2419-
The already-required `provisioning_install: passed` remains the separate
2420-
full-chip-erase/install proof and is neither duplicated nor weakened.
2406+
For `esp32-c3-4mb`, `create-result` additionally requires three explicit
2407+
post-OI NVS evidence paths — the canonical inventory receipt, the raw NVS
2408+
slice, and its acquisition log; Pico rejects those inputs. Each MUST be a
2409+
stable, exclusive mode-`0600` regular file, the receipt as canonical strict
2410+
JSON. The receipt contains no NVS values or device identity: only
2411+
namespace/key/type inventory and an exact summary with schema/profile,
2412+
candidate `release.json` and merged firmware SHA-256, the verify-mode OI
2413+
raw-log SHA-256, exactly 10 reset samples, NVS partition offset `0x9000` and
2414+
size `0x6000`, integrity `passed`, the complete sorted written-namespace
2415+
list, and the raw slice and acquisition log bound by exact SHA-256 and byte
2416+
length. The slice was captured by the verify-mode runner immediately after
2417+
the full OI workload — before numeric threshold evaluation and before any
2418+
app/NVS setter — and MUST be exactly 24,576 bytes, all `0xff`, SHA-256
2419+
`1df8949b2e345ab8c00cb81fb6b83686e20a4080f969e5cd8b8d520a07cdaba2`. The
2420+
earlier single-receipt design is superseded as bypassable: no stage
2421+
re-derived the embedded digest, size, or `integrity: passed` summary from
2422+
real evidence bytes. The writer therefore reopens all three files, re-derives
2423+
every digest and byte length from the reopened bytes, re-verifies the exact
2424+
all-`0xff` slice identity, requires the summary to match both the inventory
2425+
and the reopened evidence, rejects any written `phy` namespace/key, and
2426+
copies only the summary plus receipt binding into the private result.
2427+
Completion and finalization MUST again reopen and re-hash the same exclusive
2428+
mode-`0600` evidence files and cross-check the retained OI raw-log digest
2429+
against the completed C3 observation; they never trust a path, digest, size,
2430+
or copied summary from a hand-written result. A threshold failure may retain
2431+
the captured slice and log as private diagnostics but can never mint a
2432+
passing result. The public C3 summary does not expose these private objects;
2433+
`qualification_result_sha256` binds them transitively. The already-required
2434+
`provisioning_install: passed` remains the separate full-chip-erase/install
2435+
proof and is neither duplicated nor weakened.
24212436

24222437
The four ESP records use `resource_kind: "esp-idf"` and
24232438
`provisioning_kind: "esp-web-serial"`. Each additionally has exact

‎docs/specifications/firmware/ports/esp32-c3-4mb.md‎

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,45 @@ Every candidate using this setting MUST receive a full-chip erase before the
8686
exact verified install. An application-only reflash can retain the old PHY NVS
8787
pages and does not qualify the fixed bytes. After the erased install, the
8888
existing 10 controlled C3-G4 reset samples MUST still pass the 3,000 ms ceiling
89-
and every frozen heap floor. A read-only NVS namespace/key/type inventory taken
90-
after those repeated resets MUST pass partition integrity checks and contain no
91-
written `phy` namespace or key; values are neither required nor retained as
92-
public evidence. The C3 private-result writer MUST require that inventory as a
93-
stable, exclusive mode-`0600` canonical receipt. It derives and stores the
94-
receipt's exact SHA-256 and byte length plus a candidate-bound summary; the
95-
summary binds the candidate release and firmware digests, the exact OI raw-log
96-
digest, 10 reset samples, NVS offset `0x9000`, size `0x6000`, integrity pass,
97-
and the complete written namespace list. The writer rejects a missing,
98-
changed, malformed, non-exclusive, wrong-candidate, wrong-offset,
99-
wrong-size, integrity-failed, or `phy`-containing receipt. Finalization MUST
100-
cross-check its OI raw-log binding against the completed C3 observation. The
101-
public summary omits the private receipt body; its private-result digest binds
102-
the validated receipt transitively. The application and VFS regions remain
89+
and every frozen heap floor.
90+
91+
Immediately after the full OI workload completes — before any numeric
92+
threshold evaluation and before any application code or NVS setter runs — the
93+
verify-mode runner MUST capture the raw NVS partition slice over the
94+
still-open session: offset `0x9000`, size `0x6000`. Because this profile
95+
disables PHY-calibration persistence and the frozen workload writes no NVS
96+
entry, the captured slice MUST be exactly 24,576 bytes with every byte `0xff`
97+
and SHA-256
98+
`1df8949b2e345ab8c00cb81fb6b83686e20a4080f969e5cd8b8d520a07cdaba2` — the
99+
fully erased partition. Any other content fails the gate. The capture writes
100+
two exclusive mode-`0600` regular files, the raw slice and its acquisition
101+
log; neither is public evidence. The read-only namespace/key/type inventory
102+
taken from that slice MUST pass partition integrity checks and contain no
103+
written `phy` namespace or key.
104+
105+
The C3 private-result writer MUST require the inventory as a stable,
106+
exclusive mode-`0600` canonical receipt together with the raw slice and
107+
acquisition-log files. The receipt's candidate-bound summary binds the
108+
candidate release and firmware digests, the exact OI raw-log digest, 10 reset
109+
samples, NVS offset `0x9000`, size `0x6000`, integrity pass, the complete
110+
written namespace list, and the raw slice and acquisition log by exact
111+
SHA-256 and byte length. The earlier inventory-only receipt design is
112+
superseded as bypassable: a hand-written result could embed an arbitrary
113+
digest, size, and copied `integrity: passed` summary that no later stage
114+
re-derived from real bytes. Therefore result creation, completion, and
115+
finalization MUST each independently reopen the actual receipt, raw-slice,
116+
and acquisition-log files, require them to be stable, exclusive mode-`0600`
117+
regular files, re-derive every digest and byte length from the reopened
118+
bytes, and re-verify the slice's exact all-`0xff` identity. No stage may
119+
trust a path, digest, size, or summary copied from a hand-written result.
120+
The writer rejects a missing, changed, malformed, non-exclusive,
121+
wrong-candidate, wrong-offset, wrong-size, wrong-slice, integrity-failed, or
122+
`phy`-containing receipt. Finalization MUST additionally cross-check the OI
123+
raw-log binding against the completed C3 observation. A numeric threshold
124+
failure may retain the captured slice and log as private diagnostic
125+
evidence, but a failed run MUST NOT mint any passing result. The public
126+
summary omits the private receipt body; its private-result digest binds the
127+
validated receipt transitively. The application and VFS regions remain
103128
subject to their existing exact-byte and functional checks.
104129

105130
The existing V5 `provisioning_install: passed` check remains the mechanical

0 commit comments

Comments
 (0)