SEC Module · Secure Enclave
TUM MSMCD SEC-Lab · Edu4Chip Didactic SoC · Student Subsystem 1

Encryption and decryption data path

The SEC module is attached to the SoC APB bus next to a RISC-V core. Software writes plaintext through the register interface; the hardware stores authenticated ciphertext in external NVM flash using ASCON, a PUF-derived key, and a monotonic nonce counter. This page follows one write and one read through the RTL hierarchy starting at tum_ss_system.sv.

scroll freely through the chapters
SEC MODULE — tum_ss · APB slave @ SS1 RISC-V MC Ibex core APB master runs the firmware APB Gateway status_ctrl addr decode · wr-seq FSM PREADY / PRDATA mux RDY BSY ENR KEY ERR DAT Main FSM main_fsm · system policy & sequencing M_READY irq_3 Nonce Counter counter_control · 39-bit 0x1A4 TX FIFO RX FIFO ASCON_Core ascon_control wrapper AEAD-128 · encrypt / decrypt Hash-256 · key validation key: — Fuzzy Extractor fe_subsystem PUF · BCH · helper data boot-time key recovery → see Startup & Enrollment QSPI spi_master_quad erase · prog · read WIP polling addr guard ⛨ NVM Flash W25Q64JV · 8 MB · on PMOD 0x000000 helper data W 2805 bits · 88 words · 352 B 0x000160 hash(K) · 8 words 0x000180 ENROLLED flag 0x001000 counter ceiling (obf.) 0x002000… records · 256 B pages target record layout — one 256 B page: AD 8 B ciphertext 232 B tag 16 B +0x00 +0x08 +0xF0
Scroll to inspect the data path.
The system at a glance

System-level flow

The SEC module connects a firmware-facing APB interface to an authenticated storage path. The Main FSM coordinates ASCON, a nonce counter, FIFOs, and the Quad-SPI master. Plaintext is accepted through the APB write path; external flash stores associated data, ciphertext, and authentication tags.

The diagram on the right updates with each section. Highlighted modules indicate which part of the implementation is active in the described phase.

Reading the colours: ■ plaintext / APB traffic · ■ ciphertext · ■ metadata, counters, AD · ■ key material, tags, control

Chapter 1 · shared: enc + dec

APB request format

The SoC talks to the SEC module through a plain AMBA APB slave port. Each transfer carries an address (PADDR, the lower 10 bits select one of the SEC registers), a direction (PWRITE), and on writes a 32-bit payload (PWDATA).

  • Writes complete with zero wait states. Side effects occur only in the ACCESS phase, when PSEL and PENABLE are both asserted.
  • Status reads are forwarded to the Main FSM; the gateway holds PREADY low for the round trip.
  • PSLVERR is never raised — errors are reported through status registers instead, and reads of invalid targets return the sentinel 0xDEAD_BEEF.

Encrypt request

Page address → 0x064, trigger 0x044, 58 plaintext words → 0x068…0x14C, trigger 0x044 again.

Decrypt request

A single write to 0x048 with the 24-bit flash page address.

Chapter 2 · shared: enc + dec

Gateway decoding and request staging

status_ctrl is the only block that ever touches the bus. It decodes the address into four regions: status registers, trigger registers, the debug-key window, and the 58-word data window.

During a write sequence, it counts exactly 58 consecutive word addresses into the TX FIFO and remembers every violation — a gap in the addresses, a 59th word, a full FIFO. When software closes the sequence at 0x044, the result is binary:

  • Valid sequence → a one-cycle tx_valid pulse posts a pending write request to the Main FSM.
  • Invalid sequenceseq_error is latched and the FIFO is flushed.

One request at a time. A single request slot holds the pending write or read request. A second request while one is outstanding is rejected and latches the sticky req_dropped bit (0x030[23]).

Chapter 3 · shared: enc + dec

Main FSM sequencing

The Main FSM is the top-level controller for the module. It validates requests, decides when the flash is erased, when the counter increments, which command ASCON runs, and when status flips back to ready.

Its control fan-out, visible on the right, reaches every subsystem:

  • ASCON — gets one of three commands: KEY_VALIDATE, ENCRYPT, DECRYPT.
  • CounterRESTORE at boot, INCREMENT per encryption.
  • QSPI — atomic FIFO entries: erase sector, program word, read word.
  • Fuzzy Extractor — only during boot (separate page).

While it is active, busy is high and new requests wait on the request slot. Every state is observable at 0x008 — the full map lives on the Main FSM page.

encryption path

Writing an authenticated record

Sequence after a valid 58-word write request is accepted.

Chapter 4 · encryption

Address validation and erase decision

The FSM first checks the target: the page address must lie in the application area (≥ 0x002000) and be 256-byte aligned. A bad address ends the request immediately with ERR_BAD_SECTOR — no flash access happens.

Flash programming requires an erased target region. To limit erase cycles, a 4 KB sector erase is issued only when the target is the first page of its sector. The 15 following pages program straight into the already-erased space.

  • Erase command travels as one atomic FIFO entry to the QSPI master.
  • The master runs Sector Erase (0x20) and polls the flash's busy flag until the sector reads blank.
  • The FSM waits for qspi_idle before touching the counter.
Chapter 5 · encryption

Nonce and associated data

AEAD encryption requires nonce uniqueness, so every encryption increments a 39-bit counter. Writing the counter to flash on every increment would increase wear; instead counter_control keeps a reservation ceiling in NVM: only once every 100 increments does it persist a new ceiling, always before the nonce is used. An interrupted operation can skip reserved values, but it does not reuse them.

From counter + address, the module derives ASCON's metadata:

nonce = { addr[23:0], 65'b0, counter[38:0] }   // 128 bit, unique per record
AD    = { backdoor_flag, counter[38:0], addr[23:0] }  // 64 bit

The two AD words are written to the page in plaintext because they must be read before decryption. They are still authenticated by the ASCON tag.

Chapter 6 · encryption

ASCON processing and flash programming

Now the FSM issues CMD_ENCRYPT and steps aside. ASCON pulls the 58 plaintext words out of the TX FIFO one by one, runs ASCON-AEAD128 with the PUF-derived key, and pushes each 32-bit ciphertext word straight into the QSPI command FIFO — addressed word-precisely into the page's ciphertext field.

  • The TX FIFO drains as ASCON consumes data; QSPI programming proceeds as ASCON produces ciphertext. Plaintext is not written to flash.
  • After the last message word, the core emits the 128-bit tag — four more words, landing at page offset 0xF0.
  • Back-pressure is wired through: if the QSPI FIFO fills, ASCON simply stalls.

No separate commit marker is used. A page is accepted only if its ASCON tag authenticates. Blank or modified pages fail the same check.

Chapter 7 · encryption

Completion and status update

The FSM counts outstanding QSPI commands and waits until the flash has physically committed every word (pending == 0 and the master idle). Only then:

  • operation_done pulses; if enabled, irq_3 fires.
  • The state returns to M_READY0x000 reads ready=1, busy=0.
  • The request slot is free; the next request may start.

Software that skipped the interrupt simply polls 0x000 until ready reappears, then checks error/0x004 for the result.

decryption path

Reading a record back

Read-back reconstructs the nonce and releases plaintext only after authentication succeeds.

Chapter 8 · decryption

Read request format

A read request is a single APB write to 0x048, carrying the 24-bit page address in PWDATA[23:0]. No payload follows — the request bypasses the data FIFO and lands directly in the request slot as rd_pending.

When the FSM is ready it validates the address with the same rules as a write (application area, page-aligned), then starts fetching.

vs. encryption

No erase, no counter increment, no TX data — the stored record already fixes nonce and AD.

read flow

Fetch AD → check metadata → fetch ciphertext+tag → decrypt → authenticate → release.

Chapter 9 · decryption

Fetch and metadata checks

The FSM reads the record in two passes. First the two AD words: they tell it which address and counter were used, and whether the record was written under the debug/fallback key. Two inexpensive checks run before decryption:

  • the address stored in the AD must equal the requested page, and
  • the record's key-source flag must match the key currently loaded — a record written under the PUF key is rejected in debug-key mode, and vice versa.

A mismatch aborts with ERR_AUTH before the flash is read any further. Otherwise the FSM streams all 62 ciphertext+tag words into an internal buffer, ready to feed ASCON.

Chapter 10 · decryption

Decryption before release

CMD_DECRYPT starts ASCON with the nonce rebuilt from the record's own AD — the stored counter and address, not whatever the requester claimed. The core consumes the 58 ciphertext words and the 4 tag words, producing plaintext into an internal buffer.

The release rule is enforced by an SVA assertion in the RTL: plaintext must not leave the internal buffer before the tag authenticates.

  • Tag valid → 58 plaintext words stream into the RX FIFO; the data-ready status bit rises.
  • Tag invalid → buffer is discarded, ERR_AUTH is latched, the RX FIFO stays empty.

Effect: a change in ciphertext or associated data causes authentication to fail, so modified records are not released as plaintext.

Chapter 11 · decryption

Software collects the plaintext

The hand-off back to firmware is a two-register protocol:

  • Poll 0x038 (RX_READY) until it reads 1.
  • Pop 0x03C (RX_DATA) — each read returns one word and advances the FIFO; 58 reads drain the record.

Required order: A read of 0x03C while no data is valid returns 0xDEAD_BEEF and raises rd_fail — which the FSM treats as a protocol error: it flushes the FIFOs and reports ERR_MC_PROTOCOL. Firmware should poll first, then pop data.

Epilogue

Summary of the complete flow

Plaintext crosses the hardware boundary only at the APB interface: inbound for encryption and outbound after authenticated decryption. Data stored in flash is encrypted and covered by an authentication tag.

Two kinds of failure exist, and they are deliberately different: request errors (bad address, protocol error, failed authentication) flush the FIFOs, report a code and return to M_READY; fatal errors (key recovery failure, flash address violation, counter corruption) move the module to M_FATAL_ERROR until reset.

Continue with:

Encryption vs. decryption — side by side

The two operations share most infrastructure but differ in counter handling, flash preparation, and data release. The chapters above already walk through both — this is a condensed recap for quick reference.

Show the full side-by-side comparison
Encrypt — write record
Decrypt — read record
Software request
Encrypt0x064 page addr · 0x044 start · 58 × data · 0x044 end
Decryptsingle write to 0x048 with page addr
Arbitration
Both directionsone pending request slot; extra requests latch the sticky req_dropped flag
Address rules
Both directionsapplication area only (≥ 0x002000), 256-byte page aligned, helper region hardware-blocked
Flash prep
Encrypt4 KB sector erase, only on the sector's first page
Decryptnone — read-only
Counter
Encrypt+1, ceiling persisted every 100 steps
Decryptuntouched — nonce comes from the record's AD
ASCON command
EncryptCMD_ENCRYPT: FIFO plaintext → flash ciphertext + tag
DecryptCMD_DECRYPT: buffered ciphertext → FIFO plaintext after auth
Security gate
Encryptfresh nonce guaranteed by reservation scheme
Decryptplaintext released only after tag authenticates (RTL assertion)
Result for SW
Encryptstatus ready + optional IRQ; record in NVM
Decryptpoll 0x038, pop 58 words from 0x03C
Typical errors
EncryptBAD_SECTOR, SEQ_ERROR, counter errors
DecryptAUTH (tag/AD mismatch), MC_PROTOCOL (early pop)