Appendix: Foundational Principles of KLE

This chapter is informative.

This chapter states sixteen Design Principles and nine Design Decisions taken from them, from which the General Rules of Unprivileged Architecture: Instructions and Architectural States follow, apart from the choices listed in the final section. The Decisions could be revisited without changing the Principles. No Principle is stated in terms of an individual instruction: each rule should read as one Principle applied to one instruction or State class.

Two texts take precedence over this chapter:

The SR rules are cited where a Principle or a Decision motivates them, and are not covered.

Vocabulary

The Principles use only the instruction and state classes defined as follows.

State classes.

  • Unconfigured: the locker holds no CC; State and StateExtension are 0.

  • Valid States: the locker holds a usable CC.

  • Error States: the locker holds only an MDH, which records why its CC became unusable; State is 0 and StateExtension holds the code.

  • Configuration States: the CC is in transit, i.e., being provisioned, imported or exported.

  • Complete = Valid ∪ Error.

  • Inert = Unconfigured ∪ Error: State 0, no Content. A locker named by KLNL with klnamedlocker = 32 is not there at all, and is inert (klnamedlocker).

Instruction classes.

  • Usage instructions operate on the CC through the Machine; UsagePolicy gates them. They are kl.exec, kl.setst (except the encodings of kl.clear and kl.clearall), kl.clearads, and kl.derive; kl.derive is gated on both lockers. kl.mgmt shares the encoding of kl.setst but is a separate instruction, not a Usage one.

  • Configuration instructions operate on the locker as a container; UsagePolicy does not gate them. They are all instructions that are not Usage instructions. Most are of four kinds, which may overlap (kl.setste, the CSR getters and setters, kl.input and kl.output are of none):

    • inspection: read the MDH or a size, change nothing;

    • destructive: zeroize or overwrite the locker without reading (Destructive Configuration Instructions);

    • transfer: move a CC, or part of it, unchanged, between lockers or between a locker and memory or registers: the management transfers (kl.load, kl.store, kl.mvin, kl.mvout), kl.rename and kl.swap, and the completing kl.mgmt;

    • narrowing: restrict the policies of a CC (kl.rstr*).

  • Memory instructions have a memory operand. The class cuts across the others: kl.load and kl.store are both transfer and memory instructions.

The named locker is the one whose number klnamedlocker holds, 32 meaning none: the locker of the CC in transit, which stays selected after the operation ends, so that software can read its outcome.

Design Principles

The sixteen Principles fall into seven groups.

  • Foundation: software uses a key without seeing it (P1), the key is bound to its algorithm and policies (P2), and every operation on it is atomic or prefix-complete (P3); these three Principles prompted the design of KLE and give the others their purpose, and the Security Principles keep them.

  • Versatility: several CCs in use at once, each with its own Machine, so that software can switch algorithms by switching lockers and combine their operations (P4). It requires the lockers and the derivation between them (D8).

  • Statefulness: a CC keeps the state of its algorithm, not only its key (P5).

  • Transparency: the architecture describes all the architected state, and confines the rest to implementation-defined fields that software may ignore (P6). It precedes the definition of a locker.

  • Scalability: KLE works on every class of RISC-V core, from microcontrollers without vectors to vector cores, and on SoCs whose cores share one KLE unit (P7). The Economy Principles limit the cost of what this requires.

  • Economy: simple instructions and short code, the least encoding space, the least architectural state, which also serves Security as the least attack surface (P8–P10).

  • Security: the algorithm and the CC inside the unit, what software may always do and keep, the CC outside the unit, and what software may never gain (P11–P16): the integrity of the algorithms and the protection of the CCs inside a locker, the availability of the lockers, the persistence of the CCs, their protection outside a locker, and the confidentiality of the keys.

Three of the nine Decisions rest on the Economy Principles, two of them together with other Principles:

  • the Metadata Header (D1), from P6, P9, P10 and P8;

  • the named locker (D6), from P8 and P10;

  • the attached-unit architecture (D9), from P8 and P9, with P7, P16 and P12.

P1: KLE must allow software to use keys that are hidden from it

Software that uses a key need not, and cannot, see it: it names the locker that holds the key, and the KLE unit performs the operation. The internal state of an algorithm is likewise not observable (P12, D9(a)). The key, and every secret derived from it, stays in the unit, or leaves it only sealed (P15) or as an output that its Machine defines, such as the ECDH shared secret, so that compromising the software that uses a key does not disclose it. Material that software supplies in clear, in a PI, leaves the unit again in clear only as a PCCC that carries just what software supplied (a PI-shaped one, or the loaded data of a system-specific import), until the provisioning completes; software keeps such a locker from other software contexts (Rule SR1).

P2: Keys in Cryptographic Contexts are associated with an algorithm and its Machine, and with policies that limit their use to certain privilege modes and bind them to software and hardware environments

A key is usable only:

  • through the Machine that its MDH names;

  • for the operations that MachinePolicy enables;

  • in the privilege modes that UsagePolicy admits;

  • where Locality and ExpirationDate bind it, only in that environment and until that date.

The binding is set at provisioning and only narrowed afterward (P16).

For hash functions, MACs and XOFs (Hash and MAC Functions, and XOFs, BLAKE2 Specific Rules):

  • a MAC whose key the locker holds, such as CMAC, HMAC, KMAC128, KMAC256 or BLAKE2 with a system key, gates tag generation, and separately verification where it has one, so that a verify-only locker cannot produce a tag;

  • KMACXOF, a key derivation function, and an unkeyed hash function gate nothing.

A bit gates not only the State that performs its operation but every State that follows uniquely from it, its Gated States, so that a narrowed locker can complete no part of a disabled operation (Rule MR1). Examples are:

  • the last block and the tag of an encryption, resp. decryption;

  • the emission of a signature in Output or Sign_Output;

  • the loading of a signature in Sign_Input, which serves only verification.

Each Machine states which States each bit gates; the rule itself is stated only once, in that Rule.

P3: Every cryptographic operation is atomic, and an instruction that performs several reports prefix-complete progress

An operation that is interrupted, or fails, leaves either nothing or a complete prefix of a partial execution: it takes effect entirely or not at all (atomic), or for an initial part of its input, recording where it stopped (prefix-complete). No part of a key or a secret is thus ever exposed, and the state that P14 saves is always consistent.

The Principle applies at every scale:

  • Instructions.

    • An uninterruptible instruction is atomic: it completes, has no effect, or traps with only the effects of Rule GR16.

    • A long-running instruction changes the Content only on completion, except for an ephemeral random value and any flag establishing its presence, which a restart discards (Rule GR37).

    • A resumable instruction is prefix-complete: it halts only at a point that klstart records, having committed exactly what a shorter instruction would. A memory instruction may also have performed later accesses, which re-execution repeats harmlessly (Rule GR33.1).

  • Operations spanning instructions. A management operation is prefix-complete as a whole: between its instructions, the CC in transit can only be transferred, saved, completed or discarded (D5, Rule GR13.3).

  • Units within an instruction. Key material that kl.derive moves enters a field whole, and a shared secret enters a message input whole: each transfer is atomic.

Two consequences follow. A committed prefix is never recomputed, which protects the one-time use of keystream and nonces. No resource fails in mid-operation: an instruction that transfers data draws no random bits (Rule MR19), and the clock is read only when an instruction starts or resumes (ExpirationDate Field).

Rules. GR39, GR41–GR44, GR16, GR32–GR36 (klstart, interruptibility), GR28 (transfer size, progress of the endpoints), GR37 (halt points), GR29 (key item); for management operations, GR13.3, GR24.

P4: Multiple keys can be in use at the same time, and their algorithms composed

Applications run several cryptographic operations at once and chain them: a protocol agrees on a key, derives session keys from it, and uses them to encrypt and authenticate while it hashes its transcript. KLE therefore holds several CCs at once, each with its own Machine, policies and State, so that operations on different lockers interleave, and combines them inside the unit (D8).

P5: Cryptographic Contexts are stateful and active, not passive

Complex algorithms run in steps:

  • a hash or MAC absorbs its input in pieces;

  • an AEAD takes associated data, then the message, then the tag;

  • a key agreement or encapsulation emits and receives values between steps.

Their intermediate state is often secret, so it stays in the CC (P16). A CC holds the state of an algorithm, not only its key, and each instruction of the caller advances it. The State records where the algorithm stands, so that it can be:

  • resumed, saved and restored (P14);

  • checked against the sequences its standard allows (P11).

Each instruction therefore handles a bounded piece of data, held in registers, the KLIOBUF or a locker. Only memory is unbounded, and processing unbounded data in one instruction would make the Machine itself access memory; memory instructions only move data instead (P8, D9(a)). A long field therefore crosses several instructions that count its progress, and entering its loading State zeroes it, so that a reload replaces the field rather than extending it (Rule MR14).

Rules. State and StateExtension Fields; through D2, the Rules it lists; in the Machines, Unprivileged Architecture: Machines and Rule MR14.

P6: The entire resource management is architectural

Where other architectures cache keys to make several available to software, KLE exposes resource management to the caller through an architectural interface (Management of Cryptographic Contexts): the lockers that P4 requires share the capacity of the KLF, and capacity exhaustion is always reported to software, which handles it (P13).

Rules. The Cryptographic Locker File and Authentication Information, Software Guidelines; among the General Rules, GR53 (capacity fixed by the MDH), GR37 (progress outside the Content, ephemeral random values architected), GR19.3 (the ADS can be dropped) and Validity of Metadata (implementation-bound Metadata).

P7: KLE must work on RISC-V cores with or without vector registers

Keys need protection on microcontrollers, many of which have no vector unit, and one KLE unit may serve cores with and without vectors on a SoC.

This Principle drives Zklio: the KLIOBUF, kl.input, kl.output and the substitutions, which turn vector code directly into code without vectors. Such code runs on any core with Zklio; where Zklv exists, vector code is faster.

Principles P8–P10 shape the buffer rather than argue against it:

  • kl.input and kl.output only move data;

  • the substitutions reuse existing Forms, each native Form of kl.exec admitting its substitution without a Machine having to say so;

  • kl.setst and kl.mgmt need no substitution: their auxiliary operand is at most 128 bits, which Form D carries in GPRs, so code without vectors uses Form D where vector code uses Form C;

  • only one buffer exists per hart, which a context switch need not save once software sets its length to zero.

Every write to kliobuflen makes the bytes beyond the new length inaccessible, zeroized at once at Level C, so no contents leak once software writes it before giving control to a less privileged mode (Rule SR1).

Rules. The conformance requirements of Extensions Overview, Zklio, the KLIOBUF variants of kl.mvin and kl.mvout (kl.mvin and kl.mvout), GR11, GR10–GR10.2; outside the GR series, Rule SR2.

