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_openenigma_statusenigma_authenticateenigma_lockenigma_generate_keyenigma_encryptenigma_decryptenigma_signenigma_verifyenigma_ecdhenigma_ecdh_freeenigma_export_public_keyenigma_list_keysenigma_key_list_freeenigma_destroy_keyenigma_closeenigma_open
Open a connection to the Enigma device.
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.
| Parameter | Description |
|---|---|
device | Device handle |
error | NULL or error if device could not be opened |
code | Error code |
enigma_status
Retrieve device status.
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.
| Parameter | Description |
|---|---|
device | Device handle |
status | Resulting status |
error | NULL or error if status could not be retrieved |
code | Error code |
enigma_authenticate
Authenticate the device token.
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.
| Parameter | Description |
|---|---|
device | Device handle |
pin | Device authentication PIN |
error | NULL or error if status could not be retrieved |
code | Error code |
enigma_lock
Lock the device token.
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.
| Parameter | Description |
|---|---|
device | Device handle |
error | NULL or error |
code | Error code |
enigma_generate_key
Generate a key on device.
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.
| Parameter | Description |
|---|---|
device | Device handle |
key_type | Key type |
key_usage | Key usage |
key_size | Key size in bits (or curve for EC) |
label | Key label |
key_id | Resulting key ID |
error | NULL or error |
code | Error code |
enigma_encrypt
Encrypt arbitrary data.
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.
| Parameter | Description |
|---|---|
device | Device handle |
key_id | Encryption key ID |
plaintext | Plaintext to be encrypted |
plaintext_len | Length of plaintext |
ciphertext | Ciphertext buffer |
capacity | Buffer capacity of given ciphertext |
ciphertext_len | Actual length of ciphertext |
error | NULL or error |
code | Error code |
enigma_decrypt
Decrypt data.
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.
| Parameter | Description |
|---|---|
device | Device handle |
key_id | Encryption key ID |
ciphertext | Ciphertext buffer |
ciphertext_len | Length of ciphertext |
plaintext | Plaintext to be decrypted |
capacity | Buffer capacity of given plaintext |
plaintext_len | Actual length of plaintext |
error | NULL or error |
code | Error code |
enigma_sign
Sign a message.
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.
| Parameter | Description |
|---|---|
device | Device handle |
key_id | Signing key ID |
message | Message to be signed |
message_len | Message buffer capacity |
signature | Resulting signature buffer (caller provided) |
capacity | Signature buffer capacity |
signature_len | Signature buffer length |
error | NULL or error |
code | Error code |
enigma_verify
Verify an HMAC message.
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.
| Parameter | Description |
|---|---|
device | Device handle |
key_id | Signing key ID |
message | Message to verify |
message_len | Length of message |
signature | MAC to verify |
signature_len | MAC length |
verified | Verification status of message and MAC |
error | NULL or error |
code | Error code |
enigma_ecdh
Perform ECDH + HKDF to derive an AES key.
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.
| Parameter | Description |
|---|---|
device | Device handle |
private_key_id | Private key ID |
encoding | Public key encoding |
public_key | Public key bytes |
public_key_len | Public key buffer length |
label | Resulting key's label |
result | ECDH result |
error | NULL or error |
code | Error code |
enigma_ecdh_free
Free ECDH result.
void enigma_ecdh_free(
const enigma_ecdh_result * result
);| Parameter | Description |
|---|---|
result | ECDH result from enigma_ecdh |
enigma_export_public_key
Get public key material.
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.
| Parameter | Description |
|---|---|
device | Device handle |
key_id | Target key ID |
public_key | Public key SPKI DER bytes |
capacity | Public key buffer size |
public_key_len | Public key byte count |
error | NULL or error |
code | Error code |
enigma_list_keys
List available crypto keys on the device.
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.
| Parameter | Description |
|---|---|
device | Device handle |
filter_type | Key type filter |
filter_usage | Key usage filter |
filter_label | Key label filter |
filter_key_id | Key ID filter |
key_list | List of key metadatas |
error | NULL or error |
code | Error code |
enigma_key_list_free
Free library allocated key list.
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.
| Parameter | Description |
|---|---|
list | Key list |
enigma_destroy_key
Destroy a key on device.
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.
| Parameter | Description |
|---|---|
device | Device handle |
key_id | Key ID to destroy |
error | NULL or error |
code | Error code |
enigma_close
Close device.
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.
| Parameter | Description |
|---|---|
device | Device handle |
error | NULL or error if device could not be cleanly closed |
code | Error 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
typedef struct enigma_device enigma_device;enigma_result
typedef int32_t enigma_result;enigma_error
typedef struct {
int32_t code;
uint32_t device_code;
char message[256];
} enigma_error;enigma_status_info
typedef struct {
uint32_t token_state;
uint32_t session_state;
} enigma_status_info;enigma_key_type
typedef uint32_t enigma_key_type;enigma_key_usage
typedef uint32_t enigma_key_usage;enigma_public_key_encoding
typedef uint32_t enigma_public_key_encoding;enigma_key_meta
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
typedef struct {
uint32_t count;
const enigma_key_meta *keys;
} enigma_key_list;enigma_ecdh_result
typedef struct {
uint32_t key_id;
const uint8_t *salt;
size_t salt_len;
const char *info;
} enigma_ecdh_result;Constants
| Name | Value |
|---|---|
ENIGMA_OK | 0x00 |
ENIGMA_INVALID_ARG | 0x01 |
ENIGMA_DEVICE_NOT_FOUND | 0x02 |
ENIGMA_MULTIPLE_DEVICES | 0x03 |
ENIGMA_INCOMPATIBLE_DEVICE | 0x04 |
ENIGMA_USB_ERROR | 0x05 |
ENIGMA_PROTOCOL_ERROR | 0x06 |
ENIGMA_DEVICE_ERROR | 0x07 |
ENIGMA_INTERNAL_ERROR | 0x08 |
ENIGMA_MALFORMED_OUTPUT | 0x09 |
ENIGMA_BUFFER_TOO_SMALL | 0x0A |
enigma_key_type_aes | 0x01 |
enigma_key_type_rsa | 0x02 |
enigma_key_type_ec | 0x03 |
enigma_key_type_hmac | 0x04 |
enigma_key_usage_encrypt | 0x01 |
enigma_key_usage_sign | 0x02 |
enigma_key_usage_derive | 0x03 |
enigma_public_key_encoding_der_spki | 0x01 |