Skip to main content

CommandOpcode

Enum CommandOpcode 

Source
#[repr(u8)]
pub enum CommandOpcode {
Show 24 variants Info = 1, GetPubkey = 2, Sign = 3, GenKey = 4, ReadConfigZone = 5, ReadConfigSlot = 6, VerifyPin = 7, SetPin = 8, UnblockPin = 9, GetPinStatus = 10, SetPuk = 11, CloseSession = 12, EmergencyReset = 13, ReadSlotBlock = 14, ReadSlotWord = 15, WriteConfigZone = 16, ProvisionSlot = 17, ProvisionInitialPin = 18, ProvisionInitialPuk = 19, ProvisionIoKey = 20, ReadCounter = 21, LockConfigZone = 240, LockDataZone = 241, LockSlot = 242,
}
Expand description

Opcode byte for each command.

Variants§

§

Info = 1

0x01 - Info: read firmware version, chip serial, provisioning state. Payload: empty.

§

GetPubkey = 2

0x02 - GetPubkey(slot): read a slot’s public key (64 bytes). Payload: [slot: u8].

§

Sign = 3

0x03 - Sign(slot, digest): produce an ECDSA P-256 signature. Requires an active PIN session and a touch. Payload: [slot: u8, digest: [u8; 32]].

§

GenKey = 4

0x04 - GenKey(slot): regenerate a P-256 key pair. Requires an active PIN session. Payload: [slot: u8].

§

ReadConfigZone = 5

0x05 - Read the 128 bytes of the chip’s config zone. Payload: [block: u8] where block is in 0..=3. The 128-byte config zone is returned one 32-byte block at a time so the response fits in a single report. The host issues this command four times, once per block, to assemble the full image.

§

ReadConfigSlot = 6

0x06 - Read the 4-byte SlotConfig + KeyConfig for one slot. Payload: [slot: u8].

§

VerifyPin = 7

0x07 - VerifyPin(pin): open a PIN session (30 s window). Payload: [pin: [u8; 4]] (each byte holds an ASCII digit '0'..'9').

§

SetPin = 8

0x08 - SetPin(old, new): change PIN within an active session. Payload: [old: [u8; 4], new: [u8; 4]].

§

UnblockPin = 9

0x09 - UnblockPin(puk, new_pin): reset PIN counter via PUK. Payload: [puk: [u8; 8], new_pin: [u8; 4]].

§

GetPinStatus = 10

0x0A - Read current PIN / PUK retry counters. Payload: empty.

§

SetPuk = 11

0x0B - SetPuk(old_puk, new_puk, io_key): change the PUK. Requires an active PIN session (proves the caller knows the current PIN). Rewrites slot 6 via the encrypted-write protocol. Payload: [old_puk: [u8; 8], new_puk: [u8; 8], io_key: [u8; 32]].

§

CloseSession = 12

0x0C - CloseSession: terminate the current PIN session immediately, without waiting for the 30 s inactivity timeout.

Idempotent: closing an already-closed session is a no-op and still returns Ok. No payload from the host. No payload in the response.

§

EmergencyReset = 13

0x0D - EmergencyReset(magic, io_key): last-chance reset. Requires that both PIN and PUK batches are exhausted. The firmware refuses to run otherwise with the EmergencyResetNotPermitted status (which carries the actual tries-remaining figures in its payload).

Regenerates the ECC private keys in slots 0..=4 and 7 (the user’s secrets are lost), resets PIN to "0000", generates and stores a fresh random PUK (returned in the response payload). The user is granted one fresh batch of PIN attempts and one fresh batch of PUK attempts.

Protected against accidental invocation by a magic word (0xBADC0FFE, little-endian on the wire). The CLI also requires an interactive double-confirm before sending.

Payload: [magic: [u8; 4], io_key: [u8; 32]] (36 bytes). Response payload on success: [new_puk: [u8; 8]].

§

ReadSlotBlock = 14

0x0E - ReadSlotBlock(slot, block): read one 32-byte block from a data slot. Useful for bring-up diagnostics (verify what ProvisionSlot wrote) and for inspecting the IO key in slot 8 before locking the data zone.

The chip applies the slot’s IsSecret / EncryptRead policy and rejects reads of private ECC keys. No host-side filter is added here: the chip is the authority.

Payload: [slot: u8, block: u8]. Response: [data: [u8; 32]].

§

ReadSlotWord = 15

0x0F - ReadSlotWord(slot, block, offset_words): read one 4-byte word from a data slot. Same policy as Self::ReadSlotBlock. Payload: [slot: u8, block: u8, offset_words: u8]. Response: [data: [u8; 4]].

§

WriteConfigZone = 16