P8: Make instructions as simple as possible, while keeping code sequences short

From it follow:

  1. D6, with P10: the named-locker index, its implicit and KLNL operands, and the instructions that read and write it.

  2. The “check once” property of D4(b): a routine checks the State only after its last step.

  3. One instruction clears every locker and the KLIOBUF.

Rules. GR4, GR13.2, GR21 and the NOTE of Rules Governing Inert Lockers.

P9: Minimize the pressure on the encoding space

Opcode space is the scarcest resource of an ISA, while cryptographic algorithms are many, some short-lived, and standardization keeps adding new ones. KLE therefore encodes the algorithm, its mode and its parameters in the Metadata, not in opcodes, so that:

  • the instruction set stays fixed as Machines are added;

  • every Machine follows one protocol (D2).

kl.exec performs every cryptographic operation and kl.setst drives every transition between a Machine’s Valid States, with kl.derive moving material between lockers.

The remaining instructions manage lockers, not algorithms, and none is specific to a Machine.

P10: Additional architectural state beyond the lockers is kept to a minimum

Each added register:

  • must be saved and restored at a context switch;

  • must be preserved by interposed software;

  • may leak between contexts.

The less state is exposed, the smaller the attack surface. State that an operation needs only while under way therefore exists once per hart, not per locker:

  • One set of authentication and identification registers, SIV, IMPQUAL and SIV2, 384 bits in all, serves every locker, so that software keeps at most one management operation in flight per hart, saving it before starting another (D6).

  • klstart and, with Zklio, the KLIOBUF (P7) follow the same rule.

With one klstart, an instruction honoring it starts from the value it finds, so an opening kl.mgmt clears it and interposed software saves and restores it. Touching the shared registers or the locker index while an operation is in flight is a conflicting access, and a long-running operation keeps its progress in its own locker (D7). An instruction that honors klstart, and any kl.exec, writes 0 to it whether it falls through or completes, except kl.mvin and kl.mvout, which keep it (Rule GR14): a restart after a clear then starts at offset 0, and no stale offset skips a prefix of the next operand or trips Rule GR7.

Rules. GR14, GR13.2, GR16 (klstart cleared by kl.mgmt), GR37, GR35; through D6, GR4, GR21; outside the GR series, Context Save Order, Rules SR3 and SR6–SR9.

P11: Machines prevent all avoidable abuse of their algorithms

A hidden key is safe only if the algorithm that uses it cannot be driven to leak it. A Machine therefore admits only the sequences of operations that its specification defines, so that no sequence of KLE instructions can manipulate its internal state by repeating, skipping or reordering steps. A step outside these sequences may be an attack, so the locker fails closed (D4(a)).

The final States Success and Failure admit no further step: their only usage instructions are a kl.setst naming Ready and kl.clearads (Rule GR19.3). A kl.setst that names Success or Failure invalidates the locker, like any other instruction that the State does not admit: it misuses the Machine, and is not a malformed instruction to trap on.

A same-State kl.setst is not admitted by default: repeating the entry operations of a State, such as finalize(), the padding of a last block or the setting of an output bound (out_len), can yield a state that the standard does not define. It is admitted only where it is useful and safe:

  • in Ready, where it performs the operations of entering Ready, so that software can reset a value that an operation set there;

  • in a State that loads a field, where it restarts the load;

  • where a Machine explicitly allows it, as for:

    • a new tweak (XEX);

    • a new IV (CTR, CBC, CFB, OFB);

    • a pass boundary (EdDSA);

    • a re-entry that changes nothing (ECB, the generic tweakable block cipher), so that software can name the State of a CC restored from an SCC.

A parameter that the Machine keeps across a return to Ready, such as nn and kk of BLAKE2, changes only by a new operation.

Abuse that software can commit anyway is not prevented, since a constraint that software can bypass protects nothing and costs complexity:

A length that no practical message reaches, such as one beyond a 64-bit counter, needs no check either.

Rules. GR13.5, GR19.3, GR19.2 and the endpoint definitions of Derivation Rules; in the Machines, Rules MR18 and MR15.

P12: Cryptographic Contexts keep their confidentiality and integrity inside a locker, and the unit keeps their resources available

A CC spends most of its life in a locker that all the software of a hart can reach, and the binding of P2 holds there only if nothing reaches the CC except through its Machine and the configuration instructions. The KLF, which only the KLE implementation, or M-mode firmware emulating it, can access, guarantees the confidentiality and integrity of its contents, and no instruction lets a mode other than M-mode and authenticated Debug mode see locker state in clear, except the clear data that software itself supplied to an open management operation (Rule SR1). A misuse that Rule MR15 leaves to the caller, such as the reuse of an IV, can still reveal locker state derived from the key, such as the GHASH key of GCM (Accepted Risks).

  • Confidentiality: no instruction returns a secret field (P16), and no intermediate value of an operation in flight is observable (D9(a)).

  • Integrity: the Content changes only through its Machine, in the sequences its standard admits (P11), or as a whole, through a configuration instruction (P3), and no access interferes with an operation in flight (D9(a)).

  • Availability of resources: the unit never evicts a CC, nor reclaims its locker or KLF capacity, on its own (P6). Short of a fatal error, a CC leaves its locker only when software destroys, replaces or moves it, or when it fails closed into an Error State that records why (D3(a)). The availability of the CC itself against software that can reach the locker is not an architectural goal (Threat Model).

The lockers are shared by all privilege modes of a hart, so isolating them between modes is the duty of software. A fatal error resets the KLE state as soon as it is detected, so that a corrupt KLF is never used. Only the record needed to raise the KLE fatal-error exception survives the reset, and the exception clears it (GR16). A privileged write to a CSR that governs an in-flight operation, such as the mklcsk group, a Locality CSR, a *llockerstatus CSR, KLS or a *stateen0 CSR, is a conflicting access like any other (Rule GR35), so the instruction never continues with a changed key, locality or access right.

P13: It must always be possible to configure new Cryptographic Contexts

No caller that privileged software admits to KLE may be denied the KLE resources. Neither a Machine nor a UsagePolicy may therefore restrict a configuration instruction:

  • a management operation can always be opened on a Valid locker;

  • the instructions that destroy, replace or move a CC are admitted in every State group.

Even when all lockers are in use, a caller can reconfigure any of them, even one in an Error State or a Configuration State, after clearing other lockers if the KLF capacity requires it (Rule GR53).

Only a configuration instruction that does not fit the management state of a locker that is not inert traps (D3(b), P3, D5):

  • a transfer or a completing kl.mgmt with no management operation under way, or a completing kl.mgmt whose ml.State is inconsistent with the operation;

  • for a CC in transit:

    • a transfer of the other direction;

    • a clone from it, which would put a second CC in transit with one set of authentication registers;

    • a restriction, which would change the MDH that the operation has validated or will authenticate.

The trap keeps the State, since a locker being exported may hold the only complete copy of its CC.

Rules. GR17, GR26, GR13.3, GR23, GR13.4, GR13.5 and GR13.2 (configuration instructions), GR19.3, kl.mgmt exception of GR16.

P14: Cryptographic Contexts support persistence

CCs can be stored and reloaded to survive context switches, process and VM migrations, and power cycles, unless the CSK changes, as at each power-on under the fourth way of establishing it.

Persistence is the counterpart of P13: a CC evicted to make room is saved, not destroyed. Which software may destroy a resident CC is a matter of software isolation (P12), and a CC that must survive software it does not trust is exported before that software runs. An export therefore completes, and its image is saved, before the locker is cleared or the CSK changes (Rules SR9 and SR16). The architecture does not block a change of the CSK while an export is open.

A CC is bound neither to its locker, nor to the hart, nor, unless its Locality or its CSK binds it, to the power state or to the machine. The whole CC, MDH and Content, is saved in a format independent of the implementation and the ISA (Plaintext of the Sealed Cryptographic Context (SCC) Format, all Sections in Order, Structure of the KLE Specification: Separation of Architecture and Data Formats), and restoring it into any locker yields one that behaves as the saved one did.

Persistence extends to an operation in progress: an interruption leaves a state that the locker, klstart, vstart, the committed output prefix and the ADS describe completely. From that state, resumption, even after a restore, yields what an uninterrupted operation would (D7, P3).

P15: Cryptographic Contexts keep their confidentiality and integrity also outside a locker

Persistence (P14) moves a CC through memory, storage and networks that the KLE unit does not control, and the binding of P2 holds there only if the saved form carries them, as the locker does inside the unit (P12). A CC outside a locker therefore reveals nothing of its secret material and cannot be altered undetected:

  • export seals it with an AEAD under keys derived from the CSK, with the MDH, the Localities and the public fields as associated data, and encrypts the rest;

  • import verifies the seal before the CC becomes usable; a failure leaves an Error State or, for the ADS alone, drops the ADS;

  • a partial provisioning is exported as the clear PI it holds, and an unfinished system-specific import as the data that software supplied (Management States and Formats); only a completed CC is sealed.

The seal can be bound to a locality, a chip, a chip family or a system, and the CC is then restorable only there. The binding applies at sealing and unsealing. A CC resident in a locker when a Locality Secret it names changes is sealed to the new value at its next export, so software that needs the old binding exports such lockers before the change; Rule SR12 states the case of a Locality Secret that is unconfigured. Implementation-defined Metadata is interpreted only by the implementation that wrote it, and zeroed elsewhere (MachineUse and AuxInfo Fields).

Rules. GR8, GR24 (the exported image), The SCC Authenticated Encryption Scheme, Locality Field, Validity of Metadata, GR13.3 (restricting a CC in transit), GR25, GR55.1, GR9 (public fields in clear), GR46–GR51 (system-specific import); outside the GR series, Rule SR12, SR13, SR19.

P16: Privileges are never elevated

