enigmastick
Documentation menu
On this page

Host library / reference

Rust API.

One device handle. Typed requests. Owned responses.

These declarations are imported from the public host library API. See the Rust guide for connection and signing examples.

Device methods

Device::open

Rust
pub fn open() -> Result<Self, EnigmaError>

Finds a single matching USB device, checks the data interface and bulk endpoints, and claims the interface. Multiple matching devices produce an error. The current transaction timeout is 10 seconds.

Device::status

Rust
pub fn status(&mut self) -> Result<Status, EnigmaError>

Returns token and session state. A status check is a snapshot; a session can expire before a later operation.

Device::authenticate

Rust
pub fn authenticate(&mut self, pin: &str) -> Result<(), EnigmaError>

Unlocks the token with a PIN. This opens a reusable device session; it is not scoped to this host handle. PIN input and prompting belong in your application.

Device::lock

Rust
pub fn lock(&mut self) -> Result<(), EnigmaError>

Closes the authenticated device session. Closing a USB handle alone does not lock the token.

Device::generate_key

Rust
pub fn generate_key( &mut self, request: GenerateKeyRequest, ) -> Result<GenerateKeyResponse, EnigmaError>

Creates a persistent key and returns its object ID. Use a compatible type, size, and usage. The timestamp is supplied by the host.

Device::encrypt

Rust
pub fn encrypt( &mut self, request: EncryptRequest, ) -> Result<EncryptDecryptResponse, EnigmaError>

Encrypts a bounded message with an AES ENCRYPT key. The AES-GCM output is nonce[12] || ciphertext || tag[16].

Device::decrypt

Rust
pub fn decrypt( &mut self, request: DecryptRequest, ) -> Result<EncryptDecryptResponse, EnigmaError>

Decrypts an AES-GCM blob, or performs RSA-OAEP/SHA-1 decryption with a suitable RSA key. Returns owned plaintext bytes.

Device::sign

Rust
pub fn sign(&mut self, request: SignRequest) -> Result<Signature, EnigmaError>

Signs a message with RSA-PSS or ECDSA, or creates an HMAC, according to the key type. Mechanism selection follows the firmware.

Device::verify

Rust
pub fn verify(&mut self, request: VerifyRequest) -> Result<bool, EnigmaError>

Verifies an HMAC. This operation does not implement on-device RSA or ECDSA signature verification.

Device::ecdh

Rust
pub fn ecdh(&mut self, request: EcdhRequest) -> Result<EcdhResponse, EnigmaError>

Performs ECDH followed by HKDF-SHA-256 inside the secure element to create a persistent AES-256 key. Returns its ID and the public salt and info.

Device::get_public_key

Rust
pub fn get_public_key(&mut self, key_id: u32) -> Result<PublicKey, EnigmaError>

Exports an RSA or EC public key as DER SubjectPublicKeyInfo. Private material is not returned.

Device::list_keys

Rust
pub fn list_keys(&mut self, filter: KeyListFilter<'_>) -> Result<KeyList, EnigmaError>

Returns owned key metadata. Type, usage, and label filters combine with AND; a key ID filter takes precedence.

Device::destroy_key

Rust
pub fn destroy_key(&mut self, key_id: u32) -> Result<(), EnigmaError>

Permanently deletes a customer key and its metadata. IDs may be reused. A timeout does not prove deletion failed.

Device::close

Rust
pub fn close(&mut self) -> Result<(), EnigmaError>

Releases the USB connection. Drop also attempts cleanup. This is separate from explicitly locking the device.

Request & response types

KeyMeta

Rust
pub struct KeyMeta {
    pub id: u32,
    pub key_type: KeyType,
    pub key_usage: KeyUsage,
    pub size: u16,
    pub label: String,
    pub created_at: u32,
}

Metadata is stored on the ESP, separate from secret key material in the secure element. Object IDs may be reused after deletion.

KeyList

Rust
pub struct KeyList {
    pub keys: Vec<KeyMeta>,
}

PublicKey

Rust
pub struct PublicKey {
    pub encoding: u32,
    pub public_key: Box<[u8]>,
}

The current encoding is DER SubjectPublicKeyInfo (encoding value 1). public_key owns its bytes.

KeyListFilter

Rust
pub struct KeyListFilter<'a> {
    pub key_type: Option<KeyType>,
    pub key_usage: Option<KeyUsage>,
    pub key_label: Option<&'a str>,
    pub key_id: Option<u32>,
}

