mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(esp32p4): Support newer Key Manager key sources for ESP32-P4 V3
This commit is contained in:
@@ -21,7 +21,7 @@ if(CONFIG_SOC_ECDSA_SUPPORTED)
|
||||
list(APPEND srcs "ecdsa/test_ecdsa.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_KEY_MANAGER_SUPPORTED)
|
||||
if(CONFIG_CRYPTO_IS_KEY_MANAGER_SUPPORTED)
|
||||
list(APPEND srcs "key_manager/test_key_manager.c"
|
||||
"$ENV{IDF_PATH}/components/esp_security/src/esp_key_mgr.c")
|
||||
list(APPEND priv_include_dirs "$ENV{IDF_PATH}/components/esp_security/include")
|
||||
|
||||
@@ -37,9 +37,17 @@ menu "Test App Configuration"
|
||||
|
||||
config CRYPTO_TESTAPP_USE_AES_INTERRUPT
|
||||
bool "Use interrupt for long AES operations"
|
||||
depends on SOC_AES_SUPPORTED
|
||||
depends on SOC_AES_SUPPORTED
|
||||
default n
|
||||
help
|
||||
Use an interrupt to coordinate long AES operations.
|
||||
|
||||
config CRYPTO_IS_KEY_MANAGER_SUPPORTED
|
||||
bool
|
||||
default n if IDF_TARGET_ESP32P4 && ESP32P4_SELECTS_REV_LESS_V3
|
||||
default y
|
||||
depends on SOC_KEY_MANAGER_SUPPORTED
|
||||
help
|
||||
A hidden config to determine if the Key Manager tests should be included.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "unity.h"
|
||||
#include "unity_fixture.h"
|
||||
#include "unity_fixture_extras.h"
|
||||
@@ -30,7 +31,7 @@ static void run_all_tests(void)
|
||||
#endif /* !CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG*/
|
||||
#endif
|
||||
|
||||
#if CONFIG_SOC_KEY_MANAGER_SUPPORTED
|
||||
#if CONFIG_CRYPTO_IS_KEY_MANAGER_SUPPORTED
|
||||
RUN_TEST_GROUP(key_manager);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -93,6 +93,10 @@ static esp_err_t esp_ds_start_sign(const void *message, const esp_ds_data_t *dat
|
||||
|
||||
#if SOC_KEY_MANAGER_DS_KEY_DEPLOY
|
||||
if (key_id == HMAC_KEY_KM) {
|
||||
if (!key_mgr_ll_is_supported()) {
|
||||
HAL_ASSERT(false && "Key manager is not supported");
|
||||
}
|
||||
|
||||
ds_hal_set_key_source(DS_KEY_SOURCE_KEY_MGR);
|
||||
} else {
|
||||
ds_hal_set_key_source(DS_KEY_SOURCE_EFUSE);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import argparse
|
||||
import hashlib
|
||||
@@ -148,11 +148,11 @@ def generate_k1_G(key_file_path: str) -> tuple:
|
||||
|
||||
def generate_hmac_test_data(key: bytes) -> tuple:
|
||||
hmac_message = (
|
||||
'Deleniti voluptas explicabo et assumenda. Sed et aliquid minus quis. '
|
||||
'Praesentium cupiditate quia nemo est. Laboriosam pariatur ut distinctio tenetur. '
|
||||
'Sunt architecto iure aspernatur soluta ut recusandae. '
|
||||
'Ut quibusdam occaecati ut qui sit dignissimos eaque..'
|
||||
).encode('utf-8')
|
||||
b'Deleniti voluptas explicabo et assumenda. Sed et aliquid minus quis. '
|
||||
b'Praesentium cupiditate quia nemo est. Laboriosam pariatur ut distinctio tenetur. '
|
||||
b'Sunt architecto iure aspernatur soluta ut recusandae. '
|
||||
b'Ut quibusdam occaecati ut qui sit dignissimos eaque..'
|
||||
)
|
||||
hmac_result = hmac.HMAC(key, hmac_message, hashlib.sha256).digest()
|
||||
return hmac_message, hmac_result
|
||||
|
||||
@@ -179,22 +179,18 @@ def number_as_bignum_words(number): # type: (int) -> str
|
||||
return '{ ' + ', '.join(result) + ' }'
|
||||
|
||||
|
||||
def generate_ds_encrypted_input_params(aes_key: bytes, target: str) -> tuple:
|
||||
iv = os.urandom(16)
|
||||
max_key_size = max(supported_ds_key_size[target])
|
||||
key_size = max_key_size
|
||||
private_key = rsa.generate_private_key(public_exponent=65537, key_size=key_size, backend=default_backend())
|
||||
|
||||
def generate_ds_encrypted_input_params(aes_key: bytes, max_key_size: int, iv: bytes) -> tuple:
|
||||
private_key = rsa.generate_private_key(public_exponent=65537, key_size=max_key_size, backend=default_backend())
|
||||
priv_numbers = private_key.private_numbers()
|
||||
pub_numbers = private_key.public_key().public_numbers()
|
||||
Y = priv_numbers.d
|
||||
M = pub_numbers.n
|
||||
|
||||
rr = 1 << (key_size * 2)
|
||||
rr = 1 << (max_key_size * 2)
|
||||
rinv = rr % pub_numbers.n
|
||||
mprime = -rsa._modinv(M, 1 << 32)
|
||||
mprime &= 0xFFFFFFFF
|
||||
length = key_size // 32 - 1
|
||||
length = max_key_size // 32 - 1
|
||||
|
||||
# calculate MD from preceding values and IV
|
||||
# Y_max_key_size || M_max_key_size || Rb_max_key_size || M_prime32 || LENGTH32 || IV128
|
||||
@@ -230,12 +226,12 @@ def generate_ds_encrypted_input_params(aes_key: bytes, target: str) -> tuple:
|
||||
encryptor = cipher.encryptor()
|
||||
ds_encrypted_input_params = encryptor.update(p) + encryptor.finalize()
|
||||
|
||||
mask = (1 << key_size) - 1 # truncate messages if needed
|
||||
mask = (1 << max_key_size) - 1 # truncate messages if needed
|
||||
|
||||
ds_message = random.randrange(0, 1 << max_key_size)
|
||||
ds_result = number_as_bytes(pow(ds_message & mask, Y, M))
|
||||
|
||||
return number_as_bytes(ds_message), ds_encrypted_input_params, iv, key_size, ds_result
|
||||
return number_as_bytes(ds_message), ds_encrypted_input_params, ds_result
|
||||
|
||||
|
||||
def write_to_c_header(
|
||||
@@ -254,77 +250,77 @@ def write_to_c_header(
|
||||
k1_G_1: bytes,
|
||||
hmac_message: bytes,
|
||||
hmac_result: bytes,
|
||||
ds_message: bytes,
|
||||
ds_encrypted_input_params: bytes,
|
||||
ds_encrypted_input_params_iv: bytes,
|
||||
ds_key_size: int,
|
||||
ds_result: bytes,
|
||||
ds_message_4096: bytes,
|
||||
ds_encrypted_input_params_4096: bytes,
|
||||
ds_result_4096: bytes,
|
||||
ds_message_3072: bytes,
|
||||
ds_encrypted_input_params_3072: bytes,
|
||||
ds_result_3072: bytes,
|
||||
ds_iv: bytes,
|
||||
) -> None:
|
||||
with open('key_manager_test_cases.h', 'w', encoding='utf-8') as file:
|
||||
header_content = """#include <stdint.h>
|
||||
header_content = f"""#include <stdint.h>
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#define TEST_COUNT 5
|
||||
|
||||
typedef struct test_xts_data {
|
||||
typedef struct test_xts_data {{
|
||||
uint16_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint8_t ciphertext[128];
|
||||
} test_xts_data_t;
|
||||
}} test_xts_data_t;
|
||||
|
||||
typedef struct test_ecdsa_data {
|
||||
typedef struct test_ecdsa_data {{
|
||||
uint8_t pubx[32];
|
||||
uint8_t puby[32];
|
||||
} test_ecdsa_data_t;
|
||||
}} test_ecdsa_data_t;
|
||||
|
||||
typedef struct test_hmac_data {
|
||||
uint8_t message[%d];
|
||||
typedef struct test_hmac_data {{
|
||||
uint8_t message[{len(hmac_message)}];
|
||||
uint8_t hmac_result[32];
|
||||
} test_hmac_data_t;
|
||||
}} test_hmac_data_t;
|
||||
|
||||
typedef struct test_ds_data {
|
||||
uint8_t ds_message[%d / 8];
|
||||
uint8_t ds_encrypted_input_params[%d];
|
||||
uint8_t ds_encrypted_input_params_iv[16];
|
||||
typedef struct test_ds_data {{
|
||||
#if SOC_RSA_MAX_BIT_LEN == 4096
|
||||
uint8_t ds_message[4096 / 8];
|
||||
uint8_t ds_encrypted_input_params[1584];
|
||||
uint8_t ds_result[4096 / 8];
|
||||
#elif SOC_RSA_MAX_BIT_LEN == 3072
|
||||
uint8_t ds_message[3072 / 8];
|
||||
uint8_t ds_encrypted_input_params[1200];
|
||||
uint8_t ds_result[3072 / 8];
|
||||
#endif
|
||||
size_t ds_key_size;
|
||||
uint8_t ds_result[%d];
|
||||
} test_ds_data_t;
|
||||
uint8_t ds_encrypted_input_params_iv[16];
|
||||
}} test_ds_data_t;
|
||||
|
||||
typedef struct test_data {
|
||||
typedef struct test_data {{
|
||||
uint8_t init_key[32];
|
||||
uint8_t k2_info[64];
|
||||
uint8_t k1_encrypted[2][32]; // For both 256-bit and 512-bit keys
|
||||
uint8_t plaintext_data[128];
|
||||
union {
|
||||
union {{
|
||||
test_xts_data_t xts_test_data[TEST_COUNT];
|
||||
test_ecdsa_data_t ecdsa_test_data;
|
||||
test_hmac_data_t hmac_test_data;
|
||||
test_ds_data_t ds_test_data;
|
||||
};
|
||||
} test_data_aes_mode_t;
|
||||
}};
|
||||
}} test_data_aes_mode_t;
|
||||
|
||||
typedef struct test_data_ecdh0 {
|
||||
typedef struct test_data_ecdh0 {{
|
||||
uint8_t plaintext_data[128];
|
||||
uint8_t k1[2][32];
|
||||
uint8_t k1_G[2][64];
|
||||
} test_data_ecdh0_mode_t;
|
||||
}} test_data_ecdh0_mode_t;
|
||||
|
||||
// For 32-byte k1 key
|
||||
test_data_aes_mode_t test_data_xts_aes_128 = {
|
||||
.init_key = { %s },
|
||||
.k2_info = { %s },
|
||||
.k1_encrypted = { { %s }, { } },
|
||||
.plaintext_data = { %s },
|
||||
.xts_test_data = {
|
||||
""" % (
|
||||
len(hmac_message),
|
||||
ds_key_size,
|
||||
len(ds_encrypted_input_params),
|
||||
len(ds_result),
|
||||
key_to_c_format(init_key),
|
||||
key_to_c_format(k2_info),
|
||||
key_to_c_format(k1_encrypted_32_reversed[0]),
|
||||
key_to_c_format(bytes(range(1, 129))),
|
||||
)
|
||||
test_data_aes_mode_t test_data_xts_aes_128 = {{
|
||||
.init_key = {{ {key_to_c_format(init_key)} }},
|
||||
.k2_info = {{ {key_to_c_format(k2_info)} }},
|
||||
.k1_encrypted = {{ {{ {key_to_c_format(k1_encrypted_32_reversed[0])} }}, {{ }} }},
|
||||
.plaintext_data = {{ {key_to_c_format(bytes(range(1, 129)))} }},
|
||||
.xts_test_data = {{
|
||||
"""
|
||||
|
||||
for data_size, flash_address, ciphertext in test_data_xts_aes_128:
|
||||
header_content += (
|
||||
@@ -354,85 +350,65 @@ test_data_aes_mode_t test_data_xts_aes_128 = {
|
||||
)
|
||||
header_content += '\t}\n};\n'
|
||||
|
||||
header_content += """
|
||||
test_data_aes_mode_t test_data_ecdsa = {
|
||||
.init_key = { %s },
|
||||
.k2_info = { %s },
|
||||
.k1_encrypted = { { %s }, { } },
|
||||
.ecdsa_test_data = {
|
||||
.pubx = { %s },
|
||||
.puby = { %s }
|
||||
}
|
||||
};\n
|
||||
""" % (
|
||||
key_to_c_format(init_key),
|
||||
key_to_c_format(k2_info),
|
||||
key_to_c_format(k1_encrypted_32_reversed[0]),
|
||||
key_to_c_format(pubx),
|
||||
key_to_c_format(puby),
|
||||
)
|
||||
header_content += f"""
|
||||
test_data_aes_mode_t test_data_ecdsa = {{
|
||||
.init_key = {{ {key_to_c_format(init_key)} }},
|
||||
.k2_info = {{ {key_to_c_format(k2_info)} }},
|
||||
.k1_encrypted = {{ {{ {key_to_c_format(k1_encrypted_32_reversed[0])} }}, {{ }} }},
|
||||
.ecdsa_test_data = {{
|
||||
.pubx = {{ {key_to_c_format(pubx)} }},
|
||||
.puby = {{ {key_to_c_format(puby)} }}
|
||||
}}
|
||||
}};
|
||||
"""
|
||||
|
||||
header_content += """
|
||||
test_data_ecdh0_mode_t test_data_ecdh0 = {
|
||||
.plaintext_data = { %s },
|
||||
.k1 = {
|
||||
{ %s },
|
||||
{ %s },
|
||||
},
|
||||
.k1_G = {
|
||||
{ %s },
|
||||
{ %s },
|
||||
}
|
||||
};\n
|
||||
""" % (
|
||||
key_to_c_format(bytes(range(1, 129))),
|
||||
key_to_c_format(k1),
|
||||
key_to_c_format(k1),
|
||||
key_to_c_format(k1_G_0),
|
||||
key_to_c_format(k1_G_1),
|
||||
)
|
||||
header_content += f"""
|
||||
test_data_ecdh0_mode_t test_data_ecdh0 = {{
|
||||
.plaintext_data = {{ {key_to_c_format(bytes(range(1, 129)))} }},
|
||||
.k1 = {{
|
||||
{{ {key_to_c_format(k1)} }},
|
||||
{{ {key_to_c_format(k1)} }},
|
||||
}},
|
||||
.k1_G = {{
|
||||
{{ {key_to_c_format(k1_G_0)} }},
|
||||
{{ {key_to_c_format(k1_G_1)} }},
|
||||
}}
|
||||
}};
|
||||
"""
|
||||
|
||||
header_content += """
|
||||
test_data_aes_mode_t test_data_hmac = {
|
||||
.init_key = { %s },
|
||||
.k2_info = { %s },
|
||||
.k1_encrypted = { { %s }, { } },
|
||||
.hmac_test_data = {
|
||||
.message = { %s },
|
||||
.hmac_result = { %s }
|
||||
}
|
||||
};\n
|
||||
""" % (
|
||||
key_to_c_format(init_key),
|
||||
key_to_c_format(k2_info),
|
||||
key_to_c_format(k1_encrypted_32[0]),
|
||||
key_to_c_format(hmac_message),
|
||||
key_to_c_format(hmac_result),
|
||||
)
|
||||
header_content += f"""
|
||||
test_data_aes_mode_t test_data_hmac = {{
|
||||
.init_key = {{ {key_to_c_format(init_key)} }},
|
||||
.k2_info = {{ {key_to_c_format(k2_info)} }},
|
||||
.k1_encrypted = {{ {{ {key_to_c_format(k1_encrypted_32[0])} }}, {{ }} }},
|
||||
.hmac_test_data = {{
|
||||
.message = {{ {key_to_c_format(hmac_message)} }},
|
||||
.hmac_result = {{ {key_to_c_format(hmac_result)} }}
|
||||
}}
|
||||
}};
|
||||
"""
|
||||
|
||||
header_content += """
|
||||
test_data_aes_mode_t test_data_ds = {
|
||||
.init_key = { %s },
|
||||
.k2_info = { %s },
|
||||
.k1_encrypted = { { %s }, { } },
|
||||
.ds_test_data = {
|
||||
.ds_message = { %s },
|
||||
.ds_encrypted_input_params = { %s },
|
||||
.ds_encrypted_input_params_iv = { %s },
|
||||
.ds_key_size = %d,
|
||||
.ds_result = { %s }
|
||||
}
|
||||
};\n
|
||||
""" % (
|
||||
key_to_c_format(init_key),
|
||||
key_to_c_format(k2_info),
|
||||
key_to_c_format(k1_encrypted_32_reversed[0]),
|
||||
key_to_c_format(ds_message),
|
||||
key_to_c_format(ds_encrypted_input_params),
|
||||
key_to_c_format(ds_encrypted_input_params_iv),
|
||||
ds_key_size,
|
||||
key_to_c_format(ds_result),
|
||||
)
|
||||
header_content += f"""
|
||||
test_data_aes_mode_t test_data_ds = {{
|
||||
.init_key = {{ {key_to_c_format(init_key)} }},
|
||||
.k2_info = {{ {key_to_c_format(k2_info)} }},
|
||||
.k1_encrypted = {{ {{ {key_to_c_format(k1_encrypted_32_reversed[0])} }}, {{ }} }},
|
||||
.ds_test_data = {{
|
||||
#if SOC_DS_SIGNATURE_MAX_BIT_LEN == 4096
|
||||
.ds_message = {{ {key_to_c_format(ds_message_4096)} }},
|
||||
.ds_encrypted_input_params = {{ {key_to_c_format(ds_encrypted_input_params_4096)} }},
|
||||
.ds_key_size = 4096,
|
||||
.ds_result = {{ {key_to_c_format(ds_result_4096)} }},
|
||||
#elif SOC_DS_SIGNATURE_MAX_BIT_LEN == 3072
|
||||
.ds_message = {{ {key_to_c_format(ds_message_3072)} }},
|
||||
.ds_encrypted_input_params = {{ {key_to_c_format(ds_encrypted_input_params_3072)} }},
|
||||
.ds_key_size = 3072,
|
||||
.ds_result = {{ {key_to_c_format(ds_result_3072)} }},
|
||||
#endif
|
||||
.ds_encrypted_input_params_iv = {{ {key_to_c_format(ds_iv)} }},
|
||||
}},
|
||||
}};
|
||||
"""
|
||||
|
||||
file.write(header_content)
|
||||
|
||||
@@ -472,8 +448,14 @@ def generate_tests_cases(target: str) -> None:
|
||||
|
||||
hmac_message, hmac_result = generate_hmac_test_data(k1_32)
|
||||
|
||||
ds_message, ds_encrypted_input_params, ds_encrypted_input_params_iv, ds_key_size, ds_result = (
|
||||
generate_ds_encrypted_input_params(k1_32, target)
|
||||
ds_iv = os.urandom(16)
|
||||
|
||||
ds_message_4096, ds_encrypted_input_params_4096, ds_result_4096 = generate_ds_encrypted_input_params(
|
||||
k1_32, 4096, ds_iv
|
||||
)
|
||||
|
||||
ds_message_3072, ds_encrypted_input_params_3072, ds_result_3072 = generate_ds_encrypted_input_params(
|
||||
k1_32, 3072, ds_iv
|
||||
)
|
||||
|
||||
write_to_c_header(
|
||||
@@ -492,11 +474,13 @@ def generate_tests_cases(target: str) -> None:
|
||||
k1_G_1,
|
||||
hmac_message,
|
||||
hmac_result,
|
||||
ds_message,
|
||||
ds_encrypted_input_params,
|
||||
ds_encrypted_input_params_iv,
|
||||
ds_key_size,
|
||||
ds_result,
|
||||
ds_message_4096,
|
||||
ds_encrypted_input_params_4096,
|
||||
ds_result_4096,
|
||||
ds_message_3072,
|
||||
ds_encrypted_input_params_3072,
|
||||
ds_result_3072,
|
||||
ds_iv,
|
||||
)
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user