Least privilege is enforceable only if no operation can widen or bypass the policies granted at provisioning and narrowed later. No instruction therefore yields a key, a locker or an output with more rights than its inputs and its issuer hold, unless that is the purpose of the Machine, as for public output encrypted under a secret key. The consequences are:

  1. No extraction. A key in a CC is used only through its Machine and never read out, and an exported CC is sealed: whoever obtains the CC may use the key under its policies, but never obtains the key.

    Rules. GR8.

  2. Usage is gated. A usage instruction can change a Valid locker only if UsagePolicy grants the issuing mode access; otherwise it raises a privilege-violation exception, the locker unchanged. Configuration instructions, which preserve, transfer, narrow or discard a CC without using its secrets, are not gated, even when an import or a clone restarts implementation-defined progress; kl.clearads is a usage instruction.

    Rules. GR17, GR13.5 (UsagePolicy before ExpirationDate).

  3. Secrets flow only downhill. Material derived from a secret inherits all its constraints, except when it is an output meant to be public, a KLE choice in line with the NIST key-management principles cited with Principle P16. No operation widens a policy, raises a protection level or enables a Machine to perform operations beyond those defined at its provisioning. A secret bound to the system never leaves it, and a bound key field is never replaced from outside.

    Whether an ML-KEM decapsulation rejected its ciphertext implicitly affects only the value of the shared key, not the execution time or any field of the locker. Its SCProtection level governs the other physical leakage, since a side channel of the decryption or the re-encryption is a plaintext-checking oracle on the decapsulation key. The value itself is no such oracle, as FIPS 203 returns it to the caller and ML-KEM is IND-CCA2 secure under that interface (ML-KEM).

    Secrets do not linger:

    • A completed operation destroys the values drawn for it and its intermediate values, unless the algorithm of its Machine keeps them as the standard requires (Rule GR38, item 5). It keeps only its result and values computed from a key field alone, masked shares included, which may stay in the ADS until that field changes, and which KLE treats as part of the stored key (FIPS 203 §3.3 and FIPS 204 §3.6.3 name only the seed and the matrix Â; ML-KEM, ML-DSA).

    • The material that depended on a destroyed, invalidated or restarted CC is released or zeroized.

    • A destructive configuration instruction destroys the CC it replaces right after the locker-state-independent checks and, for kl.mgmt, the check of its MDH operand.

    • A kl.setste that replaces an Error State overwrites the only information the locker holds, and kl.swap moves each CC into the other locker, so neither has anything to erase.

    Rules. GR30–GR31.3, GR20, Validity of Metadata, GR54–GR55.3, GR48, GR51; GR38, GR15, GR16 (zeroizing step) and GR38.

  4. Nothing stale is returned. Neither an input nor an earlier output left in an output window or an inert locker can pass for a result. A kl.exec that performs no operation, or stops in an Error State, zeroes the unwritten part of its output window in registers or the KLIOBUF; one that traps or has an empty window leaves it unchanged, and an inert locker reads as zeros, or as its MDH in an Error State.

    A kl.store that falls through writes no memory, so software relies on an exported image only after checking the State (Rule SR15).

    A State writes only within its output window, bits [8 × klstart, KLLEN − 1]. Hence a resumed instruction keeps its committed prefix, and a block-wide value never spills past KLLEN. An output longer than KLLEN is truncated, unless it is meant to be emitted over several instructions, so a short KLLEN selects a truncated tag (Rule MR9).

    Rules. GR14, MR9, GR13.2; outside the GR series, Rule SR15.

Design Decisions

A Design Decision is a mechanism that two or more Principles select together, and from which a group of rules follows. It is not a Principle, since another mechanism could satisfy the same Principles, but the rules derive more easily from it.

D1: The Metadata Header

A locker is described by a 128-bit header carried with its CC, the MDH, which alone determines what the locker is, what it admits and how large it is. The MDH meets three Principles at once:

  • it is the architected description that P6 requires;

  • it names the algorithm, as P9 asks;

  • it is one fixed-size header rather than a table or a set of registers (P10).

Its layout minimizes the lookahead needed to identify a locker (P8):

Hence:

  • the State field, with StateExtension at State 0, identifies the points software must recognize;

  • an Error-State locker is its MDH (D3(a));

  • an Unconfigured locker reads as the one MDH value that is not an MDH;

  • a management operation restores the MDH it was given, up to prescribed normalizations;

  • implementation-defined progress lives outside the Content (D7).

Rules. GR5 (the MDH as one 128-bit operand), GR52, GR53, GR22, GR15, GR26, GR13.2, GR25, GR37.

D2: The Machine protocol

With active CCs (P5) and two generic instructions (P9), every Machine follows one protocol, so that one routine shape serves all (P8):

  • kl.setst names the next State, or an operation on the current one;

  • kl.exec performs the operation of the current State;

  • the architecture and each Machine’s specification say which transitions exist and which usage instructions each Valid State admits (P11).

The hash, MAC and XOF Machines other than CMAC go further: one instruction sequence hashes with any of them, the Machine owning the padding (Hash Functions, MACs and XOFs).

Rules. GR23, GR19.3–GR19.5, GR25, GR19.2.

D3: The error architecture

Each CC records its own errors, with no global error register (D3(a)), and traps only for what falling through would misreport (D3(b)). Either way, a handler or the locker’s owner acts on the cause without decoding the instruction or reconstructing the sequence.

This follows from three requirements:

  • algorithms in use at the same time fail independently (P4);

  • an error must travel with its CC through context switches, exports and imports (P14);

  • one check per locker must suffice (P8).

D3(a): An error is recorded as an Error State

A failure is recorded in the State of the locker whose precondition failed.

  • The Error State names the class of the cause:

    • Invalid for sequencing, a MachinePolicy gate or invalid Metadata;

    • Privilege Violation for a narrowing or a binding;

    • Unsupported for a Machine, variant or field value that the implementation does not support;

    • Out of Memory for KLF capacity;

    • Expired for the clock;

    • Authentication Failed for a seal.

  • A negative result of the algorithm, such as a rejected signature, is not an error (Failure).

  • Likewise, what is rejected decides whether the CC becomes unusable or only the operation ends (Rules MR2 and MR3):

    • a rejected key or parameter of the CC makes the CC unusable (Invalid);

    • rejected data of an operation, a public key, a ciphertext, a signature or a message representative, ends only that operation (Failure).

  • An ML-KEM key or ciphertext, or an ML-DSA public key or signature, loaded with excess data is rejected instead of having the excess ignored, as FIPS 203 §7.2–7.3 and FIPS 204 §3.6.2 require, so that a value of another length is never truncated into a valid one.

  • A system-specific import checks a converted ECC field, ML-KEM key or ciphertext, or ML-DSA key as a load does, marks a converted HMAC K0 as loaded, and, like a load, leaves the public key of an ML-DSA private key to compute_pubKey.

  • A malformed encoding is a configuration error only where it is checked when the field is written. One that the standard detects only while decoding, such as an ML-DSA hint, is a data error, so that a forged signature cannot erase a verify-only CC.

  • A corrupted KLF, by contrast, can no longer be trusted for any locker: it is a fatal error of the KLE unit, not an Error State of one locker (Error Handling Architecture).

  • An Error State is State 0 with its code in StateExtension, so an Error-State locker is its MDH alone (D1), and every locker that holds no Content has State 0:

    • its Content and ADS are released on entry (P16);

    • it is exported and imported as an MDH, without a management operation.

  • A handler that cannot resolve a condition records it by setting the Error State itself.

Rules. GR15–GR26, Export and Import of a Locker in an Error State, the error list of Error Handling Architecture, GR29 (which locker transitions), GR30 (Privilege Violation), GR45 (Invalid, not Failure).

D3(b): Exceptions are raised only for error conditions that the fall-through mechanism would misreport
  • The error conditions are four:

    • a malformed or reserved encoding, a programming error that an illegal-instruction exception signals;

    • a sequencing error that would silently lose a CC (P14);

    • a use of unconfigured infrastructure, as opposed to an inert locker;

    • a policy violation, which the policy owner must see, not the caller (P16).

  • Their locker-state-independent checks precede every condition on the locker. Their other checks, UsagePolicy included, come in the order of Rules GR12 and GR13.5: an inert locker falls through unchecked once the locker-state-independent checks have passed, while a Configuration State traps. The encoding checks apply to every instruction, so a malformed encoding traps regardless of the locker, and software cannot probe the locker’s State with it.

  • The other exceptions name a condition that a more privileged handler may resolve, by emulating a Machine, freeing memory, granting a right, or supplying a clock or entropy. Rule SR10 says what a handler must do with one it cannot.

Rules. GR1, GR2, GR4, GR5–GR6 (illegal-instruction grounds), GR13.3, GR13.5, GR14 (no operand checked on fall-through), GR11, GR13.4, GR19.4 (reserved immediates), GR12, GR45 (temporary failure), Exception causes in decreasing priority order; outside the GR series, Rule SR10.

D4: The outcome of an instruction on a locker

When an instruction cannot do what it is asked, its outcome depends only on the State group of the locker and the class of the instruction. Unless it raises an exception (D3(b)), it falls through:

  • it performs no operation (Definition: No Operation.) and zeroes its output;

  • on a misused Valid locker, the State moves to Invalid (D4(a));

  • on an inert locker, the State is unchanged (D4(b)).

The outcome Rules of the State classes that Rule GR13 names are selected:

  • for the traps, by D3(b);

  • for the Configuration States, by P3;

  • for the configuration instructions, by P13;

  • for Valid and inert lockers, by the two parts below:

D4(a): Algorithm misuse invalidates a Valid locker

The locker fails closed (P11) and records the cause (D3(a)). It then stays inert (D4(b)), with no history kept, until reconfigured (P13).

The outcome depends on the cause:

  • these move the locker to Invalid:

    • an instruction forbidden by the Machine’s sequencing or MachinePolicy rules, also where the Machine itself would make the forbidden transition;

    • a transfer window or klstart that the Machine does not admit;

    • the first instruction issued after a narrowing that disables the operation it performs (Rule GR20), or the narrowing itself if it leaves a MachinePolicy that the Machine forbids;

    • a permanent RBG failure;

  • a UsagePolicy denial traps, the locker unchanged (D3(b));

  • a failed narrowing of a restricted transfer gives Privilege Violation.

Rules. GR13.5, GR27, GR19.2, GR19.3, GR19.1, GR10.2, GR19.4 (non-admitted immediates), the endpoint definitions of Derivation Rules, GR20, GR29, GR18, GR45 (permanent failure), GR23, GR19.5.

D4(b): Inert lockers let instructions fall through

A locker becomes inert asynchronously, when a handler clears or invalidates it (P3). The instructions that follow must neither trap nor act on something else, and the original error must stay readable (D3(a)), so that one check at the end of a sequence suffices (P8).

  • Every instruction other than a destructive one and kl.setste therefore falls through with the State unchanged:

    • a transfer other than kl.mvin and kl.mvout leaves klstart as an empty window would;

    • an inspection reads what is there: zeros, the MDH, or a size or availability derived from it.

  • KLNL with klnamedlocker = 32 names no locker and is treated as an inert one (kl.load and kl.store then fall through: they access no memory and no KLIOBUF and write only 0 to klstart); Results of instructions on an inert locker lists what each instruction writes in the three cases.

  • Two kinds of instruction are excepted:

    • a destructive instruction is issued to destroy the error, and kl.swap keeps it readable in the other locker;

    • kl.setste, which sets an Error State: it overwrites nearly all that an Error-State locker holds, and on an Unconfigured locker it records an error that an opening kl.mgmt or a kl.clone raised after clearing it, so that a handler can report it (Rule SR10).

  • So a locker leaves an Error State only through:

    • kl.clear or kl.clearall;

    • a kl.rename naming it as source;

    • a kl.clone, kl.rename or kl.swap naming it as destination, resp. as either operand, whatever the other locker holds (a kl.clone clears the destination before it can trap);

    • a provisioning- or import-opening kl.mgmt.

  • As klstart does not advance on an inert locker, a transfer sequence is bounded by the caller’s own count (Rule SR14).

  • A locker in a Configuration State falls under P3 and D3(b) instead.