0x10 - WriteConfigZone(blob): replace the writable part of the config zone. Payload: [block: u8, blob: [u8; 32]]. The host issues this command four times, once per block index 0..=3.

Two blocks of the config zone have a special wire-level shape because the chip’s Write command refuses some words inside them:

  • Block 0 : words 0..=3 (chip-side bytes 0..16) are the read-only factory area. The firmware writes only words 4..=7 (bytes 16..32) as four 4-byte transfers. Payload bytes 0..16 are ignored; callers may set them to any placeholder value (the canonical config-generator emits zeros).
  • Block 2 : word 5 (chip-side bytes 84..88) covers UserExtra, Selector, LockValue, and LockConfig. Those are modified only via the dedicated UpdateExtra and Lock commands; the Write command rejects a 32-byte transfer that includes them. The firmware writes block 2 as seven 4-byte transfers at word offsets 0..=4 and 6..=7. Payload bytes 20..24 are ignored.

Blocks 1 and 3 are written wholesale as a single 32-byte transfer.

This mirrors the strategy of CryptoAuthLib’s calib_write_bytes_zone (lib/calib/calib_basic.c).

§

ProvisionSlot = 17

0x11 - ProvisionSlot(slot, value): write a 32-byte cleartext value into one of the data slots. Only accepted by the firmware for the three policy-allowed slots (5, 6, 8). Used at provisioning to install the initial PIN hash, PUK hash, and IO key, before LockDataZone. Returns InvalidSlot for other slots and chip-error after data lock. Payload: [slot: u8, value: [u8; 32]].

§

ProvisionInitialPin = 18

0x12 - ProvisionInitialPin: write SHA256("0000" || pin_salt) into slot 5 in cleartext, where pin_salt is derived from the chip’s serial. No payload. Used at provisioning instead of ProvisionSlot --slot 5 so that the host does not need to reimplement the PIN-hash derivation. Returns Ok (empty payload) on success.

§

ProvisionInitialPuk = 19

0x13 - ProvisionInitialPuk: generate a fresh random 8-digit PUK from the chip’s RNG, compute its hash with the per-chip salt, write the hash into slot 6 in cleartext, and return the PUK in the response payload so the operator can record it. This is the only opportunity to learn the PUK. No payload from the host. Response: [puk: [u8; 8]].

§

ProvisionIoKey = 20

0x14 - ProvisionIoKey: generate a fresh random 32-byte I/O Protection Key from the chip’s RNG, write it into slot 8 in cleartext, and return it in the response payload so the host can store it for later encrypted writes. This is the only opportunity to learn the IO key. No payload from the host. Response: [io_key: [u8; 32]].

§

ReadCounter = 21

0x15 - ReadCounter(counter_id): read the raw value of an ATECC608B monotonic counter without modifying it. Diagnostic tool used for bring-up and debugging. Payload: [counter_id: u8] where counter_id is 0 (Counter0, backs PIN slot) or 1 (Counter1, backs PUK slot). Response: [value: [u8; 4]] in little-endian (the same u32 the chip returns from Counter(mode=Read)).

Unlike GetPinStatus which converts the raw count into “tries remaining” via the service’s batch logic, this command returns the chip’s binary count unmodified. Useful to verify the batch-arithmetic against the actual hardware state during development.

§

LockConfigZone = 240

0xF0 - Lock the config zone permanently. Payload: [magic: [u8; 4], crc: [u8; 2]]. The CRC is computed by the host CLI over the full 128 bytes of the current configuration zone and is verified one last time by the chip before commit.

§

LockDataZone = 241

0xF1 - Lock the data zone permanently. Payload: [magic: [u8; 4]]. No CRC: secret-bearing slots cannot be read back to compute one.

§

LockSlot = 242

0xF2 - Lock a single slot permanently. Payload: [magic: [u8; 4], slot: u8].

Implementations§

Source§

impl CommandOpcode

Source

pub(crate) const fn from_byte(byte: u8) -> Option<Self>

Map a raw byte to a CommandOpcode, if it is a recognized value.

Returns None for any opcode the firmware does not implement, including reserved-for-future-use values.

Source

pub const fn as_u8(self) -> u8

The raw opcode byte that goes on the wire.

Trait Implementations§

Source§

impl Clone for CommandOpcode

Source§

fn clone(&self) -> CommandOpcode

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CommandOpcode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for CommandOpcode

Source§

fn eq(&self, other: &CommandOpcode) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl TryFrom<u8> for CommandOpcode

Source§

type Error = UnknownOpcode

The type returned in the event of a conversion error.
Source§

fn try_from(byte: u8) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl Copy for CommandOpcode

Source§

impl Eq for CommandOpcode

Source§

impl StructuralPartialEq for CommandOpcode

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.