enigmastick
Documentation menu
On this page

Documentation / Integration

Using C.

The Rust host library, behind an opaque device handle and a C interface.

Build and link

Build the host library with cargo build --release in enigma-host. Its include/enigma.h header declares the C API; Cargo produces a shared library alongside the Rust library.

For example, on a Linux development system with a sibling host-library checkout:

Terminal
cc example.c -I ../enigma-host/include \
  -L ../enigma-host/target/release -lenigma \
  -Wl,-rpath,"$PWD/../enigma-host/target/release" \
  -o example

Library filenames and runtime search paths depend on the platform. The command above is a Linux example, not a claim of validation on every platform.

Open, inspect, close

This example reads device status without embedding a PIN or changing persistent key state.

C
#include <enigma.h>
#include <stdio.h>

int main(void) {
    enigma_device *device = NULL;
    enigma_error error = {0};
    enigma_status_info status = {0};

    enigma_result result = enigma_open(&device, &error);
    if (result != ENIGMA_OK) {
        fprintf(stderr, "Open failed: %s\n", error.message);
        return 1;
    }

    result = enigma_status(device, &status, &error);
    int failed = result != ENIGMA_OK;
    if (failed) {
        fprintf(stderr, "Status failed: %s\n", error.message);
    } else {
        printf("Token: %u, session: %u\n",
               (unsigned)status.token_state,
               (unsigned)status.session_state);
    }

    result = enigma_close(device, &error);
    if (result != ENIGMA_OK) {
        fprintf(stderr, "Close failed: %s\n", error.message);
        return 1;
    }
    return failed;
}

The device handle is owned by the library. Close it exactly once; do not access it after enigma_close. USB close and token lock are separate operations.

Check result codes

Operations return ENIGMA_OK on success. On failure, enigma_error supplies the library category, device error code where applicable, and a fixed-size NUL-terminated message.

Use result codes for control flow. Do not depend on the wording of error messages, and do not inspect output values after a failed call unless that function documents a size-query contract.

Caller-provided buffers

Encryption, decryption, signing, and public-key export use output buffers supplied by the caller. Pass the actual allocated capacity. ENIGMA_BUFFER_TOO_SMALL indicates insufficient space.

For public-key export, public_key = NULL and capacity = 0 query the required length via public_key_len. Allocate that many bytes and call again. Do not assume every buffer-producing operation is a free sizing query: encryption or signing can perform a device operation before reporting buffer size.

Library-owned results

ResultRelease with
enigma_device *enigma_close
enigma_key_list *enigma_key_list_free
const enigma_ecdh_result *enigma_ecdh_free

Nested labels, key entries, salts, and info strings belong to their enclosing result. Copy them before freeing that result if they must live longer. Do not pass these allocations to your own free().

Serialize calls on a device handle. The protocol has no request IDs, and a handle must not be concurrently accessed or freed.

Full reference

The C API reference includes signatures and parameter documentation for every exported function, plus public types and constants.