Enforce HSM object policy when opening v1 private key material

Require verified PIN, SO/admin, or isolated firmware authorization without migrating legacy keys

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2026-07-17 23:16:32 +02:00
parent f77a07b927
commit d2ebbb2a44
6 changed files with 61 additions and 1 deletions
+1
View File
@@ -158,6 +158,7 @@ if(NOT ESP_PLATFORM)
add_test(NAME hsm_object_provider_test COMMAND hsm_object_provider_test)
add_executable(hsm_object_authorization_test
${CMAKE_CURRENT_LIST_DIR}/pico-keys-sdk/src/fs/object_policy.c
${CMAKE_CURRENT_LIST_DIR}/src/hsm/object_authorization.c
${CMAKE_CURRENT_LIST_DIR}/tests/hsm_object_authorization_test.c
)
+4
View File
@@ -22,6 +22,7 @@
#endif
#include "kek.h"
#include "crypto_utils.h"
#include "object_authorization.h"
#include "object_store.h"
#include "random.h"
#include "mbedtls/md.h"
@@ -343,6 +344,9 @@ int mkek_load_file(file_t *file, uint8_t *data, uint16_t *len) {
}
bool object_file = (file->fid >> 8) == HSM_OBJECT_PREFIX;
if (object_file && !hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_USE, false)) {
return PICOKEYS_NO_LOGIN;
}
uint32_t stored_len = file_get_size(file);
file_object_handle_t object_handle = FILE_OBJECT_INVALID_HANDLE;
if (object_file) {
+23
View File
@@ -23,6 +23,14 @@
static uint32_t hsm_object_session_epoch = 1;
static bool hsm_object_secure_messaging;
// Private-key operations require UV plus a user/admin MKEK session; firmware uses an isolated rule.
static const uint8_t hsm_object_key_policy[] = {
FILE_OBJECT_POLICY_FORMAT_VERSION, 3,
0x01, 0x7c, 0x00, 0x00, 0x04, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x01, 0x7c, 0x00, 0x00, 0x04, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x01, 0x7c, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
};
void hsm_object_authorization_session_invalidate(void) {
hsm_object_secure_messaging = false;
hsm_object_session_epoch++;
@@ -39,6 +47,13 @@ void hsm_object_authorization_command_set_secure_messaging(bool active) {
hsm_object_secure_messaging = active;
}
const uint8_t *hsm_object_authorization_key_policy(size_t *policy_size) {
if (policy_size) {
*policy_size = sizeof(hsm_object_key_policy);
}
return hsm_object_key_policy;
}
int hsm_object_authorization_context_build(bool internal_firmware, file_object_authorization_context_t *context) {
if (!context) {
return PICOKEYS_ERR_NULL_PARAM;
@@ -69,3 +84,11 @@ int hsm_object_authorization_context_build(bool internal_firmware, file_object_a
context->caller_namespace = HSM_OBJECT_NAMESPACE;
return PICOKEYS_OK;
}
bool hsm_object_authorization_key_operation(uint16_t operation, bool internal_firmware) {
file_object_authorization_context_t context;
if (hsm_object_authorization_context_build(internal_firmware, &context) != PICOKEYS_OK) {
return false;
}
return file_object_policy_authorize(hsm_object_key_policy, sizeof(hsm_object_key_policy), operation, &context);
}
+4
View File
@@ -20,7 +20,11 @@
#include "object_policy.h"
#define HSM_OBJECT_KEY_POLICY_ID 0x0101u
int hsm_object_authorization_context_build(bool internal_firmware, file_object_authorization_context_t *context);
const uint8_t *hsm_object_authorization_key_policy(size_t *policy_size);
bool hsm_object_authorization_key_operation(uint16_t operation, bool internal_firmware);
void hsm_object_authorization_session_invalidate(void);
uint32_t hsm_object_authorization_session_epoch(void);
void hsm_object_authorization_command_set_secure_messaging(bool active);
+28
View File
@@ -108,12 +108,40 @@ static void test_epoch_invalidation(void) {
assert(after.facts_epoch == after.session_epoch);
}
static void test_key_policy(void) {
size_t policy_size = 0;
const uint8_t *policy = hsm_object_authorization_key_policy(&policy_size);
assert(policy != NULL);
assert(file_object_policy_validate(policy, policy_size) == PICOKEYS_OK);
test_state_reset();
assert(!hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_USE, false));
isUserAuthenticated = true;
assert(!hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_USE, false));
has_session_pin = true;
assert(hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_USE, false));
assert(hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_SIGN, false));
assert(!hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_READ, false));
has_session_pin = false;
has_session_sopin = true;
assert(hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_EXPORT, false));
test_state_reset();
assert(hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_DERIVE, true));
assert(!hsm_object_authorization_key_operation(FILE_OBJECT_OPERATION_READ, true));
}
int main(void) {
test_unauthenticated_context();
test_authenticated_context();
test_secure_messaging_context();
test_internal_context();
test_epoch_invalidation();
test_key_policy();
assert(hsm_object_authorization_context_build(false, NULL) == PICOKEYS_ERR_NULL_PARAM);
puts("hsm_object_authorization_test: OK");
return 0;