Caliptra Utility Host Library Design
Overview
The Caliptra Utility host library is a modular, extensible and transport-agnostic C library designed to enable the development of utility tools that can run on both BMC and host systems. These utilities facilitate both in-band and out-of-band communication with the Caliptra subsystem on the device, supporting a variety of transport interfaces such as MCU mailbox and MCTP VDM etc. The library provides a unified API for all supported Caliptra commands, making it easy to build robust management, provisioning, and diagnostic tools for diverse deployment environments.
Design Goals
- Modularity: Clear separation between transport layer, command processing, and application logic
 - Extensibility: Easy addition of new commands and transport mechanisms
 - Transport Agnostic: Support multiple communication channels without changing application code
 - Type Safety: Strong typing for command structures and responses
 - Thread Safety: Safe for use in multi-threaded environments
 
Use Cases
- Device Identification and Capabilities
- Retrieve firmware versions, unique device identifiers, and device capabilities to ensure compatibility and proper configuration.
 - Query device-specific information such as chip identifiers or subsystem details.
 
 - Debugging and Diagnostics
- Retrieve debug logs to analyze device behavior, diagnose issues, and monitor runtime states.
 - Clear logs to reset diagnostic data and maintain storage efficiency.
 
 - Certificate Management
- Export Certificate Signing Requests (CSRs) for device keys to facilitate secure provisioning.
 - Import signed certificates to establish a trusted certificate chain for device authentication.
 
 - Debug Unlock Mechanisms
- Facilitate secure debugging in production environments
 - Ensure controlled access to debugging features
 
 - Cryptographic Services
- AES encryption and decryption
 - SHA hashing
 - Random number generation
 - Digital signing
 - Signature verification
 - Key exchange
 
 
Architecture
Layered framework
flowchart TD
    classDef wideBox font-size:12px, padding:10px;
    A["Utility Application"]:::wideBox
    subgraph Library["Caliptra Utility Host Library"]
        B["Command Layer<br>(High-level APIs, transport-agnostic)"]:::wideBox
        C["Core Layer<br>(Command builder, Response parser, <br/>protocol mapping, session mgmt)"]:::wideBox
        D["Transport Abstraction Layer<br>(Unified interface for all transports)"]:::wideBox
        E["Transport Implementation Layer<br>(SoC Mailbox, MCTP VDM, <br/>Custom transports etc.)"]:::wideBox
    end
    A --> B
    B --> C
    C --> D
    D --> E
Component Descriptions
Command Layer
- Purpose: Provides high-level, transport-agnostic APIs for Caliptra commands
 - Functionality:
