enigmastick
Documentation menu
On this page

Host library / reference

C API.

The C interface to Enigma Stick. Exact declarations from enigma.h, with explicit ownership and caller-provided buffers.

Start with the C guide for a complete connection example. Function and parameter documentation below is generated from the host library header.

Current development API. Match the host library and firmware from the same development period. Review mechanisms and limits before choosing key sizes or buffer capacities. RSA-4096 generation can exceed the host library’s current 10-second timeout.

Functions

enigma_open

Open a connection to the Enigma device.

C
enigma_result enigma_open(
    enigma_device ** device,
    enigma_error * error
);

Secure a USB handle to the Enigma device to be able to read and write data frames over the wire. out_device is set to NULL before attempting to open the device.

ParameterDescription
deviceDevice handle
errorNULL or error if device could not be opened
codeError code

enigma_status

Retrieve device status.

C
enigma_result enigma_status(
    enigma_device * device,
    enigma_status_info * status,
    enigma_error * error
);

Enigma status contains the global state of the token and session. The token status displays the initialization state of the crypto token. The session status is for whether or not the token has an open authenticated session.

ParameterDescription
deviceDevice handle
statusResulting status
errorNULL or error if status could not be retrieved
codeError code

enigma_authenticate

Authenticate the device token.

C
enigma_result enigma_authenticate(
    enigma_device * device,
    const char * pin,
    enigma_error * error
);

Authenticating the token unlocks it globally. Cryptographic operations require the token to be authenticated. Authentication only works if the token is already locked.

ParameterDescription
deviceDevice handle
pinDevice authentication PIN
errorNULL or error if status could not be retrieved
codeError code

enigma_lock

Lock the device token.

C
enigma_result enigma_lock(
    enigma_device * device,
    enigma_error * error
);

Locking the token prevents cryptographic operations from taking place on the secure element and closes the open session on the ESP. Locking only works if the token is already authenticated.

ParameterDescription
deviceDevice handle
errorNULL or error
codeError code

enigma_generate_key

Generate a key on device.

C
enigma_result enigma_generate_key(
    enigma_device * device,
    enigma_key_type key_type,
    enigma_key_usage key_usage,
    uint16_t key_size,
    const char * label,
    uint32_t * key_id,
    enigma_error * error
);

Generate a key on the secure element. Supported key types, usages, and sizes:

AES 128/256 : ENCRYPT HMAC 256/512 : SIGN RSA 1024/2048/4096 : ENCRYPT,SIGN EC P256/P384/P521 : SIGN,DERIVE

Please note that RSA 4096 generation takes around 30 seconds to complete. Most other keys and respective sizes complete within around 1-2 seconds.

ParameterDescription
deviceDevice handle
key_typeKey type
key_usageKey usage
key_sizeKey size in bits (or curve for EC)
labelKey label
key_idResulting key ID
errorNULL or error
codeError code

enigma_encrypt

Encrypt arbitrary data.

C
enigma_result enigma_encrypt(
    enigma_device * device,
    uint32_t key_id,
    const uint8_t * plaintext,
    size_t plaintext_len,
    uint8_t * ciphertext,
    size_t capacity,
    size_t * ciphertext_len,
    enigma_error * error
);

Encrypt arbitrary plaintext with an ENCRYPT key. The firmware will reject a key that does not have appropriate key usage. The ciphertext buffer is caller provided and must have enough capacity for the resulting ciphertext, or the function will fail.

ParameterDescription
deviceDevice handle
key_idEncryption key ID
plaintextPlaintext to be encrypted
plaintext_lenLength of plaintext
ciphertextCiphertext buffer
capacityBuffer capacity of given ciphertext
ciphertext_lenActual length of ciphertext
errorNULL or error
codeError code

enigma_decrypt

Decrypt data.

C
enigma_result enigma_decrypt(
    enigma_device * device,
    uint32_t key_id,
    const uint8_t * ciphertext,
    size_t ciphertext_len,
    uint8_t * plaintext,
    size_t capacity,
    size_t * plaintext_len,
    enigma_error * error
);