Rules. GR13.2, GR14, item 1 of GR21, first sentence of GR26, the States paragraph of kl.rstrl, kl.rstrh, and kl.rstrv.

D5: The management operation protocol

A management operation is one operation spanning several instructions (P3):

  1. an opening kl.mgmt starts it;

  2. transfer instructions move the image;

  3. a completing kl.mgmt ends it.

Between the opening and the completing kl.mgmt, the locker is in a Configuration State.

A provisioning- or import-opening kl.mgmt is a destructive configuration instruction:

  • it is admitted in every State (P13);

  • it zeroizes the locker and frees its resources right after the locker-state-independent checks and the check of an MDH operand in Vs (P16);

  • this also lets the capacity check count the locker’s own allocation as free, so that a CC can be reconfigured in place.

The named locker names the operation in flight (D6).

Rules. GR14, GR13.2 (transfers on a cleared locker), GR13.3–GR25, Destructive Configuration Instructions, the kl.mgmt exception of GR16, Locker Management Operations, Management States and Formats, GR46–GR51; outside the GR series, Rules SR6–SR9.

D6: The named locker architecture

The authentication and identification registers SIV, IMPQUAL and SIV2 exist once per hart (P10), so software, not hardware, keeps one management operation in flight at a time. Before managing another locker or performing cryptographic operations, it completes or discards the one in flight, or saves it by a nested export (Context Save Order, Rules SR8 and SR7). Without that, a context switch could find klnamedlocker naming another locker that KLNL cryptography or a kl.mgmt used, save it as the managed locker, and export a Valid locker before the open one, overwriting its authentication registers.

klnamedlocker holds the number of the locker of the CC in transit, so that a management routine needs no locker number (P8). The number:

  • follows the CC when it moves;

  • is kept when the operation completes or fails, so that the outcome stays readable;

  • otherwise changes as Rule GR21 lists, or as software writes it.

Every instruction that names a locker can take the locker index instead, for one of two lockers at most: a management routine written for it replaces 32 written for fixed lockers (P8), and cryptographic code can work on a locker chosen at run time.

With D4(b) and D3(b): a kl.mgmt that names a locker by number makes it the named locker (Rule GR21), and no instruction that names a locker by number is checked against klnamedlocker, so software, not the unit, keeps a management sequence on one locker; naming the named locker when there is none falls through for every instruction that names a locker, an opening kl.mgmt and a destructive instruction included, so that a management routine detects a clear by its State check alone.

Rules. GR4, GR21, GR13.2 (no named locker), GR24, GR35 (because klnamedlocker is KLE state).

D7: The resumption architecture

Since every operation is atomic or prefix-complete (P3) and the hart keeps one progress register (P10):

  • klstart records the prefix-complete point of whichever resumable instruction is in flight, in bytes;

  • vstart records the same point in elements where a vector operand is involved;

  • for kl.mvin and kl.mvout, klstart is the offset into the locker image instead.

Interruption points are of two kinds:

  • Those the architecture defines, per instruction and per Machine State, are part of the CC: the State and the hart CSR klstart record them, and a restored CC resumes from them once klstart is restored too (P14).

  • Those an implementation defines, inside a long-running operation, are not part of the CC. The operation records its progress in MachineUse and the ADS, so that it is architected and not hidden (P6), but an import or an export completion that does not retain the ADS, as on another implementation, discards it and restarts from the Content, and a clone always does (GR38).

Restarts and timeouts are bounded, and a resumed instruction eventually completes, as one resumed from vstart does in RVV. A restart is counted against a locker, so kl.input and kl.output, which name none, never restart: they complete or halt precisely and resume.

A handler that resets klstart to 0 would make a kl.exec execute anew over its whole window, but from the state that its completed prefix committed, which may leak partial plaintext or reuse a pad (Rule SR4).

Rules. GR7, GR28, GR41, GR16 (memory exceptions), GR32–GR38; outside the GR series, Rules SR3–SR4.

D8: The derivation architecture

Combining algorithms (P4) while no key leaves the unit in clear (P16) requires a transfer between lockers inside KLE.

kl.derive moves material from a source endpoint to a destination endpoint. An endpoint is a field or the kl.exec output or input that a Machine lists for a State. One instruction serves every pair, the endpoints being Machine data rather than opcodes (P9).

A transfer is restricted unless P16 exempts it. It exempts, for instance, a transfer of kl.exec output, a shortcut for instructions that software could issue anyway: kl.exec on the source, then kl.exec on the destination or a provisioning with a key of its choice.

For now the architecture admits only the pairs that protocols need most:

  • a shared secret of a public-key Machine into a symmetric Machine, a hash function included;

  • the output of a block cipher Machine, a keystream, a CMAC, or a hash function, MAC or XOF, into a symmetric key, as the KDFs of SP 800-56C, SP 800-108 and HKDF produce it.

Every such transfer is short, so every kl.derive is uninterruptible, and no common interruption points or granularities of two endpoints need be defined. The long-running work that produces a derivable value, such as a scalar multiplication or a decapsulation, is done by an earlier kl.exec, so kl.derive is never long-running (Rule GR32). A long-running kl.derive with implementation-defined interruption points is a possible future extension; this version does not define its semantics.

A restricted transfer into a destination of lower SCProtection fails instead of raising its level, which a narrowing never does (Narrowing of Metadata): the secret would otherwise be used with weaker side-channel protection than its source requires.

A shared secret that its Machine does not export through kl.exec may feed:

  • a symmetric key field, other than the K1 ‖ K2 of nonce masking;

  • the message input of a hash function, HMAC, KMAC or XOF, but not that of CMAC, whole and in one step, with a length equal to that of the secret so that the uninterruptible transfer stays short.

It never feeds a private key, whose public counterpart would expose it to a discrete-log or quantum attack. A shared secret that its Machine exports through kl.exec, such as the ECDH secret, moves as an unrestricted transfer of its field, to the same destinations, except that only an X25519 or X448 secret enters a key field: the others are not uniform strings, and SP 800-56A §5.8 admits Z only as the input of a key-derivation method (Rules GR31.1, Derivation Endpoints of the Machines).

CMAC is excluded because the caller may know the key of the destination and choose the data around the secret. The destination must therefore be one-way under a known key, and a block cipher is pseudorandom only under a secret key:

  • under a known K, every step C_i = E_K(C_(i-1) xor M_i), the final subkey included, can be inverted;

  • so the caller runs back from the tag to the chaining value after the secret, and knows C_0, the one before it.

Then:

  • a one-block secret is E_K-1(C_1) xor C_0;

  • a two-block one S1 ‖ S2 leaves the Even–Mansour cipher X ↦ E_K(X xor S1) xor S2 under a public permutation, which about 2b/2 chosen X break, 232 for a 64-bit block.

Nonce masking is excluded for the same reason: its K2 is XORed into a nonce that the caller chooses, and a plain Ascon-AEAD128 locker can receive the same K1. The attack takes two steps:

  1. The caller queries the two lockers with the same associated data and the same plaintext of at least one full block, the first with the nonces x ‖ 064 and the second with 064 ‖ y.

  2. After about 265 queries, it finds the pair of equal ciphertexts and tags, for which x ‖ y = K2.

Hence 128 bits of a restricted secret leave the KLF, and a 256-bit sharedkey used whole elsewhere keeps only the strength of K1. As the NOTE of nonce masking states, the same holds for a System Key that the SKS allows both for nonce masking and for a Machine with a nonce that software chooses.

The HMAC K0 takes a key shorter than b, zero-padded as FIPS 198-1 Step 3 does, so that an ML-KEM sharedkey, an X25519 or X448 shared secret, or a CMAC can key HMAC; the shared secret Z of a Weierstrass curve (SP 800-56A) and that of SM2 are HMAC input, not its key. Two conditions keep a secret prefix from being recovered:

  • the source must supply the whole key, since a short prefix of a secret, used as an HMAC key, can be recovered by exhaustive search from the tags;

  • the derive replaces any part of K0 that kl.exec loaded, so that no known bytes can surround a secret prefix.

A keystream never keys HMAC: it has no length of its own to transfer whole (Rule GR29 item 6, HMAC).

A BLAKE2 message may end with bytes that a kl.derive delivers, which software cannot hold back for the last block. Since the final-block flag must mark the block that holds the last byte, BLAKE2 keeps a full block until the next byte arrives, as the reference code of RFC 7693 does (BLAKE2 Specific Rules):

  1. the held block stays in block through a kl.setst into Hash_Absorb_Last_Block with Xs = 0;

  2. the kl.setst into Hash_Output ends the message, whose finalize() flags the held block.

A sealed source keeps a key derivation inside KLE, which a readable hash output would otherwise end after one hop (Rule GR31.3):

  • the source opts in through an immutable variant: TLS 1.3 and HPKE read values of their key schedules, and the owner of a hash locker that chose would simply not seal it;

  • the sealed ECC variant fixes Generator, since the caller could otherwise load the peer point there and read [d]P as a public key;

  • sealed material never keys keystream generation, OFB or CMAC, whose outputs are sources that a copy of the key in an ECB locker would reproduce;

  • every transfer moves at least 16 bytes: a 1-byte output derived into K0, then into a key used by ECB, falls to 256 guesses, and so does each further byte of a longer output in turn;

  • each value leaves its source once: a kl.exec and a kl.derive consume the same output, the field of a shared secret feeds one kl.derive (Rule GR28), and an XOF yields new bytes at each transfer; two hash lockers fed the same Z would otherwise give the same KDF output as a 16-byte key and as a 32-byte one, and a search of 2128 keys for the first would leave 2128 for the second.

A sealed key may still be used for its purpose, and sealing protects only a secret that software never chose, such as a random Scalar. Only a recomputation from the same inputs, a kl.clone or a restored SCC copy yields a value twice. The architecture accepts this residual: it splits a 256-bit key into two 128-bit searches at most, and Grover’s algorithm does not make a 128-bit search practical, since each of its steps costs a whole quantum AES circuit. Under a maximum circuit depth of 240, recovering an AES-128 key takes about 2118 logical qubit-cycles, and still 2102 under a depth of 256 cite:[NCSC-Grover-AES-2024]; the gate counts of cite:[JangBKSSC-CiC-2025] give similar costs.

