Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions plugins/ossl_prov/inc/azihsm_ossl_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extern "C"
#endif

// Value provided by CMake, defined in top level CMakeLists.txt
#define AZIHSM_OSSL_VERSION ""
#define AZIHSM_OSSL_VERSION "0.0.1"
#define AZIHSM_OSSL_NAME "azihsm"

#ifndef _Return_type_success_
Expand All @@ -37,25 +37,12 @@ typedef struct
azihsm_handle priv;
} AZIHSM_KEY_PAIR_OBJ;

/* Default file paths for partition keys */
#define AZIHSM_DEFAULT_BMK_PATH "/var/lib/azihsm/bmk.bin"
#define AZIHSM_DEFAULT_MUK_PATH "/var/lib/azihsm/muk.bin"
#define AZIHSM_DEFAULT_MOBK_PATH "/var/lib/azihsm/mobk.bin"

typedef struct
{
char bmk_path[4096];
char muk_path[4096];
char mobk_path[4096];
} AZIHSM_CONFIG;

typedef struct
{
OSSL_LIB_CTX *libctx;
const OSSL_CORE_HANDLE *handle;
azihsm_handle device;
azihsm_handle session;
AZIHSM_CONFIG config;
} AZIHSM_OSSL_PROV_CTX;

static const OSSL_PARAM azihsm_ossl_param_types[] = {
Expand Down
15 changes: 1 addition & 14 deletions plugins/ossl_prov/inc/azihsm_ossl_base.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extern "C"
#endif

// Value provided by CMake, defined in top level CMakeLists.txt
#define AZIHSM_OSSL_VERSION "@AZIHSM-OpenSSL-Provider_VERSION@"
#define AZIHSM_OSSL_VERSION "@azihsm_ossl_provider_VERSION@"
#define AZIHSM_OSSL_NAME "azihsm"

#ifndef _Return_type_success_
Expand All @@ -37,25 +37,12 @@ typedef struct
azihsm_handle priv;
} AZIHSM_KEY_PAIR_OBJ;

/* Default file paths for partition keys */
#define AZIHSM_DEFAULT_BMK_PATH "/var/lib/azihsm/bmk.bin"
#define AZIHSM_DEFAULT_MUK_PATH "/var/lib/azihsm/muk.bin"
#define AZIHSM_DEFAULT_MOBK_PATH "/var/lib/azihsm/mobk.bin"

typedef struct
{
char bmk_path[4096];
char muk_path[4096];
char mobk_path[4096];
} AZIHSM_CONFIG;

typedef struct
{
OSSL_LIB_CTX *libctx;
const OSSL_CORE_HANDLE *handle;
azihsm_handle device;
azihsm_handle session;
AZIHSM_CONFIG config;
} AZIHSM_OSSL_PROV_CTX;