Decrypt data that was encrypted on-device. The firmware will reject a key that does not have appropriate key usage.

ParameterDescription
deviceDevice handle
key_idEncryption key ID
ciphertextCiphertext buffer
ciphertext_lenLength of ciphertext
plaintextPlaintext to be decrypted
capacityBuffer capacity of given plaintext
plaintext_lenActual length of plaintext
errorNULL or error
codeError code

enigma_sign

Sign a message.

C
enigma_result enigma_sign(
    enigma_device * device,
    uint32_t key_id,
    const uint8_t * message,
    size_t message_len,
    uint8_t * signature,
    size_t capacity,
    size_t * signature_len,
    enigma_error * error
);

Sign an arbitrary message with a SIGNING key. The firmware will reject a key that does not have appropriate key usage. The signature buffer is caller provided and must have enough capacity for the resulting signature, or the function will fail.

ParameterDescription
deviceDevice handle
key_idSigning key ID
messageMessage to be signed
message_lenMessage buffer capacity
signatureResulting signature buffer (caller provided)
capacitySignature buffer capacity
signature_lenSignature buffer length
errorNULL or error
codeError code

enigma_verify

Verify an HMAC message.

C
enigma_result enigma_verify(
    enigma_device * device,
    uint32_t key_id,
    const uint8_t * message,
    size_t message_len,
    const uint8_t * signature,
    size_t signature_len,
    bool * verified,
    enigma_error * error
);

Verify a message and its MAC.

ParameterDescription
deviceDevice handle
key_idSigning key ID
messageMessage to verify
message_lenLength of message
signatureMAC to verify
signature_lenMAC length
verifiedVerification status of message and MAC
errorNULL or error
codeError code

enigma_ecdh

Perform ECDH + HKDF to derive an AES key.

C
enigma_result enigma_ecdh(
    enigma_device * device,
    uint32_t private_key_id,
    enigma_public_key_encoding encoding,
    const uint8_t * public_key,
    size_t public_key_len,
    const char * label,
    const enigma_ecdh_result ** result,
    enigma_error * error
);

ECDH requires a private key, and a peer's public key. The private key in this operation resides on the secure element and is selected via the private_key_id. The peer public key bytes are provided in public_key. Internally, the secure element performs ECDH and HKDF with a random salt. The resulting key also resides on the secure element.

To compute the shared secret and resulting AES key, export the private key pair's public key material. Also use the resulting info string and salt in the HKDF operation.

ParameterDescription
deviceDevice handle
private_key_idPrivate key ID
encodingPublic key encoding
public_keyPublic key bytes
public_key_lenPublic key buffer length
labelResulting key's label
resultECDH result
errorNULL or error
codeError code

enigma_ecdh_free

Free ECDH result.

C
void enigma_ecdh_free(
    const enigma_ecdh_result * result
);
ParameterDescription
resultECDH result from enigma_ecdh

enigma_export_public_key

Get public key material.

C
enigma_result enigma_export_public_key(
    enigma_device * device,
    uint32_t key_id,
    uint8_t * public_key,
    size_t capacity,
    size_t * public_key_len,
    enigma_error * error
);

Keypairs are generated on the secure element but do not return the public key as part of that operation. The returned public_key is formatted to be SubjectPublicKeyInfo DER bytes.

Public key memory must be allocated by the caller, and the buffer size passed in via capacity. If not enough memory was allocated, the error code is ENIGMA_BUFFER_TOO_SMALL. When public_key = NULL and capacity = 0, the library will return the necessary bytes to allocate in public_key_len.

ParameterDescription
deviceDevice handle
key_idTarget key ID
public_keyPublic key SPKI DER bytes
capacityPublic key buffer size
public_key_lenPublic key byte count
errorNULL or error
codeError code

enigma_list_keys

List available crypto keys on the device.