A failed check is recorded on the locker whose condition failed, on both for a pair that is not admitted (D3(a)).

Each unit of a transfer commits at both endpoints at once, and the narrowing with the first unit; a key and its initialization are part of the same uninterruptible instruction (Rules GR30, GR28 and GR32).

Rules. The endpoint definitions of Derivation Rules; GR27–GR31.2, GR55.1 (no kl.derive into or out of a System Key field); kl.derive; Derivation Endpoints of the Machines.

D9: The attached-unit architecture

KLE instructions are architected as messages to an attached unit, which executes them independently of the issuing hart and alone accesses the lockers. Thus:

  • the secrets live where only the unit, or M-mode firmware emulating it, reaches them (P16, P12);

  • one unit can serve several cores, with and without vectors (P7);

  • a new algorithm is a new Machine, not new instructions (P9);

  • the hart side stays simple: software configures the lockers, the unit performs the cryptography (P8).

The unit can be updated, or emulated in part by M-mode firmware, without affecting the hart.

D9(a): Asynchrony is invisible

The unit may run asynchronously to the hart, but the hart never observes the asynchrony: a conflicting access waits until the operation completes or halts precisely (D7).

Other harts, in contrast, see the component accesses of a memory instruction as ordinary memory operations, so a buffer that a KLE memory instruction accesses needs the same synchronization to be shared as one that an ordinary software loop accesses.

The asynchrony is hidden from the hart because, were it visible:

  • software would need instructions to wait for an operation, which cost encoding space (P9) and increase code size (P8);

  • by reading an incomplete result, or interfering with an operation in flight, software could break the confidentiality, integrity and availability of the CC and of its results (P12).

Rules. GR39–GR41, GR42, GR43, GR34, GR35, GR36, GR40, Long-Running Operation (Definition).

D9(b): Operands follow the RISC-V conventions

The hart passes the unit its operands in its own registers, so the RISC-V conventions apply, extended only where RISC-V defines none (P7, P8); a malformed operand is a programming error, which an illegal-instruction exception reports (D3(b)).

Rules. GR1, GR2, GR3, GR5–GR7.

Coverage

For each rule, the Principles and Design Decisions it follows from; each of them lists the same rules under Rules, directly or, where it says so, through a Decision.

Table 1. Rules and the Principles and Design Decisions they follow from
Rules Principles and Design Decisions Rules Principles and Design Decisions

GR1, GR2, GR6

D3(b), D9(b)

GR27

D4(a), D8

GR3

D9(b)

GR28

P3, D7, D8

GR4

P8, P10, D3(b), D6

GR29

P3, D3(a), D4(a), D8

GR4

P8, P10, D6

GR30

P16, D3(a), D8

GR5

D1, D3(b), D9(b)

GR31

P16, D8

GR7

D7, D9(b)

GR31.1, GR31.2, GR31.3

P16, D8

GR8

P1, P12, P15, P16

GR55.1

P15, P16, D8

Validity of Metadata

P6, P15, P16

GR16

P3, P10, P12, P13, P16, D5, D7

GR17

P2, P13, P16, D4

GR33.3, GR32, GR33, GR33.2

P3, D7

GR21

P8, P10, D4(b), D6

GR34, GR36, Long-Running Operation (Definition)

P3, D7, D9(a)

GR22

D1

GR9

P1, P15, P14

GR23

P13, D2, D4(a)

GR18

P3, D4(a), D7

GR13.4

P13, D3(b)

GR35

P1, P3, P10, P12, D6, D7, D9(a)

GR13.5

P11, P13, P16, D3(b), D4, D4(a)

GR37

P3, P6, P10, P14, D1, D7

GR19.3

P6, P11, P13, D2, D4, D4(a)

GR38

D7, P16

GR19.2

P11, D2, D4, D4(a)

GR38

P14, P16, D7

GR19.4

D2, D3(b), D4(a)

GR40

D9(a)

GR19.5

D2, D4(a)

GR43, GR39

P3, D9(a)

GR20

P2, P16, D4(a)

GR33.1, GR44

P3

GR13.3

P3, P13, P15, D3(b), D4, D5

GR41

P3, D7, D9(a)

GR24

P3, P15, D5, D6

GR45

D3(a), D3(b), D4(a)

GR25

P14, P15, D1, D2, D5

GR46, GR47, GR49, GR50

P15, D5

GR12

D3(b), D4

GR48, GR51

P15, P16, D5

GR13

D4

GR10, GR10.1

P7

GR11

P7, D3(b)

GR19.1

P7, D4(a)

GR13.2

P8, P10, P13, P16, D1, D4, D4(b), D5, D6

GR10.2

P7, D4(a)

GR14

P3, P10, P16, D3(b), D4, D4(b), D5, D7

GR52

D1

GR42

P3, D9(a)

GR53

P6, D1

GR26

P13, P14, D1, D3(a), D4(b)

GR54

P14, P16

GR15

P16, D1, D3(a)

GR55.2, GR55.3

P16

What the Principles do not determine

The choices below are constrained by the Principles and Design Decisions but not fixed by them, and remain rules in their own right: Table 2 lists those of the General Rules, Table 3 the most important of the other normative statements of Unprivileged Architecture: Instructions and Architectural States, Privileged Architecture and Unprivileged Architecture: Machines.

Table 2. Choices of the General Rules
Rule Choice Why, and what the Principles leave open

GR1

A reserved encoding raises an illegal-instruction exception.

RISC-V leaves the behavior of a reserved encoding UNSPECIFIED cite:[RISCV-ISA-Unpriv]; D3(b) treats it as a programming error, which a trap reports, and a fixed outcome keeps the encodings free for later extensions.

GR2, GR3, GR6

Register groups are aligned: a GPR pair starts at an even register, a quartet at a multiple of four, a vector group at a multiple of LMUL; a group based at X0 reads as zero and is never written.

D9(b) requires the RISC-V conventions: the vector groups and the GPR pairs follow them, and the quartets extend the pairs to 128 bits.

GR6

An instruction that produces no vstart value raises an illegal-instruction exception when issued with vstart ≠ 0.

RVV 1.0 permits this exception for a vstart value that the instruction can never produce, without requiring it; raising it reports the stale value.

GR21

A kl.mgmt that names a locker explicitly is not checked against klnamedlocker: it runs on the locker it names and sets klnamedlocker to that number, even while another locker is under management.

D6 leaves the sequencing of management operations to software. A hardware check would be no boundary, since kl.setnl and kl.setnli are unprivileged, and would only repeat the check that a management routine makes once at its start; software therefore keeps one operation in flight under Rules SR6 and SR7.

GR21

klnamedlocker is kept on completion.

D6 would also allow a reset to 32, but kl.getst Xd, KLNL after the completing kl.mgmt would then read 0; software resets it afterward (Rule SR6).

Validity of Metadata

A custom Machine or a system-specific Version needs a Locality binding of one of the kinds that Validity of Metadata enumerates.

P15 asks only for a binding.

GR19.2

A same-State kl.setst is not admitted, except in Ready, in a loading State, where it restarts the load, and where the Machine explicitly allows it.

P11: a default ban removes a class of errors in which re-entry repeats operations, such as finalize(), and replaces many per-State prohibitions with one rule.

GR20

A kl.rstrl or kl.rstrv narrows MachinePolicy as any narrowing does, by an AND (Narrowing of Metadata), and invalidates the locker by itself only if it leaves a MachinePolicy that the Machine forbids, such as zero where a set bit is required. Otherwise the locker is invalidated by the first kl.exec, kl.derive or usage kl.setst that is issued in a State that performs a disabled operation or leads only to disabled operations, or that enters a State whose operation is disabled. The narrowing does not affect an instruction issued in a State that performs no disabled operation and still leads to an enabled one, nor, wherever it is issued, kl.clearads or a kl.setst that names Ready or such a State.

Invalidating at the first instruction in the disabled operation satisfies P16 and D4(a), and lets software narrow a locker that keeps a useful function, also in the middle of loading its inputs, without returning it to Ready.

State and StateExtension Fields, GR19.5

An Error State is State 0 with its code, 1–6, in StateExtension; Success and Failure are States 54 and 55, and the Machine defines States 2–53. State 0 is Inert. kl.setste, the kl.setst encoding with bit 23 set, writes the code to StateExtension; the kl.setst immediates 1–53 name Ready and the Machine States, while 54 and 55 are the numbers of Success and Failure, which kl.setst cannot set (Rule GR19.5).

D3(a) requires only that the error be recorded in the MDH. State 0 makes "holds no Content" one test for both inert States, and kl.setste then needs no exception for an Unconfigured locker. A State immediate cannot name a StateExtension value, so a separate instruction, parallel to kl.getstx, sets it; bit 23 was a fixed zero of the kl.setst encoding. Moving Success and Failure to the top of the Valid States leaves the contiguous range 2–53 to the Machines.

GR26

An Error-State image is the MDH alone, neither encrypted nor authenticated, and its import installs it as is unless it is invalid Metadata (Export and Import of a Locker in an Error State). A kl.setste also configures an Unconfigured locker into an Error State.

P15 protects secrets and policies, and an Error-State locker has neither and is easy to create, so authentication is superfluous. An unsupported-Metadata or out-of-memory exception of an opening kl.mgmt, and one of kl.clone, is raised after the locker has been cleared; without the second choice, a handler could record it only through the short import of Export and Import of a Locker in an Error State.

GR14, GR12

The address-misaligned exception is raised on an empty window, but not when klnamedlocker = 32; order of the locker-state-independent checks, with the alignment check last among them, preceded only by the address breakpoint of the first component access, so an inert locker traps on a misaligned address; open for hardware implementers (Discussion Points).

RISC-V conventions (D9(b)); D3(b) requires only that the locker-state-independent checks come first.

GR13.5

On a Valid locker, with Zklio, an unconfigured KLIOBUF is checked before the UsagePolicy for a substitution of a native Form that the State admits. Any other substitution, and every substitution without Zklio, is a wrong Form: it invalidates the locker unless the UsagePolicy or the ExpirationDate has decided the outcome first.

D3(b) puts only the locker-state-independent checks first, and P16 the UsagePolicy before the ExpirationDate, so that an excluded mode cannot expire the locker. This ground (P7) follows the priority of Exception causes in decreasing priority order, after the Configuration State, since a substitution exists only for a State with an operation.

GR19.3

A kl.setst naming Ready is of Form A unless the Machine defines another Form, as the ECC Machines do; any other Form is a wrong Form.

A convention of the protocol (D2): a return to Ready needs no operand, and a fixed native Form lets two implementations agree on whether the locker survives.

GR25

Provisioning and the base import of a system-specific format (completed with ml.State = 0) end in Ready, with MachineUse zero and StateExtension zero except for the flags of the fields that the format configures. A nested import of a Version 3 PCCC, like any other nested operation, only restores the Configuration State of ml.