static const OSSL_PARAM azihsm_ossl_param_types[] = {
Expand Down
40 changes: 39 additions & 1 deletion plugins/ossl_prov/inc/azihsm_ossl_hsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,47 @@ extern "C"
#endif

#include <azihsm.h>
#include <stdint.h>

#include "azihsm_ossl_base.h"
/* Environment variable names for credentials paths.
* These are checked first, before falling back to hardcoded defaults. */
#define AZIHSM_ENV_CREDENTIALS_ID_PATH "AZIHSM_CREDENTIALS_ID_PATH"
#define AZIHSM_ENV_CREDENTIALS_PIN_PATH "AZIHSM_CREDENTIALS_PIN_PATH"

/* Default file paths for partition keys */
#define AZIHSM_DEFAULT_BMK_PATH "/var/lib/azihsm/bmk.bin"
#define AZIHSM_DEFAULT_MUK_PATH "/var/lib/azihsm/muk.bin"
#define AZIHSM_DEFAULT_MOBK_PATH "/var/lib/azihsm/mobk.bin"
Copy link
Contributor

@mhatrevi mhatrevi Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to add following to the config:

  1. Caller OBK
  2. Caller POTA endorsement (pub key; signature)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think we need to overhaul the PR once #164 is merged.

#define AZIHSM_DEFAULT_CREDENTIALS_ID_PATH "/var/lib/azihsm/credentials_id.bin"
#define AZIHSM_DEFAULT_CREDENTIALS_PIN_PATH "/var/lib/azihsm/credentials_pin.bin"

/* Configuration parameter names for openssl.cnf */
#define AZIHSM_CFG_BMK_PATH "azihsm-bmk-path"
#define AZIHSM_CFG_MUK_PATH "azihsm-muk-path"
#define AZIHSM_CFG_MOBK_PATH "azihsm-mobk-path"
#define AZIHSM_CFG_API_REVISION "azihsm-api-revision"

/* Supported API revision range */
#define AZIHSM_API_REVISION_MIN_MAJOR 1
#define AZIHSM_API_REVISION_MIN_MINOR 0
#define AZIHSM_API_REVISION_MAX_MAJOR 1
#define AZIHSM_API_REVISION_MAX_MINOR 0
#define AZIHSM_API_REVISION_DEFAULT_MAJOR 1
#define AZIHSM_API_REVISION_DEFAULT_MINOR 0

/* Provider configuration structure */
typedef struct
{
char *credentials_id_path; /* Path to credentials ID file */
char *credentials_pin_path; /* Path to credentials PIN file */
char *bmk_path; /* Path to BMK file */
char *muk_path; /* Path to MUK file */
char *mobk_path; /* Path to MOBK file */
uint16_t api_revision_major; /* API revision major version */
uint16_t api_revision_minor; /* API revision minor version */
} AZIHSM_CONFIG;

void azihsm_config_free(AZIHSM_CONFIG *config);
void azihsm_close_device_and_session(azihsm_handle device, azihsm_handle session);
azihsm_status azihsm_open_device_and_session(
const AZIHSM_CONFIG *config,
Expand Down
216 changes: 201 additions & 15 deletions plugins/ossl_prov/src/azihsm_ossl_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <openssl/evp.h>
#include <openssl/prov_ssl.h>
#include <openssl/proverr.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#include "azihsm_ossl_base.h"
Expand Down Expand Up @@ -297,6 +299,166 @@ static const OSSL_DISPATCH azihsm_ossl_base_dispatch[] = {
{ 0, NULL },
};

/*
* Helper to strip "file:" prefix from path if present.
* Returns pointer to the actual path (may be the original string or offset by 5).
*/
static const char *strip_file_prefix(const char *path)
{
if (path == NULL)
{
return NULL;
}
if (strncmp(path, "file:", 5) == 0)
{
return path + 5;
}
return path;
}

/*
* Validate that all required config fields are non-NULL.
* Returns 1 if valid, 0 if any required field is NULL.
*/
static int azihsm_config_is_valid(const AZIHSM_CONFIG *config)
{
if (config == NULL)
{
return 0;
}
return config->credentials_id_path != NULL && config->credentials_pin_path != NULL &&
config->bmk_path != NULL && config->muk_path != NULL && config->mobk_path != NULL;
}

/*
* Validate that the API revision is within the supported range.
* Returns 1 if valid, 0 if out of range.
*/
static int azihsm_api_revision_is_valid(const AZIHSM_CONFIG *config)
{
uint32_t version;
uint32_t min_version;
uint32_t max_version;

if (config == NULL)
{
return 0;
}

/* Combine major.minor into a single comparable value */
version = ((uint32_t)config->api_revision_major << 16) | config->api_revision_minor;
min_version = ((uint32_t)AZIHSM_API_REVISION_MIN_MAJOR << 16) | AZIHSM_API_REVISION_MIN_MINOR;
max_version = ((uint32_t)AZIHSM_API_REVISION_MAX_MAJOR << 16) | AZIHSM_API_REVISION_MAX_MINOR;

return version >= min_version && version <= max_version;
}

/*
* Get path from environment variable, falling back to default if not set.
* Returns a newly allocated string that must be freed with OPENSSL_free.
*/
static char *get_path_from_env_or_default(const char *env_var, const char *default_path)
{
const char *env_value = getenv(env_var);
if (env_value != NULL && env_value[0] != '\0')
{
return OPENSSL_strdup(env_value);
}
return OPENSSL_strdup(default_path);
}

/*
* Parse configuration parameters from OpenSSL config file.
* Returns a populated AZIHSM_CONFIG structure with all path fields set.
*
* If OPENSSL_strdup fails for any allocation, the corresponding field will be NULL.
* Caller MUST check azihsm_config_is_valid() after this call to detect allocation
* failures before using the config. On validation failure, caller should call
* azihsm_config_free() to clean up any partially allocated fields.
*/
static AZIHSM_CONFIG parse_provider_config(
const OSSL_CORE_HANDLE *handle,
OSSL_FUNC_core_get_params_fn *get_params
)
{
AZIHSM_CONFIG config = { NULL,
NULL,
NULL,
NULL,
NULL,
AZIHSM_API_REVISION_DEFAULT_MAJOR,
AZIHSM_API_REVISION_DEFAULT_MINOR };
const char *bmk_path = NULL;
const char *muk_path = NULL;
const char *mobk_path = NULL;
const char *api_revision = NULL;

OSSL_PARAM core_params[] = {
OSSL_PARAM_construct_utf8_ptr(AZIHSM_CFG_BMK_PATH, (char **)&bmk_path, sizeof(void *)),
OSSL_PARAM_construct_utf8_ptr(AZIHSM_CFG_MUK_PATH, (char **)&muk_path, sizeof(void *)),
OSSL_PARAM_construct_utf8_ptr(AZIHSM_CFG_MOBK_PATH, (char **)&mobk_path, sizeof(void *)),
OSSL_PARAM_construct_utf8_ptr(
AZIHSM_CFG_API_REVISION,
(char **)&api_revision,
sizeof(void *)
),
OSSL_PARAM_construct_end()
};

/* Fetch parameters from OpenSSL core (returns 1 on success, 0 on failure) */
if (get_params != NULL && get_params(handle, core_params) == 1)
{
/* Copy values with file: prefix handling for key paths */
if (bmk_path != NULL)
{
config.bmk_path = OPENSSL_strdup(strip_file_prefix(bmk_path));
}
if (muk_path != NULL)
{
config.muk_path = OPENSSL_strdup(strip_file_prefix(muk_path));
}
if (mobk_path != NULL)
{
config.mobk_path = OPENSSL_strdup(strip_file_prefix(mobk_path));
}
if (api_revision != NULL)
{
unsigned int major = 0, minor = 0;
if (sscanf(api_revision, "%u.%u", &major, &minor) == 2)
{
config.api_revision_major = (uint16_t)major;
config.api_revision_minor = (uint16_t)minor;
}
}
}

/* Apply defaults for any paths not provided in config.
* Credentials: environment variable > hardcoded default (not in openssl.cnf)
* Key paths: openssl.cnf > hardcoded default */
config.credentials_id_path = get_path_from_env_or_default(
AZIHSM_ENV_CREDENTIALS_ID_PATH,
AZIHSM_DEFAULT_CREDENTIALS_ID_PATH
);
config.credentials_pin_path = get_path_from_env_or_default(
AZIHSM_ENV_CREDENTIALS_PIN_PATH,
AZIHSM_DEFAULT_CREDENTIALS_PIN_PATH
);
if (config.bmk_path == NULL)
{
config.bmk_path = OPENSSL_strdup(AZIHSM_DEFAULT_BMK_PATH);
}
if (config.muk_path == NULL)
{
config.muk_path = OPENSSL_strdup(AZIHSM_DEFAULT_MUK_PATH);
}
if (config.mobk_path == NULL)
{
config.mobk_path = OPENSSL_strdup(AZIHSM_DEFAULT_MOBK_PATH);
}

return config;
}

OSSL_STATUS OSSL_provider_init(
const OSSL_CORE_HANDLE *handle,
const OSSL_DISPATCH *in,
Expand All @@ -305,7 +467,11 @@ OSSL_STATUS OSSL_provider_init(
)
{
AZIHSM_OSSL_PROV_CTX *ctx;
AZIHSM_CONFIG config = {
NULL, NULL, NULL, NULL, NULL,
};
azihsm_status status;
const OSSL_DISPATCH *in_iter;

if ((ctx = OPENSSL_zalloc(sizeof(AZIHSM_OSSL_PROV_CTX))) == NULL)
{
Expand All @@ -322,32 +488,52 @@ OSSL_STATUS OSSL_provider_init(
return OSSL_FAILURE;
}

/* Initialize config with hardcoded default paths */
snprintf(ctx->config.bmk_path, sizeof(ctx->config.bmk_path), "%s", AZIHSM_DEFAULT_BMK_PATH);
snprintf(ctx->config.muk_path, sizeof(ctx->config.muk_path), "%s", AZIHSM_DEFAULT_MUK_PATH);
snprintf(ctx->config.mobk_path, sizeof(ctx->config.mobk_path), "%s", AZIHSM_DEFAULT_MOBK_PATH);
/* First pass: find core_get_params function */
for (in_iter = in; in_iter->function_id != 0; in_iter++)
{
if (in_iter->function_id == OSSL_FUNC_CORE_GET_PARAMS)
{
core_get_params = OSSL_FUNC_core_get_params(in_iter);
break;
}
}

status = azihsm_open_device_and_session(&ctx->config, &ctx->device, &ctx->session);
/* Parse configuration from openssl.cnf */
config = parse_provider_config(handle, core_get_params);

if (status != AZIHSM_STATUS_SUCCESS)
/* Validate configuration (check for allocation failures) */
if (!azihsm_config_is_valid(&config))
{
ERR_raise(ERR_LIB_PROV, ERR_R_INIT_FAIL);

ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
azihsm_config_free(&config);
OSSL_LIB_CTX_free(ctx->libctx);
OPENSSL_free(ctx);
return OSSL_FAILURE;
}

for (; in->function_id != 0; in++)
/* Validate API revision is within supported range */
if (!azihsm_api_revision_is_valid(&config))
{
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA);
azihsm_config_free(&config);
OSSL_LIB_CTX_free(ctx->libctx);
OPENSSL_free(ctx);
return OSSL_FAILURE;
}

switch (in->function_id)
{
/* Open device and session with configuration */
status = azihsm_open_device_and_session(&config, &ctx->device, &ctx->session);

case OSSL_FUNC_CORE_GET_PARAMS:
core_get_params = OSSL_FUNC_core_get_params(in);
break;
}
/* Free configuration (no longer needed) */
azihsm_config_free(&config);

if (status != AZIHSM_STATUS_SUCCESS)
{
ERR_raise(ERR_LIB_PROV, ERR_R_INIT_FAIL);

OSSL_LIB_CTX_free(ctx->libctx);
OPENSSL_free(ctx);
return OSSL_FAILURE;
}

*provctx = ctx;
Expand Down
Loading