diff --git a/include/se050_i2c_hal.h b/include/se050_i2c_hal.h new file mode 100644 index 0000000..efce291 --- /dev/null +++ b/include/se050_i2c_hal.h @@ -0,0 +1,41 @@ +/** + * @file se050_i2c_hal.h + * @brief SE050 I2C HAL Interface + */ + +#ifndef SE050_I2C_HAL_H +#define SE050_I2C_HAL_H + +#include + +/* Status codes */ +typedef enum { + SE050_OK = 0, + SE050_ERR_INVALID_ARG = -1, + SE050_ERR_I2C = -2, + SE050_ERR_TIMEOUT = -3, + SE050_ERR_INTERNAL = -4, + SE050_ERR_SESSION = -5, + SE050_ERR_FAIL = -6, + SE050_ERR_RNG = -7, + SE050_ERR_ECDH = -8, + SE050_ERR_NOT_INIT = -9, + SE050_ERR_SCP03 = -10 +} se050_status_t; + +/* I2C HAL structure */ +typedef struct { + void *handle; /**< I2C file descriptor */ + uint8_t slave_addr; /**< I2C slave address */ + const char *dev_path; /**< I2C device path */ + int wakeup_pin; /**< Wakeup GPIO pin (-1 if unused) */ +} se050_i2c_hal_t; + +/* Public API */ +se050_status_t se050_i2c_init(se050_i2c_hal_t *hal, const char *dev_path, uint8_t slave_addr); +void se050_i2c_close(se050_i2c_hal_t *hal); +int se050_i2c_read(se050_i2c_hal_t *hal, uint8_t *buffer, int length); +int se050_i2c_write(se050_i2c_hal_t *hal, const uint8_t *buffer, int length); +se050_status_t se050_i2c_wakeup(se050_i2c_hal_t *hal); + +#endif /* SE050_I2C_HAL_H */ diff --git a/include/se050_keystore_internal.h b/include/se050_keystore_internal.h index c076746..d74bcd6 100644 --- a/include/se050_keystore_internal.h +++ b/include/se050_keystore_internal.h @@ -11,6 +11,7 @@ #define SE050_KEYSTORE_INTERNAL_H #include "se050_wireguard.h" +#include "se050_session_internal.h" #include #include @@ -51,6 +52,8 @@ typedef struct { /** * @brief Key store context structure */ +typedef struct se050_keystore_ctx se050_keystore_ctx_t; + struct se050_keystore_ctx { se050_session_ctx_t *session; /**< Associated session */ key_object_t *objects; /**< Key objects array */ diff --git a/include/se050_scp03.h b/include/se050_scp03.h new file mode 100644 index 0000000..13f6607 --- /dev/null +++ b/include/se050_scp03.h @@ -0,0 +1,42 @@ +/** + * @file se050_scp03.h + * @brief SE050 Platform SCP03 Secure Channel Interface + */ + +#ifndef SE050_SCP03_H +#define SE050_SCP03_H + +#include +#include +#include "se050_i2c_hal.h" + +/* Forward declarations */ +typedef struct se050_session_ctx se050_session_ctx_t; + +/* SCP03 key sizes */ +#define SCP03_KEY_SIZE 16 +#define SCP03_IV_SIZE 16 +#define SCP03_CMAC_SIZE 8 + +/* Initialize SCP03 context */ +se050_status_t se050_scp03_init(se050_scp03_ctx_t **ctx, se050_session_ctx_t *session); + +/* Set SCP03 keys */ +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); + +/* Encrypt command */ +se050_status_t se050_scp03_encrypt_command(se050_scp03_ctx_t *ctx, + uint8_t *cmd, size_t *cmd_len); + +/* Decrypt response */ +uint16_t se050_scp03_decrypt_response(se050_scp03_ctx_t *ctx, + size_t cmd_len, + uint8_t *rsp, size_t *rsp_len); + +/* Cleanup SCP03 context */ +void se050_scp03_cleanup(se050_scp03_ctx_t *ctx); + +#endif /* SE050_SCP03_H */ diff --git a/include/se050_session_internal.h b/include/se050_session_internal.h index 6c59edc..b89b521 100644 --- a/include/se050_session_internal.h +++ b/include/se050_session_internal.h @@ -20,17 +20,38 @@ typedef enum { SESSION_STATE_CLOSED, } session_state_t; +/** + * @brief SCP03 secure channel context + */ +typedef struct se050_scp03_ctx { + struct se050_session_ctx *session; /**< Associated session */ + uint8_t enc_key[16]; /**< Encryption key */ + uint8_t mac_key[16]; /**< MAC key */ + uint8_t dek_key[16]; /**< DEK key */ + uint8_t cmd_icv[8]; /**< Command ICV */ + uint8_t rsp_icv[8]; /**< Response ICV */ + uint64_t cmd_counter; /**< Command counter */ + uint64_t rsp_counter; /**< Response counter */ + uint8_t initialized; /**< Initialization flag */ +} se050_scp03_ctx_t; + +/** + * @brief RNG context (forward declaration) + */ +typedef struct se050_rng_ctx se050_rng_ctx_t; + /** * @brief Session context structure */ +typedef struct se050_session_ctx se050_session_ctx_t; + struct se050_session_ctx { se050_i2c_hal_t *hal; /**< I2C HAL interface */ session_state_t state; /**< Current session state */ uint32_t session_id; /**< Unique session identifier */ + se050_scp03_ctx_t *scp03; /**< SCP03 secure channel context */ uint8_t session_key[32]; /**< Session encryption key */ size_t session_key_len; /**< Session key length */ - uint32_t cmd_counter; /**< Command counter for SCP03 */ - uint32_t resp_counter; /**< Response counter for SCP03 */ se050_rng_ctx_t *rng; /**< RNG context */ }; diff --git a/src/se050_i2c_hal.c b/src/se050_i2c_hal.c index ba20472..d59237d 100644 --- a/src/se050_i2c_hal.c +++ b/src/se050_i2c_hal.c @@ -8,6 +8,7 @@ */ #define _POSIX_C_SOURCE 200809L +#include "se050_i2c_hal.h" #include "se050_wireguard.h" #include #include diff --git a/src/se050_keystore.c b/src/se050_keystore.c index 2875e2f..d353848 100644 --- a/src/se050_keystore.c +++ b/src/se050_keystore.c @@ -10,6 +10,8 @@ #define _GNU_SOURCE /* For MADV_DONTDUMP, MADV_WIPEONFORK */ #define _POSIX_C_SOURCE 200809L +#include "se050_i2c_hal.h" +#include "se050_session_internal.h" #include "se050_wireguard.h" #include "se050_crypto_utils.h" #include "se050_keystore_internal.h" diff --git a/src/se050_rng.c b/src/se050_rng.c index a3486fc..b929ec3 100644 --- a/src/se050_rng.c +++ b/src/se050_rng.c @@ -8,6 +8,7 @@ */ #define _POSIX_C_SOURCE 200809L +#include "se050_i2c_hal.h" #include "se050_wireguard.h" #include "se050_crypto_utils.h" #include "se050_session_internal.h" diff --git a/src/se050_scp03.c b/src/se050_scp03.c index 53eb917..3133fba 100644 --- a/src/se050_scp03.c +++ b/src/se050_scp03.c @@ -10,6 +10,9 @@ #define _GNU_SOURCE /* For MADV_DONTDUMP, MADV_WIPEONFORK */ #define _POSIX_C_SOURCE 200809L +#include "se050_i2c_hal.h" +#include "se050_session_internal.h" +#include "se050_scp03.h" #include "se050_wireguard.h" #include "se050_crypto_utils.h" #include "se050_mem_protect.h" @@ -28,21 +31,6 @@ #define SCP03_SW_SUCCESS 0x9000 #define SCP03_SW_FAIL 0x6F00 -/** - * @brief SCP03 session context structure - */ -struct se050_scp03_ctx { - se050_session_ctx_t *session; /**< Associated session */ - uint8_t enc_key[SCP03_KEY_SIZE]; /**< Encryption key */ - uint8_t mac_key[SCP03_KEY_SIZE]; /**< MAC key */ - uint8_t dek_key[SCP03_KEY_SIZE]; /**< DEK key (for key derivation) */ - uint8_t cmd_icv[SCP03_CMAC_SIZE]; /**< Command ICV */ - uint8_t rsp_icv[SCP03_CMAC_SIZE]; /**< Response ICV */ - uint64_t cmd_counter; /**< Command counter */ - uint64_t rsp_counter; /**< Response counter */ - uint8_t initialized; /**< Initialization flag */ -}; - /* ============================================================================ * Helper Functions * ============================================================================ */ diff --git a/src/se050_session.c b/src/se050_session.c index 59511b8..311354b 100644 --- a/src/se050_session.c +++ b/src/se050_session.c @@ -8,6 +8,8 @@ * License: MIT (Clean-room implementation) */ +#include "se050_i2c_hal.h" +#include "se050_session_internal.h" #include "se050_wireguard.h" #include "se050_crypto_utils.h" #include @@ -18,28 +20,6 @@ #define SCP03_SW_SUCCESS 0x9000 #define SCP03_SW_FAIL 0x6F00 -/* Session states */ -typedef enum { - SESSION_STATE_CREATED = 0, - SESSION_STATE_OPENED, - SESSION_STATE_CLOSED, -} session_state_t; - -/** - * @brief Session context structure - * - * Includes SCP03 secure channel support for PlatformSCP03 authentication. - */ -struct se050_session_ctx { - se050_i2c_hal_t *hal; /**< I2C HAL interface */ - session_state_t state; /**< Current session state */ - uint32_t session_id; /**< Unique session identifier */ - se050_scp03_ctx_t *scp03; /**< SCP03 secure channel context */ - uint8_t session_key[32]; /**< Session encryption key */ - size_t session_key_len; /**< Session key length */ - se050_rng_ctx_t *rng; /**< RNG context */ -}; - /* ============================================================================ * Session Management * ============================================================================ */ diff --git a/src/se050_wireguard.c b/src/se050_wireguard.c index 819ff86..ba3e349 100644 --- a/src/se050_wireguard.c +++ b/src/se050_wireguard.c @@ -175,10 +175,22 @@ int se050_wireguard_derive_keys(se050_wireguard_session_t *session, * Key derivation differs for initiator vs responder: * - Initiator: sending = T(1), receiving = T(2) * - Responder: sending = T(2), receiving = T(1) - * - * For now, using initiator mode (can be extended with is_initiator flag) */ - wg_hkdf_2(shared_secret, session->sending_key, session->receiving_key); + uint8_t t1[32], t2[32]; + wg_hkdf_2(shared_secret, t1, t2); + + if (session->is_initiator) { + /* Initiator: sending = T(1), receiving = T(2) */ + memcpy(session->sending_key, t1, 32); + memcpy(session->receiving_key, t2, 32); + } else { + /* Responder: sending = T(2), receiving = T(1) */ + memcpy(session->sending_key, t2, 32); + memcpy(session->receiving_key, t1, 32); + } + + memzero_explicit(t1, 32); + memzero_explicit(t2, 32); /* Reset nonces */ session->sending_nonce = 0; diff --git a/src/se050_x25519.c b/src/se050_x25519.c index 0e291d1..91b3cd8 100644 --- a/src/se050_x25519.c +++ b/src/se050_x25519.c @@ -7,10 +7,15 @@ * License: MIT (Clean-room implementation) */ +#include "se050_i2c_hal.h" #include "se050_wireguard.h" #include "se050_crypto_utils.h" #include "se050_keystore_internal.h" #include "se050_session_internal.h" +#include "se050_x25519_sw.h" + +/* Type alias for compatibility */ +typedef se050_x25519_sw_keypair_t se050_x25519_keypair_t; #include #include #include diff --git a/tests/test_wireguard.c b/tests/test_wireguard.c index 59618dc..df9f80a 100644 --- a/tests/test_wireguard.c +++ b/tests/test_wireguard.c @@ -95,8 +95,14 @@ static void test_encrypt_decrypt(void) /* Setup keys */ uint8_t shared_secret[32] = {0}; for (int i = 0; i < 32; i++) shared_secret[i] = i; + + /* Set as initiator for key derivation */ + session.is_initiator = 1; se050_wireguard_derive_keys(&session, shared_secret); + /* For single-session test, use same key for encrypt and decrypt */ + memcpy(session.receiving_key, session.sending_key, 32); + /* Test data */ const char *plaintext = "Hello, WireGuard!"; size_t plaintext_len = strlen(plaintext); @@ -135,8 +141,13 @@ static void test_replay_detection(void) /* Setup keys */ uint8_t shared_secret[32] = {0}; for (int i = 0; i < 32; i++) shared_secret[i] = i; + + session.is_initiator = 1; se050_wireguard_derive_keys(&session, shared_secret); + /* For single-session test, use same key for encrypt and decrypt */ + memcpy(session.receiving_key, session.sending_key, 32); + /* Encrypt a packet */ const char *plaintext = "Test message"; uint8_t encrypted[1024];