A convention of the protocol (D2).

GR46–GR51

System-specific formats exist for import only, never for provisioning, and need not be encrypted or authenticated. Such an import takes the place of a provisioning: it gives a starting point that ends in Ready, never a snapshot of a started operation, so it supplies every field that the Machine needs and cannot set itself; AuxInfo may be carried by the MDH and is taken from the format where the format supplies it, which a key such as an EdDSA key for pure mode or an ML-DSA key for HashML-DSA requires. Their MDH (Version = 3) names a Machine, which must equal the one that the format determines, by naming it or by its definition; the MachinePolicy of the MDH must enable only operations that the format allows, since narrowing never changes MachinePolicy; likewise, an import whose declared SCProtection is lower than the level that the format requires fails with Privilege Violation. The implementation ensures that every such import ends with a Machine defined. The MDH reuses AuxDataLen as the length of the data, which the locker holds as received until completion, so a nested export returns only what software supplied; no other exported image has Version 3. The converted Content passes the same Machine checks as any import; its fields are marked configured, as a completed load marks them, and no provisioning step of the Machine overwrites them or clears their flags. The import then enters Ready with the operations of the Machine, or with initialization operations that the format defines in their place. These apply only at that import: from then on the locker is a native one, so every later entry into Ready, and every import of an SCC exported from the locker, follows the Machine. A Machine may drop a field in the conversion itself, as ML-DSA drops a pubkey converted together with a privkey, so that the public key of a private key is always derived and checked against tr. A data error leaves the locker in Failure, narrowed and with Version 0, like any other imported CC. A format and its import are defined so that they circumvent no requirement of this specification or of the referenced standard of the Machine. The base import leaves a locker whose MDH and Content could also have been produced by a provisioning of the same Machine, then the loads or operations that set the fields that the converted Content configures and the PI does not carry, a kl.setst naming Ready, and the narrowing. Every field that the Machine derives from another is derived from the converted Content, or checked against it (Rule MR4).

P14 is implemented economically with only one implementation-independent sealed format; other import formats serve to allow some interoperability, and some systems import encrypted keys without authenticating them. The MDH stays the one description of the locker (D1), so the format may confirm or restrict its Machine but never replace it. A format that authenticates its data can fail that check with Authentication Failed, which SCC import code already handles and provisioning code never does. Authentication precedes every other check, so that no check answers on forged data, and every failed check that such a format defines gives Authentication Failed, so that the outcome does not tell which check failed. A clear format for provisioning would only duplicate the PI, which software can rework freely, and unconverted data keeps the nested PCCC as harmless as a PI-shaped one. A foreign format must not become a way around a check of the referenced standard, such as the FIPS 203 input checks of an ML-KEM key. The architecture cannot check a format that it does not define, so this duty binds the architect of the format and the implementer of its import; the criterion of Rule GR49 makes it testable, and excludes, for instance, a GCM_IV J0 whose counter exposes the GHASH key, or a BLAKE2 nn of 0.

GR31.1

A shared secret whose export through kl.exec its Machine does not allow enters a symmetric key field that the endpoint table lists, or, whole and in one uninterruptible step, the message input of a hash function, HMAC, KMAC or XOF; and no other message input, CMAC’s included. One whose export its Machine allows moves to the same destinations as an unrestricted transfer of its field.

Under a key the caller may know, hash functions, HMAC, KMAC and XOFs still hide a secret that enters whole; CMAC does not, and a private key does not either, since its public key reveals it to a discrete-log or quantum attack. A secret that software can read through kl.exec has nothing left to hide, so restricting its transfers would only add policies the caller can bypass (P16, Derivation Endpoints of the Machines).

GR31.3

A shared secret of a sealed variant, or the output of a hash, MAC or XOF locker that sealed material entered, moves only by restricted transfers of at least 16 bytes, into a message input or an HMAC K0, whose locker becomes sealed, or into the key of a Machine whose output is not a source; a sealed locker emits no output through kl.exec and verifies no tag.

The policies of the source then reach the final key; D8 gives the reason for each limit.

GR28

The size arithmetic of derivations: eff_length = min(length, dest_length), a destination field zero-filled beyond eff_length, a field source read as zeros beyond its end. Every message input is byte-granular, so a shared secret enters it with nothing appended.

P3 requires only prefix-completeness and all-or-nothing keys.

GR16

Every kl.mgmt, not only an opening one, clears klstart once it passes items 1–6 of the locker-state-independent checks (the klnamedlocker and locker-Off checks included), even if it then traps.

P10 requires only that an opening kl.mgmt clear klstart. Clearing it before the State-dependent checks gives every outcome the same klstart; a kl.mgmt that raises an exception at items 1–6 leaves klstart as it was, which protects the operation in flight; a klnamedlocker check that finds no locker raises none, and the instruction clears klstart and falls through.

GR32

The KLIOBUF variants of kl.mvin and kl.mvout are uninterruptible although they transfer several blocks.

P3 would allow halts between blocks; the KLIOBUF variants (P7) need none, as the maximum length of the KLIOBUF bounds their length (P5); the interrupt latency that they add is thus bounded by a parameter that the implementation chooses.

GR52

Image lengths depend only on MDH bits [63:0], and not on SCProtection; State matters only to tell a PI, an SCC and an Error State apart, an Error State image is 16 bytes whatever its other fields hold, as the import of such an image checks only State and StateExtension, and any other Version 3 image is 16 + 16 × AuxDataLen bytes.

D1 asks that the first 64 bits size a locker, so that kl.size Form B needs one 64-bit operand; an SCC length independent of State and SCProtection lets one buffer serve every State and every protection level while StateExtension, AuxDataLen and ADSDropped are unchanged.

GR53

Capacity is fixed when the opening kl.mgmt or the kl.clone that configures the locker allocates it, whatever State or MachinePolicy the locker later takes, until an Error State or a destructive configuration releases it; it depends on KeyType, and covers every field the Machine may use in any State and the largest ADS that the implementation keeps for it. During a system-specific import, it also covers the data held as received, allocated at the opening from AuxDataLen, so that its exhaustion is reported there, even when a redundant format needs more than the converted CC; the excess may be released when the base import completes.

P6 requires that exhaustion be reported, which a capacity that grew after provisioning could not guarantee; releasing it in an Error State frees resources for a locker that holds only its MDH. It depends on KeyType because a SKID may denote a key that never enters the KLF; with KeyType = 2 the provisioning-completing kl.mgmt allocates nothing more; dropping the ADS shortens the SCCs but not the capacity.

GR54

A multi-share implementation provisions, imports and exports reconstructed values, so that a protected Machine differs from the unprotected one only in SCProtection.

P14 requires an implementation-independent format: exporting shares would make SCCs larger and readable only by the implementation that wrote them. Shares or masks may still travel in the ADS, but no ADS, alone or combined with other exported data, such as other SCCs of the same CC, may reveal a key value configured by a SKID.

GR55.1

For a Machine with several keys, such as XEX/XTS, one SKID retrieves all of them, not one SKID per key.

One SKID per key would complicate the SKS and the architecture, and the two keys of XEX form a single unit. KLE does not restrict how many keys one SKID may cover.

GR45

Random bits are drawn before any output is written, so a KLE RBG-unavailable exception leaves the output unchanged and an in-place kl.exec keeps its input for re-execution, while a permanent failure invalidates the locker and the unwritten part of the output is zeroed (Rule GR14). For kl.clone and kl.derive, the destination transitions to Invalid and the source is untouched.

The draws come at the start of the operation, where a long-running one draws its nonce anyway; no output buffer is needed to undo a partial write. A failed kl.clone or kl.derive is treated as an attempt to manipulate its destination, which it was about to overwrite.

GR42

kl.store and kl.output take their data from a locker or the KLIOBUF, not from a register: treating lockers and KLIOBUF bytes as registers gives them the data dependencies of an ordinary store, so a copy from kl.input to kl.output cannot produce out-of-thin-air values under RVWMO, since Rule GR42 makes every register and locker that decides an accessed address an address source.

The tracking is that of any register file; an implementation that never reorders a store before the load it depends on meets it without extra logic.

GR11

Xl = 0 is the encoding of a transfer to or from a locker, and with klnamedlocker = 32 it falls through like every other instruction naming KLNL: raising an exception there would make locker-transfer code depend on Zklio and on the KLIOBUF, which it never uses. A transfer of zero bytes touches neither memory nor the KLIOBUF, so the no-operation exposes and changes nothing but klstart.

Hardware tests Xl right after the checks of Rule GR12, and an M-mode emulator needs no KLIOBUF access to emulate it.

Validity of Metadata

Invalid Metadata takes precedence over unsupported Metadata, and the opening kl.mgmt tests validity first, except that the conditions that a Machine defines apply only to a Machine that the KLE unit implements.

Only a valid Version fixes the layout of Machine, MachinePolicy and MachineExtension, which the unsupported test reads; an exception is also less destructive than Error State Invalid, so it is raised only for Metadata that is otherwise valid. A KLE unit cannot decide the conditions of a Machine that it does not implement, so it reports such Metadata as unsupported, and the emulating M-mode handler decides them.

mklvendorid, mklarchid, and mklimpid

The identification CSRs mklvendorid, mklarchid and mklimpid are read-only and M-mode-only; no user-level alias exists.

Only M-mode firmware needs the values: the unit forms IMPQUAL from them and checks it on import, so lower modes gain nothing from reading them, and a lower-mode read would give an emulated unit a value to present that nothing checks.

kl.clearall

kl.clearall sets the *llockerstatus fields to Dirty for every locker that it changes or for which any field in effect is Off, as kl.clear does.

A supervisor saves only Dirty lockers; a field left Clean or Off would let a cleared locker be restored at the next switch-in.

kl.clearads

kl.clearads zeroes the progress field P of an interrupted long-running operation (Rule GR38), which restarts when its instruction is next issued.

The outcome is that of importing, on a different KLE implementation, the SCC exported before the kl.clearads (Rule GR38), so software meets no new behavior.

GR55.2

The SKS resolves a SKID whatever the issuing mode; only the policies it associates with the key, and the minimum SCProtection it may set, restrict its use.

P16 requires only that a system key never leave and that its policies be inherited; a mode-dependent resolution would restrict provisioning, against P13. Whoever configures the SKS protects the key. The SKS policies are the only architectural control on which modes may use a System Key, hence Rule SR17.

GR55.3

The SKS always supplies a Locality for a SKID and may add other policies, or none.

The Locality binds the key to the system, as keys with the same SKID may serve unrelated purposes on different devices; further policies are optional because narrowing leaves an unset field unchanged.

Table 3. Choices of other normative statements
Statement Choice Why, and what the Principles leave open

