/** * @file se050_wireguard.h * @brief SE050 WireGuard Minimum Interface * * Clean-room interface for WireGuard cryptographic operations using SE050. * * This header defines the API for: * - X25519 ECDH key exchange * - True Random Number Generation (TRNG) * - Platform SCP03 secure channel * * License: MIT (Clean-room implementation) */ #ifndef SE050_WIREGUARD_H #define SE050_WIREGUARD_H #include #include #ifdef __cplusplus extern "C" { #endif /* ============================================================================ * Error Codes * ============================================================================ */ typedef enum { SE050_OK = 0x00, SE050_ERR_FAIL = 0x01, SE050_ERR_INVALID_ARG = 0x02, SE050_ERR_SESSION = 0x03, SE050_ERR_KEY_STORE = 0x04, SE050_ERR_RNG = 0x05, SE050_ERR_ECDH = 0x06, SE050_ERR_SCP03 = 0x07, SE050_ERR_I2C = 0x08, SE050_ERR_NOT_INIT = 0x09, } se050_status_t; /* ============================================================================ * Constants * ============================================================================ */ /** WireGuard key size (X25519 uses 32-byte keys) */ #define SE050_WG_KEY_SIZE 32 /** WireGuard public key size */ #define SE050_WG_PUBKEY_SIZE 32 /** SCP03 key size */ #define SE050_SCP03_KEY_SIZE 16 /** SCP03 IV size */ #define SE050_SCP03_IV_SIZE 16 /** SCP03 CMAC size */ #define SE050_SCP03_CMAC_SIZE 8 /** Maximum buffer size for SCP03 */ #define SE050_SCP03_MAX_BUF 1024 /* ============================================================================ * Type Definitions * ============================================================================ */ /** Session context for SE050 communication */ typedef struct se050_session_ctx se050_session_ctx_t; /** Key store context */ typedef struct se050_keystore_ctx se050_keystore_ctx_t; /** RNG context */ typedef struct se050_rng_ctx se050_rng_ctx_t; /** SCP03 session context */ typedef struct se050_scp03_ctx se050_scp03_ctx_t; /** X25519 key pair */ typedef struct { uint8_t private_key[SE050_WG_KEY_SIZE]; /**< Private key (32 bytes) */ uint8_t public_key[SE050_WG_PUBKEY_SIZE]; /**< Public key (32 bytes) */ } se050_x25519_keypair_t; /** I2C HAL interface */ typedef struct { void *handle; /**< I2C device handle */ uint8_t slave_addr; /**< I2C slave address (default: 0x90) */ const char *dev_path; /**< Device path (e.g., "/dev/i2c-1") */ } se050_i2c_hal_t; /* ============================================================================ * I2C HAL Layer * ============================================================================ */ /** * @brief Initialize I2C HAL * @param hal I2C HAL structure * @param dev_path Device path (e.g., "/dev/i2c-1") * @param slave_addr I2C slave address (default: 0x90) * @return SE050_OK on success */ se050_status_t se050_i2c_init(se050_i2c_hal_t *hal, const char *dev_path, uint8_t slave_addr); /** * @brief Close I2C HAL * @param hal I2C HAL structure */ void se050_i2c_close(se050_i2c_hal_t *hal); /** * @brief Read from SE050 via I2C * @param hal I2C HAL structure * @param buffer Read buffer * @param length Number of bytes to read * @return Number of bytes read, or negative on error */ int se050_i2c_read(se050_i2c_hal_t *hal, uint8_t *buffer, int length); /** * @brief Write to SE050 via I2C * @param hal I2C HAL structure * @param buffer Write buffer * @param length Number of bytes to write * @return Number of bytes written, or negative on error */ int se050_i2c_write(se050_i2c_hal_t *hal, const uint8_t *buffer, int length); /** * @brief Wake up SE050 (if needed) * @param hal I2C HAL structure * @return SE050_OK on success */ se050_status_t se050_i2c_wakeup(se050_i2c_hal_t *hal); /* ============================================================================ * Session Management * ============================================================================ */ /** * @brief Create SE050 session * @param ctx Output session context * @param hal I2C HAL interface * @return SE050_OK on success */ se050_status_t se050_session_create(se050_session_ctx_t **ctx, se050_i2c_hal_t *hal); /** * @brief Open SE050 session * @param ctx Session context * @return SE050_OK on success */ se050_status_t se050_session_open(se050_session_ctx_t *ctx); /** * @brief Close SE050 session * @param ctx Session context */ void se050_session_close(se050_session_ctx_t *ctx); /** * @brief Delete SE050 session * @param ctx Session context */ void se050_session_delete(se050_session_ctx_t *ctx); /* ============================================================================ * Session SCP03 Integration * ============================================================================ */ /** * @brief Initialize SCP03 secure channel for session * @param ctx Session context * @return SE050_OK on success */ se050_status_t se050_session_scp03_init(se050_session_ctx_t *ctx); /** * @brief Set SCP03 keys for PlatformSCP03 authentication * @param ctx Session context * @param enc_key Encryption key (16 bytes) * @param mac_key MAC key (16 bytes) * @param dek_key Data Encryption Key (16 bytes) * @return SE050_OK on success */ se050_status_t se050_session_scp03_set_keys(se050_session_ctx_t *ctx, const uint8_t *enc_key, const uint8_t *mac_key, const uint8_t *dek_key); /** * @brief Encrypt command using SCP03 * @param ctx Session context * @param cmd Command buffer * @param cmd_len Command length (updated after padding) * @return SE050_OK on success */ se050_status_t se050_session_scp03_encrypt(se050_session_ctx_t *ctx, uint8_t *cmd, size_t *cmd_len); /** * @brief Decrypt response using SCP03 * @param ctx Session context * @param cmd_len Original command length * @param rsp Response buffer * @param rsp_len Response length (updated after decryption) * @return Status word (0x9000 on success) */ uint16_t se050_session_scp03_decrypt(se050_session_ctx_t *ctx, size_t cmd_len, uint8_t *rsp, size_t *rsp_len); /* ============================================================================ * Key Store * ============================================================================ */ /** * @brief Initialize key store * @param ctx Output key store context * @param session SE050 session * @return SE050_OK on success */ se050_status_t se050_keystore_init(se050_keystore_ctx_t **ctx, se050_session_ctx_t *session); /** * @brief Free key store * @param ctx Key store context */ void se050_keystore_free(se050_keystore_ctx_t *ctx); /* ============================================================================ * Random Number Generation (TRNG) * ============================================================================ */ /** * @brief Initialize RNG context * @param ctx Output RNG context * @param session SE050 session * @return SE050_OK on success */ se050_status_t se050_rng_init(se050_rng_ctx_t **ctx, se050_session_ctx_t *session); /** * @brief Generate random bytes using SE050 TRNG * @param ctx RNG context * @param output Output buffer * @param length Number of bytes to generate * @return SE050_OK on success */ se050_status_t se050_rng_generate(se050_rng_ctx_t *ctx, uint8_t *output, size_t length); /** * @brief Free RNG context * @param ctx RNG context */ void se050_rng_free(se050_rng_ctx_t *ctx); /* ============================================================================ * X25519 ECDH * ============================================================================ */ /** * @brief Generate X25519 key pair * @param keystore Key store context * @param keypair Output key pair * @param key_id Unique key identifier * @return SE050_OK on success * * Note: Private key is generated using SE050 TRNG and stored securely. * The private key never leaves the SE050. */ se050_status_t se050_x25519_generate_keypair(se050_keystore_ctx_t *keystore, se050_x25519_keypair_t *keypair, uint32_t key_id); /** * @brief Compute X25519 ECDH shared secret * @param keystore Key store context * @param private_key_id Local private key ID * @param peer_public Peer's public key (32 bytes) * @param shared_secret Output shared secret (32 bytes) * @return SE050_OK on success * * Note: ECDH computation is performed inside SE050. */ se050_status_t se050_x25519_compute_shared_secret(se050_keystore_ctx_t *keystore, uint32_t private_key_id, const uint8_t *peer_public, uint8_t *shared_secret); /** * @brief Export X25519 public key from SE050 * @param keystore Key store context * @param key_id Key identifier * @param public_key Output public key (32 bytes) * @return SE050_OK on success */ se050_status_t se050_x25519_export_public_key(se050_keystore_ctx_t *keystore, uint32_t key_id, uint8_t *public_key); /* ============================================================================ * Platform SCP03 Secure Channel * ============================================================================ */ /** * @brief Initialize SCP03 context * @param ctx Output SCP03 context * @param session SE050 session * @return SE050_OK on success */ se050_status_t se050_scp03_init(se050_scp03_ctx_t **ctx, se050_session_ctx_t *session); /** * @brief Set SCP03 keys (ENC, MAC, and DEK) * @param ctx SCP03 context * @param enc_key Encryption key (16 bytes) * @param mac_key MAC key (16 bytes) * @param dek_key Data Encryption Key (16 bytes) * @return SE050_OK on success */ se050_status_t se050_scp03_set_keys(se050_scp03_ctx_t *ctx, const uint8_t *enc_key, const uint8_t *mac_key, const uint8_t *dek_key); /** * @brief Load SCP03 keys from file * @param ctx SCP03 context * @param file_path Path to key file (ENC[16] + MAC[16] + DEK[16] = 48 bytes) * @return SE050_OK on success */ se050_status_t se050_scp03_load_keys_from_file(se050_scp03_ctx_t *ctx, const char *file_path); /** * @brief Encrypt command APDU * @param ctx SCP03 context * @param cmd Command buffer (in-place encryption) * @param cmd_len Command length (updated after padding) * @return SE050_OK on success */ se050_status_t se050_scp03_encrypt_command(se050_scp03_ctx_t *ctx, uint8_t *cmd, size_t *cmd_len); /** * @brief Decrypt response APDU * @param ctx SCP03 context * @param cmd_len Original command length (for ICV calculation) * @param rsp Response buffer (in-place decryption) * @param rsp_len Response length (updated after decryption) * @return SW status code (e.g., 0x9000 for success) */ uint16_t se050_scp03_decrypt_response(se050_scp03_ctx_t *ctx, size_t cmd_len, uint8_t *rsp, size_t *rsp_len); /** * @brief Free SCP03 context * @param ctx SCP03 context */ void se050_scp03_free(se050_scp03_ctx_t *ctx); /* ============================================================================ * High-Level WireGuard API * ============================================================================ */ /** * @brief Initialize WireGuard SE050 subsystem * @param hal I2C HAL interface * @param session Output session context * @param keystore Output key store context * @param rng Output RNG context * @return SE050_OK on success */ se050_status_t se050_wireguard_init(se050_i2c_hal_t *hal, se050_session_ctx_t **session, se050_keystore_ctx_t **keystore, se050_rng_ctx_t **rng); /** * @brief Generate WireGuard key pair * @param keystore Key store context * @param rng RNG context * @param keypair Output key pair * @param key_id Key identifier * @return SE050_OK on success */ se050_status_t se050_wireguard_generate_key(se050_keystore_ctx_t *keystore, se050_rng_ctx_t *rng, se050_x25519_keypair_t *keypair, uint32_t key_id); /** * @brief Compute WireGuard shared secret * @param keystore Key store context * @param key_id Local private key ID * @param peer_public Peer's public key * @param shared_secret Output shared secret * @return SE050_OK on success */ se050_status_t se050_wireguard_compute_shared(se050_keystore_ctx_t *keystore, uint32_t key_id, const uint8_t *peer_public, uint8_t *shared_secret); /** * @brief Cleanup WireGuard SE050 subsystem * @param session Session context * @param keystore Key store context * @param rng RNG context */ void se050_wireguard_cleanup(se050_session_ctx_t *session, se050_keystore_ctx_t *keystore, se050_rng_ctx_t *rng); #ifdef __cplusplus } #endif #endif /* SE050_WIREGUARD_H */