mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-08-23 05:06:53 +01:00
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:
@@ -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
|
||||
)
|
||||
|
||||
+1
-1
Submodule pico-keys-sdk updated: 5f4032fdfa...b68cc7cfb6
@@ -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,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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user