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,209 @@
|
||||
/**
|
||||
* @file se050_keystore.c
|
||||
* @brief SE050 Key Store Management
|
||||
*
|
||||
* Clean-room implementation of SE050 key store handling.
|
||||
*
|
||||
* License: MIT (Clean-room implementation)
|
||||
*/
|
||||
|
||||
#include "se050_wireguard.h"
|
||||
#include "se050_crypto_utils.h"
|
||||
#include "se050_keystore_internal.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ============================================================================
|
||||
* Key Store Management
|
||||
* ============================================================================ */
|
||||
|
||||
se050_status_t se050_keystore_init(se050_keystore_ctx_t **ctx, se050_session_ctx_t *session)
|
||||
{
|
||||
se050_keystore_ctx_t *keystore;
|
||||
|
||||
if (!ctx || !session) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Allocate key store context */
|
||||
keystore = (se050_keystore_ctx_t *)calloc(1, sizeof(*keystore));
|
||||
if (!keystore) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
keystore->session = session;
|
||||
keystore->max_objects = 16; /* Maximum 16 keys */
|
||||
keystore->objects = (key_object_t *)calloc(keystore->max_objects, sizeof(key_object_t));
|
||||
|
||||
if (!keystore->objects) {
|
||||
free(keystore);
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
keystore->num_objects = 0;
|
||||
|
||||
*ctx = keystore;
|
||||
return SE050_OK;
|
||||
}
|
||||
|
||||
void se050_keystore_free(se050_keystore_ctx_t *ctx)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Securely zeroize all key objects */
|
||||
for (i = 0; i < ctx->num_objects; i++) {
|
||||
key_object_t *obj = &ctx->objects[i];
|
||||
|
||||
if (obj->flags & KEY_FLAG_GENERATED) {
|
||||
memzero_explicit(obj->private_key, sizeof(obj->private_key));
|
||||
memzero_explicit(obj->public_key, sizeof(obj->public_key));
|
||||
}
|
||||
}
|
||||
|
||||
/* Free key objects array */
|
||||
if (ctx->objects) {
|
||||
free(ctx->objects);
|
||||
ctx->objects = NULL;
|
||||
}
|
||||
|
||||
ctx->num_objects = 0;
|
||||
ctx->max_objects = 0;
|
||||
|
||||
/* Free key store context */
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Key Object Management
|
||||
* ============================================================================ */
|
||||
|
||||
/* Internal functions - defined in se050_keystore_internal.h */
|
||||
|
||||
key_object_t *find_key_object(se050_keystore_ctx_t *keystore, uint32_t key_id)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < keystore->num_objects; i++) {
|
||||
if (keystore->objects[i].key_id == key_id) {
|
||||
return &keystore->objects[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key_object_t *allocate_key_object(se050_keystore_ctx_t *keystore)
|
||||
{
|
||||
key_object_t *obj;
|
||||
|
||||
if (keystore->num_objects >= keystore->max_objects) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = &keystore->objects[keystore->num_objects];
|
||||
memset(obj, 0, sizeof(*obj));
|
||||
|
||||
keystore->num_objects++;
|
||||
return obj;
|
||||
}
|
||||
|
||||
se050_status_t se050_keystore_generate_key(se050_keystore_ctx_t *keystore,
|
||||
uint32_t key_id,
|
||||
cipher_type_t cipher_type,
|
||||
size_t key_size,
|
||||
uint8_t *private_key,
|
||||
uint8_t *public_key)
|
||||
{
|
||||
key_object_t *obj;
|
||||
|
||||
if (!keystore || !private_key || !public_key) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Check if key already exists */
|
||||
if (find_key_object(keystore, key_id) != NULL) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
/* Allocate new key object */
|
||||
obj = allocate_key_object(keystore);
|
||||
if (!obj) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
/* Initialize key object */
|
||||
obj->key_id = key_id;
|
||||
obj->key_part = KEY_PART_PAIR;
|
||||
obj->cipher_type = cipher_type;
|
||||
obj->key_size = key_size;
|
||||
obj->flags = KEY_FLAG_GENERATED | KEY_FLAG_PERSISTENT;
|
||||
|
||||
/* Copy key data securely */
|
||||
secure_memcpy(obj->private_key, private_key, key_size);
|
||||
secure_memcpy(obj->public_key, public_key, key_size);
|
||||
|
||||
return SE050_OK;
|
||||
}
|
||||
|
||||
se050_status_t se050_keystore_get_public_key(se050_keystore_ctx_t *keystore,
|
||||
uint32_t key_id,
|
||||
uint8_t *public_key,
|
||||
size_t *key_size)
|
||||
{
|
||||
key_object_t *obj;
|
||||
|
||||
if (!keystore || !public_key || !key_size) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Find key object */
|
||||
obj = find_key_object(keystore, key_id);
|
||||
if (!obj) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
/* Check if public key is available */
|
||||
if (!(obj->flags & KEY_FLAG_GENERATED)) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
/* Copy public key securely */
|
||||
*key_size = obj->key_size;
|
||||
secure_memcpy(public_key, obj->public_key, obj->key_size);
|
||||
|
||||
return SE050_OK;
|
||||
}
|
||||
|
||||
se050_status_t se050_keystore_get_private_key(se050_keystore_ctx_t *keystore,
|
||||
uint32_t key_id,
|
||||
uint8_t *private_key,
|
||||
size_t *key_size)
|
||||
{
|
||||
key_object_t *obj;
|
||||
|
||||
if (!keystore || !private_key || !key_size) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Find key object */
|
||||
obj = find_key_object(keystore, key_id);
|
||||
if (!obj) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
/* Check if private key is available */
|
||||
if (!(obj->flags & KEY_FLAG_GENERATED)) {
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
/* Copy private key securely */
|
||||
*key_size = obj->key_size;
|
||||
secure_memcpy(private_key, obj->private_key, obj->key_size);
|
||||
|
||||
return SE050_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user