GR9

The public fields of a Machine, placed first in its Serialized Content, and the first SCC_ClearLen2 blocks of the ADS, are authenticated as associated data and not encrypted; which fields are public depends only on immutable MDH fields, and a public field never holds a secret, an intermediate value or a kl.derive destination. Only the public-key Machines designate public fields for now: ML-KEM (ek, H(ek), ciphertext), ML-DSA (pubkey, signature), and the Elliptic Curve Machines (Signature, and Generator and SecondPt in the public-points variant, MachineExtension = 1, which fixes Generator to the default and refuses a shared-secret computation).

Encrypting values that are public anyway costs one AES-256 per block at export and import, about two thirds of an ML-KEM SCC, and hides from software values it may need, such as a public key. Export is not gated by UsagePolicy, and an SCC is readable on any device and after expiry, so only values public by their role may be clear; a computed signature or ciphertext counts as released, since it reveals nothing of the key. A split that depended on State, MachinePolicy narrowing or Content could expose a field that held a secret, and the ECC points can hold a shared secret or a password-derived generator, hence the separate variant. A value read from a clear block is unauthenticated until import (Rule SR19). Symmetric Machines may follow, for instance for an IV.

MR5

A State that expects a Form C kl.setst with an INPUT of at most 128 bits also admits Form D, whose two (RV64) or four (RV32) GPRs carry it, and Form A, a zero; Form B only where the State says so, for an integer of at most 64 bits.

Code without vectors needs no vector register to enter such a State (P7); how wide an INPUT is depends on the Machine, so the Rule is a Machine Rule.

XEX/XTS Modes

SM4_XEX is the XTS mode of GB/T 17964-2021, whose multiplication of the mask takes the bits of each byte in the reverse order; AES128_XEX and AES256_XEX follow SP 800-38E and IEEE 1619.

SP 800-38E and IEEE 1619 define XTS for AES only, and GB/T 17964-2021 is the standard that defines it for SM4; the IEEE construction with SM4 swapped in would match no standard, as OpenSSL’s default SM4-XTS shows.

XEX/XTS Modes

Ciphertext stealing in decryption uses the Machine-defined kl.setst kl_xex_state_steal, an operation (MR16), and two flags of StateExtension: the kl.setst skips mask index m-1, the next kl.exec decrypts at index m and steps the mask back with update_mask_inv, and the last one decrypts at index m-1 and ends in Success.

SP 800-38E decryption uses mask index m before m-1, while the mask of the plain sequence only advances; without these steps, software needs a kl.clone and a discarded block operation per data unit, and a second locker. Each mask index is still used once, and the flags admit each step once and in order. Every transition, same-State kl.setst included, clears both flags, so a new tweak starts without them.

CMAC Functions, OCB Mode

For b = 128, the CMAC dbl of every block cipher, SM4 included, and the OCB double use the update_mask of AES128_XEX; KLE defines OCB for AES only. For b = 64, the CMAC dbl reduces by R64.

SP 800-38B and RFC 7253 define one doubling, with R128 = 0x87, for every 128-bit block cipher, and SP 800-38B §5.3 one with R64 = 0x1B for every 64-bit block cipher; the reflected multiplication of GB/T 17964-2021 belongs to XTS with SM4 only, and would give CMAC subkeys that no implementation produces. OCB generalizes readily to other block sizes: the security proof of the original algorithm covers them, and cite:[cryptoeprint-2023-326] gives a lower bound on the nonce length.

Chaining/Feedback Modes (CBC, CFB, and OFB)

CFB takes its segment size u, 0 < u ≤ b, from AuxInfo[7:0], fixed at provisioning; its granularity is a byte, a kl.exec processes the ⌊`KLLEN`/u⌋ whole segments of its window and ignores the rest, and it halts only where a whole number of segments ends on a byte boundary.

SP 800-38A defines CFB for any segment size from 1 to b bits, and names CFB1, CFB8 and CFB128. u is a parameter of the CC, like tag_len_p: holding it in the MDH keeps kl.exec free of a size operand, needs no extra State, and fixes u for the life of the CC, so it cannot change inside a stream or between the users of one key. A byte granularity keeps the KLIOBUF bound at 16 bytes and LMUL free for any u; software packs the ignored tail into the next kl.exec. Interruption points stay on whole segments and whole bytes, which klstart counts, and with a vector operand on element boundaries too (Rule GR33.2), so SEW = 8 keeps every segment boundary resumable.

Chaining/Feedback Modes (CBC, CFB, and OFB)

CBC and OFB take whole blocks and CFB whole segments, with no padding or ciphertext stealing, and the Machines check neither the uniqueness nor the unpredictability of the IV; a kl.setst into Encrypt, Decrypt or Operate without an IV leaves the zero IV of Ready.

Padding is a data format that software chooses, and SP 800-38A puts the IV requirements on the caller, as Rule MR15 does for message limits.

Elliptic Curve Cryptography

A key that the Machine generates comes from an RBG of at least the security strength of its curve: 128 bits for x25519 and SM2, 224 bits for x448, as for ed25519 and ed448.

RFC 7748 and GM/T 0003-1 fix no strength, and the Prerequisites require only an SP 800-90A DRBG; without the bound, a conforming x448 key could carry less strength than its curve.

EdDSA-Specific Rules

A narrowing that clears MachinePolicy[0] destroys the state of H', as it destroys RndNum in Elliptic Curve Cryptography, but leaves HasHashState, bit 3 of StateExtension, unchanged.

The state of H' exists only while MachinePolicy[0] is set (Length of External Formats and KLF Capacity Usage of a Locker); a signing pass that loses it cannot complete, since its next kl.exec is gated, so nothing is lost that could still be used; HasHashState still records the open pass, so a verification pass, which MachinePolicy[0] does not gate, continues with a supported StateExtension @ State.

Hash and MAC Functions, and XOFs

Every hash, MAC and XOF Machine that instantiates or extends this section, which CMAC does not, pads the message itself and absorbs and emits whole bytes. Every one has Hash_Absorb_Last_Block for a final piece of up to b bits, which Xs = 0, or the direct transition from Hash_Absorb, leaves empty; the piece has any bit length where the standard defines bit strings (SHA-2, SM3, SHA-3, KMAC, Ascon, and HMAC over SHA-2, SM3 and SHA-3), with the bit order of the standard in its last byte, and is a whole number of bytes for BLAKE2. The message ends only by the kl.setst into Hash_Output or Hash_Verify, never by a kl.exec.

D2 asks that one routine shape serve every Machine. With caller padding, software must know each standard’s padding, and a message that ends in derived bytes, or in a held BLAKE2 block, needs the Machine to pad anyway; a padder exists already for HMAC and EdDSA. A uniform final-piece State keeps bit-length messages where the standard defines them, at the cost of one State that reuses PROCESS_VLI. Padding in the ending kl.setst makes Xs = 0 and the direct transition the same, and puts BLAKE2’s final-block flag on the held block. Bit granularity is confined to the single-block final piece, so Hash_Absorb, its interruption points and the kl.derive destination stay byte-granular; a word granularity would add checks without making a byte-buffering unit simpler. Every Machine thus has the same interruption points in Hash_Absorb and Hash_Output, so that a klstart meets the same outcome on every Machine. They are 0 and, if block_base is 0 when the kl.exec is issued (or b, for BLAKE2’s held block), any byte offset. The parameters of a Machine, BLAKE2’s nn and kk as HMAC’s K0, survive a return to Ready. BLAKE2 sets its defaults as an action of the provisioning, not as an operation of entering Ready, so that a locker reused by kl.setst computes the function its SCC was made for, and the initialization operations of a system-specific format never leave them unset. Since the parameters survive, every import that writes them checks their ranges (Rule MR3), as the Set_Aux_Value operation does. A caller’s own BLAKE2 key is ordinary input that the Machine cannot tell from the message, so kk is not checked against it: a mismatch only changes the hash, and only a missing key block is detected, by finalize().

Hash and MAC Functions, and XOFs

A non-zero Xs in the kl.setst into Hash_Output, which ends the message, is the output length: the Machine emits exactly Xs bits, then enters Success; for a fixed-output Machine Xs is at most the digest length, for HMAC at least 64, and for KMAC128 and KMAC256 at least 32, the minimum of SP 800-185, which their verification also admits; the bound of KMACXOF128 and KMACXOF256 may be as short as 8 bits, their granularity. The bound is a prefix of the full output, not a different function, except for KMAC128 and KMAC256, whose L is encoded; for BLAKE2 it is a prefix of the nn-byte digest.

Truncation is always possible by reading fewer bytes. Respecting Xs only lets a truncated read end in Success, and lets one sequence cover KMAC. The bound lives in fields or padding that every Content already has, so no image grows; KMAC keeps L where SHA-3 keeps out_len. The kl.setst that ends the message clears last_block_len, so the direct ending from Hash_Absorb and an empty final piece (Xs = 0 in Hash_Absorb_Last_Block) leave the same Content, and BLAKE2 can hold out_len in that Position.

Ascon-AEAD128 with Nonce Masking

Nonce masking with a set nonce uses the set-nonce Machine, with K1 as key and N xor K2, computed by software, as nonce; it cannot use a K1 and K2 that a System Key Identifier retrieves.

The set-nonce PI has no field for K2, and its SKID retrieves key alone; software that computes N xor K2 already holds K2, so the masked nonce in the PI exposes nothing new.

MR12

The verified tag length tag_len_p of GCM, CMAC, HMAC and Ascon-AEAD128 and its variants is held in the AuxInfo field of the MDH, which these Machines use for nothing else, and not in the Serialized Content.

The 16 bits cost no Content, which may save a block of the SCC in some cases, and kl.getmd* returns the value without a privileged read, so software can use it to identify the Machine configuration. The value is not secret, and the MDH is authenticated in every SCC.

Ascon-Hash256, Ascon-CXOF128

The Ascon hashes instantiate the generic section with a 64-bit rate; Ascon-Hash256 counts its output in out_len, not in MachineUse. Ascon-CXOF128 absorbs Z0 on entering Set_Aux_Value, loads Z, of any bit length up to 2048, as a long field, and pads it on leaving that State, only after a complete load.

Z0 carries the length of Z and precedes it, so the length comes with the kl.setst; padding on leaving keeps the padding with the Machine; the 2048-bit bound of SP 800-232 is cheap to check once the Machine counts Z. An incomplete Z is Invalid rather than an unconfigured field, since absorbing it has already changed state.

GCM Mode

A kl.setst that leaves Enc_Last_Block or Dec_Last_Block before its kl.exec processes no final block, and the length block that software supplies counts only the data processed.

The Machine does not count the data, so it cannot check the length block; a length block that counts an omitted block yields a tag of neither message, which verification rejects.