- Exposes simple function calls for each Caliptra command (e.g., 
caliptra_get_device_id()) - Manages stateful operations like multi-part SHA/AES computations
 - Maintains command contexts across multiple related operations
 - Handles command-specific validation and parameter checking
 - Abstracts complex command sequences into simple APIs
 
 - Exposes simple function calls for each Caliptra command (e.g., 
 - Data Flow: Receives API calls → Validates parameters → Passes to Core Layer for execution
 
Core Layer
- Purpose: Handles the mechanics of command execution and protocol management
 - Functionality:
- Builds properly formatted command packets with headers and checksums
 - Parses and validates responses from the device
 - Implements retry logic for transient failures
 - Manages command sequencing and state machines
 - Handles protocol-level error recovery
 
 - Data Flow: Receives command requests → Formats packets → Uses Transport Layer → Parses responses
 
Transport Abstraction Layer
- Purpose: Provides a unified interface to different physical transport mechanisms
 - Functionality:
- Defines standard operations (open, close, send, receive)
 - Manages connection lifecycle and readiness checks
 - Handles transport-level timeouts and flow control
 - Provides both synchronous and asynchronous operation modes
 - Maps transport-specific errors to common error codes
 
 - Data Flow: Receives formatted packets → Routes to appropriate transport → Returns raw responses
 
Transport Implementation Layer
- Purpose: Implements actual communication with hardware interfaces
 - Functionality:
- SoC Mailbox: Direct memory-mapped I/O operations to mailbox registers
 - MCTP VDM: Socket-based communication over MCTP protocol
 - Future transports:
 - Handles hardware-specific initialization and configuration
 - Manages low-level data transfer and synchronization
 
 - Data Flow: Receives bytes to send → Writes to hardware → Reads response bytes
 
Interface Design
Transport Implementation Layer
Each transport implementation shall provide these functions:
// Transport implementation context (opaque, transport-specific)
typedef void* caliptra_transport_impl_context_t;
// Error code type for all Caliptra APIs
typedef enum {
    CALIPTRA_SUCCESS = 0,
    CALIPTRA_ERROR_UNKNOWN = 1,
    CALIPTRA_ERROR_INVALID_ARGUMENT = 2,
    CALIPTRA_ERROR_TIMEOUT = 3,
    CALIPTRA_ERROR_NOT_SUPPORTED = 4,
    CALIPTRA_ERROR_TRANSPORT = 5,
    CALIPTRA_ERROR_PROTOCOL = 6,
    CALIPTRA_ERROR_DEVICE = 7,
    CALIPTRA_ERROR_MEMORY = 8,
    CALIPTRA_ERROR_BUSY = 9,
    CALIPTRA_ERROR_STATE = 10,
    CALIPTRA_ERROR_IO = 11,
    // ... add more as needed
} caliptra_error_t;
// Transport implementation operations
typedef struct {
    // Initialize the transport implementation context with parameters
    caliptra_error_t (*init)(caliptra_transport_impl_context_t* context, const char* params);
    // Clean up and release resources for the transport context
    caliptra_error_t (*cleanup)(caliptra_transport_impl_context_t context);
    // Send data over the transport
    caliptra_error_t (*send)(caliptra_transport_impl_context_t context, const uint8_t* data, size_t len);
    // Receive data from the transport with timeout
    caliptra_error_t (*receive)(caliptra_transport_impl_context_t context, uint8_t* buffer, size_t* buffer_len, uint32_t timeout_ms);
    // Flush any pending data or buffers in the transport
    caliptra_error_t (*flush)(caliptra_transport_impl_context_t context);
    // Check if the transport is ready for communication
    bool (*is_ready)(caliptra_transport_impl_context_t context);
    // Get the maximum payload size supported by the transport
    size_t (*get_max_payload_size)(caliptra_transport_impl_context_t context);
} caliptra_transport_impl_ops_t;
// Transport implementation descriptor
typedef struct {
    const char* name;
    const char* description;
    size_t context_size;
    const caliptra_transport_impl_ops_t* ops;
} caliptra_transport_impl_t;
Transport Abstraction Layer
// Opaque transport handle
typedef struct caliptra_transport caliptra_transport_t;
// Transport operations interface
typedef struct {
    // Send data over the transport
    caliptra_error_t (*send)(caliptra_transport_t* transport, const uint8_t* data, size_t len);
    // Receive data from the transport
    caliptra_error_t (*receive)(caliptra_transport_t* transport, uint8_t* buffer, size_t* buffer_len, uint32_t timeout_ms);
    // Check if the transport is ready for communication
    bool (*is_ready)(caliptra_transport_t* transport);
    // Flush any pending data or buffers
    caliptra_error_t (*flush)(caliptra_transport_t* transport);
    // Get the maximum payload size supported by the transport
    size_t (*get_max_payload_size)(caliptra_transport_t* transport);
} caliptra_transport_ops_t;
// Transport descriptor
typedef struct {
    const char* name;
    const char* description;
    const caliptra_transport_ops_t* ops;
    void* impl_context;
} caliptra_transport_desc_t;
// Register a transport implementation
caliptra_error_t caliptra_transport_register(const caliptra_transport_impl_t* impl);
// Unregister a transport implementation
caliptra_error_t caliptra_transport_unregister(const char* transport_name);
// List registered transports
caliptra_error_t caliptra_transport_list(const char** names, size_t* count);
// Create transport instance
caliptra_error_t caliptra_transport_create(const char* transport_name, const char* params, caliptra_transport_t** transport);
// Destroy transport instance
caliptra_error_t caliptra_transport_destroy(caliptra_transport_t* transport);
// Get transport descriptor (including ops)
const caliptra_transport_desc_t* caliptra_transport_get_descriptor(caliptra_transport_t* transport);
Core Layer
// Session handle (opaque)
typedef struct caliptra_session caliptra_session_t;
// Protocol types supported by the core layer
typedef enum {
    CALIPTRA_PROTOCOL_MAILBOX,
    CALIPTRA_PROTOCOL_MCTP_VDM,
    CALIPTRA_PROTOCOL_CUSTOM
} caliptra_protocol_type_t;
// Session configuration options
typedef enum {
    CALIPTRA_SESSION_OPT_TIMEOUT_MS,
    CALIPTRA_SESSION_OPT_MAX_RETRIES,
    CALIPTRA_SESSION_OPT_VALIDATE_CHECKSUM,
    CALIPTRA_SESSION_OPT_LOG_COMMANDS,
} caliptra_session_option_t;
// Create session with protocol type
caliptra_error_t caliptra_session_create_with_protocol(caliptra_transport_t* transport, caliptra_protocol_type_t protocol_type, caliptra_session_t** session);
// Destroy session
caliptra_error_t caliptra_session_destroy(caliptra_session_t* session);
// Configure session options
caliptra_error_t caliptra_session_set_option(caliptra_session_t* session, caliptra_session_option_t option, const void* value);
// Get session options
caliptra_error_t caliptra_session_get_option(caliptra_session_t* session, caliptra_session_option_t option, void* value);
// Generic command IDs (protocol-agnostic)
typedef enum {
    // Caliptra FIPS self test command
    CALIPTRA_CMD_FIPS_SELF_TEST = 0x0000,
    // Device Information Commands (0x0001 - 0x00FF)
    CALIPTRA_CMD_GET_FIRMWARE_VERSION    = 0x0001,
    CALIPTRA_CMD_GET_DEVICE_CAPABILITIES = 0x0002,
    CALIPTRA_CMD_GET_DEVICE_ID          = 0x0003,
    CALIPTRA_CMD_GET_DEVICE_INFO        = 0x0004,
    // Certificate Management Commands (0x0100 - 0x01FF)
    CALIPTRA_CMD_EXPORT_CSR             = 0x0101,
    CALIPTRA_CMD_IMPORT_CERTIFICATE     = 0x0102,
    // SHA Commands (0x0200 - 0x020F)
    CALIPTRA_CMD_SHA_INIT               = 0x0201,
    CALIPTRA_CMD_SHA_UPDATE             = 0x0202,
    CALIPTRA_CMD_SHA_FINAL              = 0x0203,
    // AES Basic Commands (0x0210 - 0x021F)
    CALIPTRA_CMD_AES_ENCRYPT_INIT       = 0x0211,
    CALIPTRA_CMD_AES_ENCRYPT_UPDATE     = 0x0212,
    CALIPTRA_CMD_AES_DECRYPT_INIT       = 0x0213,
    CALIPTRA_CMD_AES_DECRYPT_UPDATE     = 0x0214,
    // AES GCM Commands (0x0220 - 0x022F)
    CALIPTRA_CMD_AES_GCM_ENCRYPT_INIT   = 0x0221,
    CALIPTRA_CMD_AES_GCM_ENCRYPT_UPDATE = 0x0222,
    CALIPTRA_CMD_AES_GCM_ENCRYPT_FINAL  = 0x0223,
    CALIPTRA_CMD_AES_GCM_DECRYPT_INIT   = 0x0224,
    CALIPTRA_CMD_AES_GCM_DECRYPT_UPDATE = 0x0225,
    CALIPTRA_CMD_AES_GCM_DECRYPT_FINAL  = 0x0226,
    // Random Number Commands (0x0230 - 0x023F)
    CALIPTRA_CMD_RANDOM_STIR            = 0x0231,
    CALIPTRA_CMD_RANDOM_GENERATE        = 0x0232,
    // Key Exchange Commands (0x0240 - 0x024F)
    CALIPTRA_CMD_ECDH_GENERATE          = 0x0241,
    CALIPTRA_CMD_ECDH_FINISH            = 0x0242,
    // Signature Commands (0x0250 - 0x025F)
    CALIPTRA_CMD_ECDSA384_SIG_VERIFY    = 0x0251,
    CALIPTRA_CMD_LMS_SIG_VERIFY         = 0x0252,
    CALIPTRA_CMD_ECDSA_SIGN             = 0x0253,
    CALIPTRA_CMD_MLDSA_SIGN             = 0x0254,
    // Key Management Commands (0x0260 - 0x026F)
    CALIPTRA_CMD_IMPORT                 = 0x0261,
    CALIPTRA_CMD_DELETE                 = 0x0262,
    // Debug Commands (0x0300 - 0x03FF)
    CALIPTRA_CMD_GET_LOG                = 0x0301,
    CALIPTRA_CMD_CLEAR_LOG              = 0x0302,
    CALIPTRA_CMD_PRODUCTION_DEBUG_UNLOCK_REQ   = 0x0303,
    CALIPTRA_CMD_PRODUCTION_DEBUG_UNLOCK_TOKEN = 0x0304,
    // Fuse Commands (0x0400 - 0x04FF)
    CALIPTRA_CMD_FUSE_READ              = 0x0401,
    CALIPTRA_CMD_FUSE_WRITE             = 0x0402,
    CALIPTRA_CMD_FUSE_LOCK_PARTITION    = 0x0403,
    // Custom command range
    CALIPTRA_CMD_CUSTOM_BASE            = 0x8000
} caliptra_command_id_t;
// Core command execution (used by Command Layer)
caliptra_error_t caliptra_core_execute_command(
    caliptra_session_t* session,
    caliptra_command_id_t command_id,  // Generic command ID
    const void* request,
    size_t request_size,
    void* response,
    size_t* response_size
);
// Protocol handler interface for custom protocol support.
typedef struct {
    // Format generic command into protocol-specific packet.
    caliptra_error_t (*format_packet)(caliptra_command_id_t command_id, const void* request, size_t request_size, uint8_t* packet, size_t* packet_size);
    // Parse protocol-specific packet into generic response.
    caliptra_error_t (*parse_packet)(const uint8_t* packet, size_t packet_size, uint32_t* fips_status, void* response, size_t* response_size);
    // Get protocol-specific command code.
    uint32_t (*get_command_code)(caliptra_command_id_t command_id);
    // Validate packet integrity.
    caliptra_error_t (*validate_packet)(const uint8_t* packet, size_t packet_size);
} caliptra_protocol_handler_t;
// Register custom protocol handler.
caliptra_error_t caliptra_register_protocol_handler(caliptra_protocol_type_t protocol_type, const caliptra_protocol_handler_t* handler);
// Session statistics structure.
typedef struct {
    uint64_t commands_sent;
    uint64_t commands_successful;
    uint64_t commands_failed;
    uint64_t retries;
    uint64_t checksum_errors;
    uint64_t transport_errors;
    uint64_t protocol_errors;
} caliptra_session_stats_t;
// Get session statistics.
caliptra_error_t caliptra_session_get_stats(caliptra_session_t* session, caliptra_session_stats_t* stats);
// Reset session statistics.
caliptra_error_t caliptra_session_reset_stats(caliptra_session_t* session);
// Error context with extended information.
typedef struct {
    caliptra_error_t error_code;
    caliptra_command_id_t command_id;      // Generic command that failed
    uint32_t protocol_command_code;        // Protocol-specific code
    const char* error_message;
    uint32_t device_error;
    uint32_t transport_error;
    struct {
        const char* file;
        int line;
        const char* function;
    } location;
} caliptra_error_context_t;
// Get last error context for the session.
caliptra_error_t caliptra_session_get_last_error(caliptra_session_t* session, caliptra_error_context_t* error_context);
// Session state enumeration.
typedef enum {
    CALIPTRA_SESSION_STATE_IDLE,
    CALIPTRA_SESSION_STATE_BUSY,
    CALIPTRA_SESSION_STATE_ERROR,
    CALIPTRA_SESSION_STATE_RECOVERING
} caliptra_session_state_t;
// Get current session state.
caliptra_session_state_t caliptra_session_get_state(caliptra_session_t* session);
// Reset session to clear error state.
caliptra_error_t caliptra_session_reset(caliptra_session_t* session);
// Get session protocol type.
caliptra_protocol_type_t caliptra_session_get_protocol_type(caliptra_session_t* session);
// Get transport associated with session.
caliptra_transport_t* caliptra_session_get_transport(caliptra_session_t* session);
Command Layer
Device Information Commands
// Get firmware version
caliptra_error_t caliptra_cmd_get_firmware_version(caliptra_session_t* session, caliptra_fw_index_t index, caliptra_fw_version_t* version);
// Get device capabilities
caliptra_error_t caliptra_cmd_get_device_capabilities(caliptra_session_t* session, caliptra_capabilities_t* caps);
// Get device ID
caliptra_error_t caliptra_cmd_get_device_id(caliptra_session_t* session, caliptra_device_id_t* device_id);
// Get device info
caliptra_error_t caliptra_cmd_get_device_info(caliptra_session_t* session, uint32_t info_index, uint8_t* buffer, size_t* buffer_size);
Certificate Management Commands
// Export CSR
caliptra_error_t caliptra_cmd_export_csr(caliptra_session_t* session, caliptra_csr_type_t csr_type, uint8_t* csr_buffer, size_t* csr_size);
// Import certificate
caliptra_error_t caliptra_cmd_import_certificate(caliptra_session_t* session, caliptra_csr_type_t cert_type, const uint8_t* cert_data, size_t cert_size);
Cryptographic Commands
// Initialize SHA context
caliptra_error_t caliptra_cmd_sha_init(caliptra_session_t* session, caliptra_sha_type_t sha_type, caliptra_sha_ctx_t** ctx);
// Update SHA context with data
caliptra_error_t caliptra_cmd_sha_update(caliptra_sha_ctx_t* ctx, const uint8_t* data, size_t data_len);
// Finalize SHA and get hash
caliptra_error_t caliptra_cmd_sha_final(caliptra_sha_ctx_t* ctx, uint8_t* hash, size_t* hash_len);
// Destroy SHA context
caliptra_error_t caliptra_cmd_sha_destroy(caliptra_sha_ctx_t* ctx);
// Initialize AES context
caliptra_error_t caliptra_cmd_aes_init(caliptra_session_t* session, caliptra_aes_mode_t mode, bool encrypt, const uint8_t* key, size_t key_len, const uint8_t* iv, size_t iv_len, caliptra_aes_ctx_t** ctx);
// Update AES context with input data
caliptra_error_t caliptra_cmd_aes_update(caliptra_aes_ctx_t* ctx, const uint8_t* input, size_t input_len, uint8_t* output, size_t* output_len);
// Finalize AES and get output/tag
caliptra_error_t caliptra_cmd_aes_final(caliptra_aes_ctx_t* ctx, uint8_t* output, size_t* output_len, uint8_t* tag, size_t tag_len);
// Destroy AES context
caliptra_error_t caliptra_cmd_aes_destroy(caliptra_aes_ctx_t* ctx);
// Get random bytes
caliptra_error_t caliptra_cmd_get_random(caliptra_session_t* session, uint8_t* buffer, size_t len);
// Verify ECDSA signature
caliptra_error_t caliptra_cmd_ecdsa_verify(caliptra_session_t* session, const caliptra_ecdsa_pubkey_t* pubkey, const uint8_t* hash, size_t hash_len, const caliptra_ecdsa_signature_t* signature);
// Sign hash with ECDSA
caliptra_error_t caliptra_cmd_ecdsa_sign(caliptra_session_t* session, const uint8_t* hash, size_t hash_len, caliptra_ecdsa_signature_t* signature, caliptra_ecdsa_pubkey_t* pubkey);
Telemetry Commands (WIP)
// Get log data
caliptra_error_t caliptra_cmd_get_log(caliptra_session_t* session, caliptra_log_type_t log_type, uint8_t* buffer, size_t* buffer_size);
// Clear log data
caliptra_error_t caliptra_cmd_clear_log(caliptra_session_t* session, caliptra_log_type_t log_type);
Extensibility with Plugin Architecture
The Caliptra Utility host library is designed to be highly extensible, supporting the dynamic addition of new commands, protocols, and transport mechanisms at runtime through a plugin architecture. This approach enables third-party developers and system integrators to extend the library’s capabilities without modifying or recompiling the core library.
flowchart TD
    subgraph App["Utility Application"]
        A1[Main App/CLI]
        A2["Plugin (Shared Library)"]
    end
    subgraph Library["Caliptra Utility Host Library"]
        B1[Command Layer]
        B2[Core Layer]
        B3[Transport Abstraction Layer]
        B4[Transport Impl Layer]
        B5[Plugin Loader & Registry]
    end
    A1 -->|Loads at runtime| A2
    A2 -- Registers new commands/transports/protocols --> B5
    A1 -->|Uses APIs| B1
    B1 --> B2
    B2 --> B3
    B3 --> B4
    B5 -- Makes available to --> B1
- Plugins are shared libraries (e.g., 
.soor.dllfiles) that implement new commands, protocol handlers, or transport mechanisms. - The core library provides APIs to dynamically load, register, and discover these plugins at runtime.
 - This design preserves the existing layered architecture, while enabling runtime extensibility and modularity.
 
How Plugins Work
- 
Plugin Interface Each plugin implements a standard interface and exports a descriptor structure. For example:
typedef struct { const char* name; const char* version; caliptra_error_t (*register_plugin)(void); } caliptra_plugin_descriptor_t;The plugin’s
register_pluginfunction is called by the core library to register new commands, transports, or protocol handlers. - 
Dynamic Loading The core library provides APIs such as:
caliptra_error_t caliptra_plugin_load(const char* path); caliptra_error_t caliptra_plugin_unload(const char* name);These use platform mechanisms (
dlopen/dlsymon Linux,LoadLibraryon Windows) to load plugins at runtime. - 
Dynamic Registration
 
Plugins use registration and unregistration APIs to add or remove features:
// Register new features
caliptra_error_t caliptra_command_register(const caliptra_command_desc_t* desc);
caliptra_error_t caliptra_transport_register(const caliptra_transport_impl_t* impl);
caliptra_error_t caliptra_register_protocol_handler(
    caliptra_protocol_type_t protocol_type,
    const caliptra_protocol_handler_t* handler
);
// Unregister features when plugin is unloaded
caliptra_error_t caliptra_command_unregister(const char* command_name);
caliptra_error_t caliptra_transport_unregister(const char* transport_name);
caliptra_error_t caliptra_unregister_protocol_handler(
    caliptra_protocol_type_t protocol_type
);
The library maintains internal registries of available commands, transports, and protocol handlers. When a plugin is unloaded, it should call the appropriate unregister functions to cleanly remove its features and release resources.
- Discovery and Usage
Applications can enumerate available commands and transports at runtime:
This enables dynamic feature discovery and flexible application logic.size_t caliptra_command_list(const caliptra_command_desc_t** out_array); size_t caliptra_transport_list(const caliptra_transport_impl_t** out_array);