Main control FSM for boot and record operations
The SEC module uses one top-level state machine to coordinate boot, key reconstruction, authenticated encryption, authenticated decryption, flash access, and error handling. The map below groups the 47 encoded states into functional lanes. Select a state to inspect its entry condition, wait condition, actions, and next states, or trace one of the representative flows.
REQ/WAIT state pairs are drawn as one box; error transitions are simplified — the exact set is in each state's detail panel and the table below. Dashed red = paths into the error states.
Functional lanes
Boot
Waits for flash initialization, then reads the ENROLLED flag to choose between initial enrollment and key reconstruction. This path runs automatically after reset and is not started or repeated through APB.
Enrollment
Generates the key from the PUF response, writes helper data, the key fingerprint, the counter ceiling, and finally the enrollment flag. This path is intended for the first successful boot. Detail: Startup & Enrollment.
Reconstruction
Restores the nonce counter from its NVM reservation ceiling, reconstructs the key through the fuzzy extractor, and verifies the recovered key against the stored fingerprint. A mismatch enters the fatal-error state.
Ready
The state that accepts new work. Pending requests are consumed in priority order: debug key loading first, then the single outstanding write or read. Sequence errors and premature RX reads are also converted into request errors here.
Write / Encrypt
Validates the page address, erases the sector when required, increments the nonce counter, persists a new counter ceiling when required, writes associated data, streams ASCON ciphertext and tag, and waits for flash completion.
Read / Decrypt
Validates the address, reads and checks the associated data, buffers the ciphertext and tag, and runs ASCON decryption. Plaintext is released to the RX FIFO only after the authentication tag is accepted.
Debug key loading
Loads a firmware-supplied 128-bit key into ASCON (4 words plus GO over APB). This request has priority over pending data requests and marks key_source until reset. Records written with this key are marked in their associated data.
Error classes
Request errors flush the FIFOs, pulse done, and return to ready. Fatal errors, such as FE failure, flash address violation, counter corruption, or provisioning-time ASCON faults, keep the FSM in the fatal-error state until reset.
All 47 states
Exactly as encoded in main_fsm.sv (enum order = the value readable at offset 0x008).
| # | State | Lane | What it does / waits for |
|---|---|---|---|
| 0 | M_RESET | boot | One-cycle state after reset. |
| 1 | M_BOOT_WAIT_SPI | boot | Waits for the QSPI master's flash init (Quad-Enable) to finish. |
| 2 | M_BOOT_FLAG_REQ | boot | Enqueues the read of the ENROLLED flag (0x000180). |
| 3 | M_BOOT_FLAG_WAIT | boot | Receives the flag; branches: 0x01… → reconstruct, else → enroll. |
| 4 | M_BOOT_COUNTER_REQ | recon | Enqueues reads of the 2 counter-ceiling words (0x001000). |
| 5 | M_BOOT_COUNTER_WAIT | recon | Buffers the 2 words for counter_control. |
| 6 | M_COUNTER_RESTORE_CMD | recon | Issues CTR_CMD_RESTORE to counter_control. |
| 7 | M_COUNTER_RESTORE_WAIT | recon | Waits for decode of the obfuscated ceiling; bad padding → fatal. |
| 8 | M_FE_ENROLL_START | enroll | Pulses fe_start with mode = enrollment. |
| 9 | M_FE_ENROLL_WAIT_R | enroll | Waits for the FE to deliver the 128-bit key R (r_out_valid). |
| 10 | M_KEY_PROVISION_CMD | enroll | Issues ASCON KEY_VALIDATE with no stored hash → provision mode. |
| 11 | M_KEY_PROVISION_STREAM | enroll | Streams the 8 hash words ASCON emits into the QSPI FIFO (→ 0x000160). |
| 12 | M_KEY_COUNTER_INIT_REQ | enroll | Writes the initial encoded counter ceiling (2 words → 0x001000). |
| 13 | M_KEY_FLAG_WRITE | enroll | Writes the ENROLLED flag — deliberately the last word. |
| 14 | M_KEY_COMMIT_WAIT | enroll | Waits until flash is idle, FE done and ASCON reports the key valid. |
| 15 | M_FE_RECON_START | recon | Pulses fe_start with mode = reconstruction. |
| 16 | M_FE_RECON_WAIT_R | recon | Waits for the recovered key R from the FE. |
| 17 | M_KEY_HASH_READ_REQ | recon | Enqueues reads of the 8 stored hash words. |
| 18 | M_KEY_HASH_READ_WAIT | recon | Buffers the stored hash for comparison. |
| 19 | M_KEY_COMPARE_CMD | recon | Issues ASCON KEY_VALIDATE in compare mode (hash_stored = 1). |
| 20 | M_KEY_COMPARE_WAIT | recon | Hash match + FE done → ready; mismatch → fatal. |
| 21 | M_READY | hub | Idle; accepts debug-key > write > read requests, converts protocol errors. |
| 22 | M_BACKDOOR_CMD | debug key | Issues KEY_VALIDATE with backdoor_i = 1; ASCON pulls 4 key words from the TX FIFO. |
| 23 | M_BACKDOOR_WAIT | debug key | Key accepted → key_source is set until reset, done pulse; failure → request error. |
| 24 | M_WR_VALIDATE | write | Checks page ≥ 0x002000 and 256-B aligned; decides whether to erase. |
| 25 | M_WR_ERASE_REQ | write | Enqueues the 4 KB sector erase (only on the sector's first page). |
| 26 | M_WR_ERASE_WAIT | write | Waits for erase completion (WIP polling, FIFO drained). |
| 27 | M_WR_COUNTER_CMD | write | Issues CTR_CMD_INCREMENT — one nonce per encryption. |
| 28 | M_WR_COUNTER_DECIDE | write | Ceiling crossed? → persist new ceiling first; else straight on. |
| 29 | M_WR_COUNTER_ERASE_REQ | write | Enqueues erase of the counter sector. |
| 30 | M_WR_COUNTER_ERASE_WAIT | write | Waits for the counter-sector erase. |
| 31 | M_WR_COUNTER_STREAM | write | Streams the 2 encoded ceiling words to flash. |
| 32 | M_WR_RECORD_AD_REQ | write | Writes the 2 plaintext AD words {flag, counter, address} into the page. |
| 33 | M_WR_ENCRYPT_CMD | write | Issues CMD_ENCRYPT (58 message words) to ASCON. |
| 34 | M_WR_ENCRYPT_STREAM | write | Routes 58 ct + 4 tag words from ASCON into the QSPI FIFO, word-addressed. |
| 35 | M_WR_PACKET_WAIT | write | Waits until every queued program command physically completed. |
| 36 | M_WR_DONE | write | operation_done pulse + optional IRQ; back to ready. |
| 37 | M_RD_VALIDATE | read | Same address rules as write; no erase, no counter. |
| 38 | M_RD_AD_REQ | read | Enqueues reads of the 2 AD words. |
| 39 | M_RD_AD_WAIT | read | Checks AD address == requested page and key-source flag == current key source; else ERR_AUTH. |
| 40 | M_RD_PACKET_REQ | read | Enqueues reads of the 62 ciphertext + tag words. |
| 41 | M_RD_PACKET_WAIT | read | Buffers the packet in packet_buf. |
| 42 | M_RD_DECRYPT_CMD | read | Issues CMD_DECRYPT with nonce metadata from the record's AD. |
| 43 | M_RD_DECRYPT_STREAM | read | Feeds ct+tag to ASCON; on auth OK plaintext flows to the RX FIFO, else ERR_AUTH. |
| 44 | M_RD_DONE | read | operation_done pulse + optional IRQ; back to ready. |
| 45 | M_REQUEST_ERROR | error | Recoverable: flush FIFOs, done pulse + IRQ, return to ready. Code stays at 0x004. |
| 46 | M_FATAL_ERROR | error | Sticky: flush, IRQ, remain here until reset. Set by FE/QSPI-guard/counter/provision faults. |
Observability: the current state value is always readable at offset
0x008; ASCON's own FSM at 0x014, the counter FSM inside
0x01C/0x028. See the
register reference.