C
enigma_result enigma_list_keys(
    enigma_device * device,
    const enigma_key_type * filter_type,
    const enigma_key_usage * filter_usage,
    const char * filter_label,
    const uint32_t * filter_key_id,
    enigma_key_list ** key_list,
    enigma_error * error
);

Get a list of key metadata structures that represent available crypto keys on the secure element. The key_list output is owned by the library and may be freed via enigma_key_list_free.

The device will filter on key type, usage, label, and ID. If the ID is provided, all other filters will be ignored, and the lookup will occur by ID only. This fact is enforced on the device firmware itself. Other filters are combined with AND logic. For example, providing type = EC and usage = SIGN will only give back keys that are both EC keys and have signing usage.

ParameterDescription
deviceDevice handle
filter_typeKey type filter
filter_usageKey usage filter
filter_labelKey label filter
filter_key_idKey ID filter
key_listList of key metadatas
errorNULL or error
codeError code

enigma_key_list_free

Free library allocated key list.

C
void enigma_key_list_free(
    const enigma_key_list * list
);

A key list returned by enigma_list_keys is owned by the library and must be freed with this function.

ParameterDescription
listKey list

enigma_destroy_key

Destroy a key on device.

C
enigma_result enigma_destroy_key(
    enigma_device * device,
    uint32_t key_id,
    enigma_error * error
);

Given a key ID, destroy that key on the secure element. This action cannot be undone.

ParameterDescription
deviceDevice handle
key_idKey ID to destroy
errorNULL or error
codeError code

enigma_close

Close device.

C
enigma_result enigma_close(
    enigma_device * device,
    enigma_error * error
);

Close the USB connection and release the handle back to the kernel. The device handle may be null in this case, where nothing will actually happen, but no errors will result.

ParameterDescription
deviceDevice handle
errorNULL or error if device could not be cleanly closed
codeError code

Types & ownership

Use the matching free function for library-allocated results. The key metadata, salt, and strings inside a result share its lifetime.

enigma_device

C
typedef struct enigma_device enigma_device;

enigma_result

C
typedef int32_t enigma_result;

enigma_error

C
typedef struct {
  int32_t code;         
  uint32_t device_code; 
  char message[256];    
} enigma_error;

enigma_status_info

C
typedef struct {
  uint32_t token_state;   
  uint32_t session_state; 
} enigma_status_info;

enigma_key_type

C
typedef uint32_t enigma_key_type;

enigma_key_usage

C
typedef uint32_t enigma_key_usage;

enigma_public_key_encoding

C
typedef uint32_t enigma_public_key_encoding;

enigma_key_meta

C
typedef struct {
  uint32_t id;
  enigma_key_type type;
  enigma_key_usage usage;
  uint16_t size;
  const char *label;
  uint32_t created_at;
} enigma_key_meta;

enigma_key_list

C
typedef struct {
  uint32_t count;
  const enigma_key_meta *keys;
} enigma_key_list;

enigma_ecdh_result

C
typedef struct {
  uint32_t key_id;
  const uint8_t *salt;
  size_t salt_len;
  const char *info;
} enigma_ecdh_result;

Constants

NameValue
ENIGMA_OK0x00
ENIGMA_INVALID_ARG0x01
ENIGMA_DEVICE_NOT_FOUND0x02
ENIGMA_MULTIPLE_DEVICES0x03
ENIGMA_INCOMPATIBLE_DEVICE0x04
ENIGMA_USB_ERROR0x05
ENIGMA_PROTOCOL_ERROR0x06
ENIGMA_DEVICE_ERROR0x07
ENIGMA_INTERNAL_ERROR0x08
ENIGMA_MALFORMED_OUTPUT0x09
ENIGMA_BUFFER_TOO_SMALL0x0A
enigma_key_type_aes0x01
enigma_key_type_rsa0x02
enigma_key_type_ec0x03
enigma_key_type_hmac0x04
enigma_key_usage_encrypt0x01
enigma_key_usage_sign0x02
enigma_key_usage_derive0x03
enigma_public_key_encoding_der_spki0x01