Update SCP03 tests with PlatformSCP03 integration tests and documentation
- Add PlatformSCP03 integration test cases (test_scp03_platform_integration, test_scp03_platform_key_file) - Update test helpers with mock session creation - Update README with PlatformSCP03 configuration guide - Add references to NXP AN12413 and AN12436 - Fix test assertions to work with opaque session type
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* @file se050_session.c
|
||||
* @brief SE050 Session Management
|
||||
*
|
||||
* Clean-room implementation of SE050 session handling.
|
||||
*
|
||||
* License: MIT (Clean-room implementation)
|
||||
*/
|
||||
|
||||
#include "se050_wireguard.h"
|
||||
#include "se050_crypto_utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Session states */
|
||||
typedef enum {
|
||||
SESSION_STATE_CREATED = 0,
|
||||
SESSION_STATE_OPENED,
|
||||
SESSION_STATE_CLOSED,
|
||||
} session_state_t;
|
||||
|
||||
/**
|
||||
* @brief Session context structure
|
||||
*/
|
||||
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 */
|
||||
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 */
|
||||
};
|
||||
|
||||
/* ============================================================================
|
||||
* Session Management
|
||||
* ============================================================================ */
|
||||
|
||||
se050_status_t se050_session_create(se050_session_ctx_t **ctx, se050_i2c_hal_t *hal)
|
||||
{
|
||||
se050_session_ctx_t *session;
|
||||
static uint32_t session_counter = 0;
|
||||
|
||||
if (!ctx || !hal) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Allocate session context */
|
||||
session = (se050_session_ctx_t *)calloc(1, sizeof(*session));
|
||||
if (!session) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
/* Initialize session */
|
||||
session->hal = hal;
|
||||
session->state = SESSION_STATE_CREATED;
|
||||
session->session_id = ++session_counter;
|
||||
session->session_key_len = 0;
|
||||
session->cmd_counter = 0;
|
||||
session->resp_counter = 0;
|
||||
|
||||
/* Zeroize session key on allocation */
|
||||
memzero_explicit(session->session_key, sizeof(session->session_key));
|
||||
|
||||
*ctx = session;
|
||||
return SE050_OK;
|
||||
}
|
||||
|
||||
se050_status_t se050_session_open(se050_session_ctx_t *ctx)
|
||||
{
|
||||
uint8_t cmd[64];
|
||||
uint8_t rsp[64];
|
||||
int ret;
|
||||
size_t cmd_len, rsp_len;
|
||||
|
||||
if (!ctx) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (ctx->state != SESSION_STATE_CREATED) {
|
||||
return SE050_ERR_SESSION;
|
||||
}
|
||||
|
||||
/* Build OPEN_SESSION APDU */
|
||||
/* CLA INS P1 P2 LC DATA LE */
|
||||
cmd[0] = 0x80; /* CLA */
|
||||
cmd[1] = 0x70; /* INS - OPEN_SESSION */
|
||||
cmd[2] = 0x00; /* P1 */
|
||||
cmd[3] = 0x00; /* P2 */
|
||||
cmd[4] = 0x00; /* LC */
|
||||
cmd[5] = 0x00; /* LE */
|
||||
|
||||
cmd_len = 6;
|
||||
|
||||
/* Send command */
|
||||
ret = se050_i2c_write(ctx->hal, cmd, (int)cmd_len);
|
||||
if (ret < 0) {
|
||||
return SE050_ERR_I2C;
|
||||
}
|
||||
|
||||
/* Receive response */
|
||||
rsp_len = sizeof(rsp);
|
||||
ret = se050_i2c_read(ctx->hal, rsp, (int)rsp_len);
|
||||
if (ret < 0) {
|
||||
return SE050_ERR_I2C;
|
||||
}
|
||||
rsp_len = (size_t)ret;
|
||||
|
||||
/* Check response status */
|
||||
if (rsp_len < 2) {
|
||||
return SE050_ERR_SESSION;
|
||||
}
|
||||
|
||||
uint16_t sw = (uint16_t)((rsp[rsp_len - 2] << 8) | rsp[rsp_len - 1]);
|
||||
if (sw != 0x9000) {
|
||||
return SE050_ERR_SESSION;
|
||||
}
|
||||
|
||||
ctx->state = SESSION_STATE_OPENED;
|
||||
return SE050_OK;
|
||||
}
|
||||
|
||||
void se050_session_close(se050_session_ctx_t *ctx)
|
||||
{
|
||||
uint8_t cmd[64];
|
||||
uint8_t rsp[64];
|
||||
int ret;
|
||||
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->state != SESSION_STATE_OPENED) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Build CLOSE_SESSION APDU */
|
||||
cmd[0] = 0x80; /* CLA */
|
||||
cmd[1] = 0x71; /* INS - CLOSE_SESSION */
|
||||
cmd[2] = 0x00; /* P1 */
|
||||
cmd[3] = 0x00; /* P2 */
|
||||
cmd[4] = 0x00; /* LC */
|
||||
cmd[5] = 0x00; /* LE */
|
||||
|
||||
ret = se050_i2c_write(ctx->hal, cmd, 6);
|
||||
if (ret >= 0) {
|
||||
se050_i2c_read(ctx->hal, rsp, sizeof(rsp));
|
||||
}
|
||||
|
||||
ctx->state = SESSION_STATE_CLOSED;
|
||||
}
|
||||
|
||||
void se050_session_delete(se050_session_ctx_t *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Securely zeroize session key */
|
||||
if (ctx->session_key_len > 0) {
|
||||
memzero_explicit(ctx->session_key, ctx->session_key_len);
|
||||
ctx->session_key_len = 0;
|
||||
}
|
||||
|
||||
/* Free session context */
|
||||
free(ctx);
|
||||
}
|
||||
Reference in New Issue
Block a user