Use Default::default() for an unfiltered query. A key_id filter overrides other filters; remaining filters use AND logic.

GenerateKeyRequest

Rust
pub struct GenerateKeyRequest<'a> {
    pub key_type: KeyType,
    pub key_usage: KeyUsage,
    pub key_size: u16,
    pub label: &'a str,
    pub timestamp: u32,
}

For EC, key_size is the curve size (256, 384, or 521). Labels need not be unique. timestamp is Unix seconds supplied by the host.

GenerateKeyResponse

Rust
pub struct GenerateKeyResponse {
    pub key_id: u32,
}

SignRequest

Rust
pub struct SignRequest<'a> {
    pub key_id: u32,
    pub message: &'a [u8],
}

VerifyRequest

Rust
pub struct VerifyRequest<'a> {
    pub key_id: u32,
    pub message: &'a [u8],
    pub signature: &'a [u8],
}

signature holds an HMAC, not an RSA or ECDSA signature for this firmware command.

Signature

Rust
pub struct Signature {
    pub signature: Box<[u8]>,
}

EncryptRequest

Rust
pub struct EncryptRequest<'a> {
    pub key_id: u32,
    pub plaintext: &'a [u8],
}

DecryptRequest

Rust
pub struct DecryptRequest<'a> {
    pub key_id: u32,
    pub ciphertext: &'a [u8],
}

EncryptDecryptResponse

Rust
pub struct EncryptDecryptResponse {
    pub data: Box<[u8]>,
}

EcdhRequest

Rust
pub struct EcdhRequest<'a> {
    pub private_key_id: u32,
    pub public_key_encoding: PublicKeyEncoding,
    pub public_key_bytes: &'a [u8],
    pub result_label: &'a str,
    pub timestamp: u32,
}

EcdhResponse

Rust
pub struct EcdhResponse {
    pub key_id: u32,
    pub salt: Box<[u8]>,
    pub info: String,
}

salt and info are public derivation parameters. Use these returned values when reproducing HKDF on the peer.

Status

Rust
pub struct Status {
    pub token: TokenState,
    pub session: SessionState,
}

DeviceError

Rust
pub struct DeviceError {
    pub code: DeviceErrorCode,
    pub message: String,
}

States & errors

KeyType

Rust
pub enum KeyType {
    Aes = 0x01,
    Rsa = 0x02,
    Ec = 0x03,
    Hmac = 0x04,
}

KeyUsage

Rust
pub enum KeyUsage {
    Encrypt = 0x01,
    Sign = 0x02,
    Derive = 0x03,
}

PublicKeyEncoding

Rust
pub enum PublicKeyEncoding {
    DerSpki = 0x01,
}

TokenState

Rust
pub enum TokenState {
    Uninitialized = 0x0,
    Provisioning = 0x1,
    Ready = 0x2,
}

SessionState

Rust
pub enum SessionState {
    Closed = 0x0,
    Authenticated = 0x1,
    Fault = 0x2,
}

DeviceErrorCode

Rust
pub enum DeviceErrorCode {
    Ok = 0x00,
    AuthRequired = 0x01,
    AuthFailed = 0x02,
    InvalidInput = 0x03,
    UnsupportedOperation = 0x04,
    MissingKey = 0x05,
    PolicyReject = 0x06,
    Storage = 0x07,
    BadCommand = 0x08,
    Serialize = 0x09,
    InitFailed = 0x0A,
    InvalidState = 0x0B,
    Fail = 0xFF,
}

DecodeError

Rust
pub enum DecodeError {
    TruncatedHeader,
    TruncatedPayload,
    UnexpectedPayload,
    InvalidMagic,
    UnsupportedVersion(u8),
    UnexpectedResponse(u8),
    InvalidTokenState(u32),
    InvalidSessionState(u32),
    InvalidUtf8,
    InvalidArgument,
}

EnigmaError

Rust
pub enum EnigmaError {
    Protocol(DecodeError),
    Device(DeviceError),
    Usb(rusb::Error),
    DeviceNotFound,
    MultipleDevicesFound,
    MissingInterface { interface: u8, alternate: u8 },
    MissingBulkEndpoint(u8),
    InvalidArgument,
    MalformedOutput,
    BufferTooSmall,
}

Separates USB access, malformed responses, firmware errors, invalid arguments, and device selection failures. Match structured variants rather than English error messages.