MR10

A final fractional block of n bits is processed by one kl.exec on the n least significant bits of its INPUT; a shorter KLLEN is not zero-padded but Invalid, and with n = 0 the Machine does the final operations on entering the State and proceeds at once, unless it defines otherwise (OCB stays and takes a Form D kl.exec). Where software chooses the successor, the State stays and admits no further kl.exec. A kl.setst that leaves the State before its kl.exec is Invalid, except one naming Ready, which every Valid State admits (GR19.3).

Zero padding would let a short KLLEN pass as a shorter message; a second kl.exec of a completed block looks like an attempt to alter the State, so it invalidates the locker. Where policy gates the successors (hash output or verification), an automatic transition would bypass the gate (MR1).

OCB Mode

A Form A kl.setst out of Enc_Last_Block or Dec_Last_Block with last_block_len = 0 is admitted and performs the operation of the Form D kl.exec on entry; every message passes through these States.

With no data left, nothing remains to process, so the Machine may proceed to the finalizing State; the final block of a message of whole blocks is processed there, as the standard requires.

XEX/XTS Modes

A kl.setst into Decrypt is admitted from Encrypt, and the reverse.

The mask is replaced by the new tweak, so no state carries over, and a locker may be reused without returning to Ready.

GR29

A key field that receives a shared secret takes its first dest_length bytes, whatever the secret’s length; a destination longer than the secret is Invalid (it is never zero-padded), except the HMAC K0, which FIPS 198-1 Step 3 pads.

A shared secret has a fixed size that its Machine defines. Truncation to a key of the same family is the usual use (a 256-bit secret for a 128-bit key), whereas zero padding would give a key with known bytes and a false key length. HMAC is the exception because FIPS 198-1 defines its padding.

MR14

Entering or leaving decapsk_Input before the load completes zeroes the whole decapsk field, its encapsk sub-field included, and clears HasEncapsk and HasDecapsk.

The encapsk sub-field is part of the field being loaded, so a partial load would otherwise leave a public key that no longer matches the secret part, and HasEncapsk would vouch for it.

GCM-SIV Mode

A same-State kl.setst into Set_Aux_Value or Set_Aux_Value_2 is Invalid.

The nonce and the SIV are set by the kl.setst that enters the State, not loaded by kl.exec, so there is no load to restart (GR19.2).

EdDSA-Specific Rules

After a narrowing that disables the operation of the open pass, its next kl.exec is Invalid. A kl.setst that ends a signing pass is admitted only toward Ready; one that ends the verification pass is admitted toward Ready or an enabled operation.

The general gate (MR1) applies unchanged; finalizing a disabled verification pass computes only the public k'. Finalizing a signing pass would read the state of H' that the narrowing destroyed, and every such exit would fail its entry conditions anyway.

Architectural Model

Locker state is accessible in clear only to M-mode and authenticated Debug mode, and only M-mode may emulate KLE; the exception is the clear data that software itself supplied to an open management operation.

P12 keeps locker state from all software except the trusted base; that base is M-mode, which may program the CSK, and authenticated Debug mode.

kl.avail and kl.size, KLE Emulation Control in mstatus

With mstatus.kleemulation set, a kl.avail or kl.size of Form B or C traps on an MDH whose combination of the fields that kl.avail examines is not implemented natively by the KLE unit; with it clear, the instruction returns 0 for such an MDH. The lookup comes after every condition that does not depend on which Machines are implemented (reserved State or StateExtension, an Error State, an unsupported Version, a reserved field value), so an Error-State MDH is sized 16 bytes either way, since its image is the MDH alone, and the trap occurs only when the answer depends on an emulated Machine.

Software discovers Machines with kl.avail, and sizes images with kl.size, from an MDH alone, before any locker holds the Machine; M-mode firmware that emulates a Machine must then answer for it. The bit keeps the non-trapping answer where nothing is emulated. Its position, the discovery of which instructions and Machines are emulated, and whether an emulated Machine may replace a native one are open points (Discussion Points).

mllockerstatus, sllockerstatus, and vsllockerstatus for Dirtiness Tracking

The KLE locker-Off exception is one cause, whichever *llockerstatus field is Off; medeleg and hedeleg delegate it as any other cause, a mode that sets one of its own fields to Off keeps it undelegated, and the handler that takes it forwards it to the most privileged mode whose field is Off.

One cause serves every field, and the handlers resolve the owner by examining the fields in order. Delegation lets medeleg and hedeleg name the mode that handles the exception, sparing a trap to M-mode where only lower modes mark lockers Off; a mode that marks its own field keeps the cause, so that it sees the exception before any lower mode, for instance to restore an SCC lazily (P14).

Cryptographic Lockers, Rule SR1 and Context Save Order

The lockers are shared by all privilege modes of a hart; isolating them between modes is the duty of software.

P10 argues against lockers per mode, which would not remove context switching anyway.

The Cryptographic Locker File and Authentication Information

The KLF guarantees capacity for two fully configured CCs of the largest supported Machine, plus the implementation’s working state; the 32 lockers are not all guaranteed to be configurable at once; more capacity is desirable.

The 32 follows from the 5-bit register fields, and Machines with small states allow more lockers in the same space. Two CCs suffice for P13, since software can save a CC and clear its locker (lazy offload) to make room.

The Cryptographic Locker File and Authentication Information

The KLF resists rollback by an access that this specification does not permit, but an SCC does not: an earlier SCC can always be re-imported, which replaces the locker by the earlier CC.

P15 asks for confidentiality and integrity, not freshness, which would need per-CC state outside the locker (P10); re-import has legitimate uses.

SCProtection Field

A protection level applies to the export and import of the locker, and otherwise only to the operations that need it for security, such as signature generation but not verification, and only as far as the cryptographic method needs it: the execution time of ML-DSA may depend on its rejection loops.

The Principles say nothing about side channels. Export and import use the AES and POLYVAL hardware of the Machines, and a leak there would expose the keys that seal every SCC. The scope follows the referenced standards: FIPS 203 and FIPS 204 require no constant execution time, and leave the bound on their loops optional (KLE requires it) (ML-KEM, ML-DSA), and a verification on public data has no secret to protect.

UsagePolicy Field

Bits 0–4 allow U-, VS-, S-, M- and Debug mode; Debug mode outside authenticated Debug mode also needs the bits of the debug access privilege and of every mode below it, and a zero field admits no mode; mstatus.MPRV is ignored.

P16 fixes neither the default nor the issuing mode. With every bit a grant, narrowing is one AND, and a CC is usable only in the modes that software deliberately allowed.

Locality Field

A Locality Secret of any Group that is not provisioned or is all zero is unconfigured, and no provisioned HW Binding Group secret may be all zero.

A zero or absent secret gives no separation; a requested Locality is substituted or rejected, never silently weakened (invalid Metadata).

Locality Field

A Locality binds only the sealed CC: a CC in a locker stays usable after a Locality Secret it names changes, and its next export binds to the new value.

P15 requires only the seal to carry the binding; for a resident locker, Rule SR1 closes the gap.

ExpirationDate Field

ExpirationDate is evaluated only when a usage instruction issues or resumes, and only in a Valid State.

The Principles say nothing about time. A secure clock is assumed never to be rolled back, so a reading before the epoch converts to 0: a genuine date before the epoch, when no CC can have expired. Protection against rollback is a property of the clock, not of the KLE unit. An unreadable secure clock traps, rather than making the instruction a silent no-op, so that M-mode can handle the failure, which may be induced by glitching the clock; the instruction keeps the State, so that a handler that restores the clock can re-execute it, and a handler that cannot can put the locker in Error State Expired with kl.setste.

AuxDataLen and ADSDropped Fields, Decryption and Authentication of a Complete SCC into a Locker

ADSDropped is an unauthenticated bit of the MDH, and an ADS that fails its check is dropped, with the implementation-defined subfields of the MDH, without rejecting the SCC.

P15 asks that the MDH be authenticated. Leaving this one bit out lets a nested export preserve an import after Content2 was dropped, without enlarging the format.

GR18

A klstart at or past the end of the transfer window makes the window empty, without error; one inside the window that is not an interruption point invalidates the locker.

P3 requires resumption only from points the instruction produces. An out-of-window value means completion, as vstart ≥ vl does in RVV; any other is misuse (D4(a)), which could release plaintext in place of ciphertext.

GR14, kl.mvin and kl.mvout

kl.mvin and kl.mvout keep klstart across instructions as an offset into the image, instead of clearing it on retirement.

D7 makes klstart the progress of one instruction; as the offset of the whole transfer it spares an offset operand (P8).

Destructive Configuration Instructions

kl.clear and kl.clearall need only release the Content, and a zero kliobuflen only hides the KLIOBUF; an implementation that supports Level C must zeroize both at once.

P16 forbids returning stale secrets, and newly allocated KLF capacity reads as zero (Destructive Configuration Instructions); zeroizing at once only shortens the time secrets stay in the KLF or the KLIOBUF, where Level C assumes a physical attacker who could read them (P12).

kl.rstrl, kl.rstrh, and kl.rstrv

A request weaker than the current policy sets Privilege Violation for Locality and is ignored for ExpirationDate; a MachinePolicy or UsagePolicy request is AND-ed, so it only removes functions or permissions, and all ones leaves the field unchanged.

P16 forbids only the widening, not a particular response to an attempt; keeping the earlier ExpirationDate matches Narrowing of Metadata. A request that cannot weaken the CC is harmless, so it is not an error; a Locality subfield that names another binding changes who may use the CC, so it is. Removal requests make every narrowing of the two policies expressible, MachinePolicy = 0 included.

Management States and Formats, Locker Management Operations

A PCCC is protected only as its base image is: a PI-shaped one is the clear PI, one taken during a system-specific import the data as software supplied it, and a nested completion checks only the base type.

P15 protects a CC, and a partial provisioning holds only what software supplied. Sealing it would add a third sealed format; an SCC-shaped PCCC is authenticated when its base operation completes, and Rule SR1 keeps a clear one from other software contexts, of the same or a lower privilege.

The SCC Authenticated Encryption Scheme

Sealing is deterministic: with no nonce, the same CC sealed twice under the same CSK and Localities gives the same SCC.

Deterministic sealing reveals only whether two SCCs seal the same CC, nothing of the secret material (P15), and makes the SCC shorter and the derived keys cacheable; GCM-SIV keeps it secure up to about 264 observed blocks.

KLE Unit Reset and M-mode-only Harts

A non-retentive hart suspend is not a hart reset; whether the KLE state survives it is implementation-defined, and retention is strongly recommended.

Suspend mechanisms differ across platforms and the specification does not define them. Losing the lockers would force software to rebuild every CC on resume, which is expensive and, for imported keys, may be impossible without the SCCs (P14).