mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(hal): Add crypto tests for key manager
Added test to verify exporting of ECDSA public key Added test to verify XTS_AES in random mode Added pytest test case for testing ECDH0 mode for XTS_128 and XTS_256 key Add test for ECDSA key in ECDH0 mode Update the key manager hal based tests Update key manager tests to add ECDH0 workflow
This commit is contained in:
parent
e5fcc2d315
commit
79b21fb624
@ -21,6 +21,12 @@ if(CONFIG_SOC_ECDSA_SUPPORTED)
|
||||
list(APPEND srcs "ecdsa/test_ecdsa.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_KEY_MANAGER_SUPPORTED)
|
||||
list(APPEND srcs "key_manager/test_key_manager.c"
|
||||
"$ENV{IDF_PATH}/components/esp_hw_support/esp_key_mgr.c")
|
||||
list(APPEND priv_include_dirs "$ENV{IDF_PATH}/components/esp_hw_support/include")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_AES_SUPPORTED)
|
||||
list(APPEND srcs "aes/test_aes.c"
|
||||
"$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_common.c"
|
||||
@ -68,7 +74,7 @@ if(CONFIG_SOC_SHA_SUPPORTED)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
PRIV_REQUIRES efuse mbedtls esp_mm bootloader_support
|
||||
PRIV_REQUIRES efuse mbedtls esp_mm bootloader_support spi_flash
|
||||
REQUIRES test_utils unity
|
||||
WHOLE_ARCHIVE
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
|
@ -30,6 +30,10 @@ static void run_all_tests(void)
|
||||
#endif /* !CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG*/
|
||||
#endif
|
||||
|
||||
#if CONFIG_SOC_KEY_MANAGER_SUPPORTED
|
||||
RUN_TEST_GROUP(key_manager);
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
|
||||
#if CONFIG_SOC_HMAC_SUPPORTED && CONFIG_CRYPTO_TEST_APP_ENABLE_HMAC_TESTS
|
||||
|
@ -72,7 +72,7 @@ static void ecc_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len
|
||||
}
|
||||
}
|
||||
|
||||
static int test_ecdsa_verify(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, uint8_t *pub_x, uint8_t *pub_y)
|
||||
int test_ecdsa_verify(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, uint8_t *pub_x, uint8_t *pub_y)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t sha_le[32];
|
||||
@ -139,7 +139,7 @@ static void test_ecdsa_corrupt_data(bool is_p256, uint8_t* sha, uint8_t* r_le, u
|
||||
|
||||
}
|
||||
|
||||
static void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, bool use_km_key, ecdsa_sign_type_t k_type)
|
||||
void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, bool use_km_key, ecdsa_sign_type_t k_type)
|
||||
{
|
||||
uint8_t sha_le[32] = {0};
|
||||
uint8_t zeroes[32] = {0};
|
||||
@ -201,7 +201,7 @@ static void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t*
|
||||
ecdsa_disable();
|
||||
}
|
||||
|
||||
static void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_x, uint8_t* pub_y, bool use_km_key, ecdsa_sign_type_t k_type)
|
||||
void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_x, uint8_t* pub_y, bool use_km_key, ecdsa_sign_type_t k_type)
|
||||
{
|
||||
uint8_t r_le[32] = {0};
|
||||
uint8_t s_le[32] = {0};
|
||||
@ -211,13 +211,10 @@ static void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_
|
||||
}
|
||||
|
||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
static void test_ecdsa_export_pubkey(bool is_p256, bool use_km_key)
|
||||
void test_ecdsa_export_pubkey_inner(bool is_p256, uint8_t *exported_pub_x, uint8_t *exported_pub_y, bool use_km_key, uint16_t *len)
|
||||
{
|
||||
uint8_t pub_x[32] = {0};
|
||||
uint8_t pub_y[32] = {0};
|
||||
uint8_t zeroes[32] = {0};
|
||||
uint16_t len;
|
||||
|
||||
uint8_t zeroes[32] = {0};
|
||||
ecdsa_hal_config_t conf = {
|
||||
.mode = ECDSA_MODE_EXPORT_PUBKEY,
|
||||
.use_km_key = use_km_key,
|
||||
@ -228,13 +225,13 @@ static void test_ecdsa_export_pubkey(bool is_p256, bool use_km_key)
|
||||
if (use_km_key == 0) {
|
||||
conf.efuse_key_blk = EFUSE_BLK_KEY0 + ECDSA_KEY_BLOCK_2;
|
||||
}
|
||||
len = 32;
|
||||
*len = 32;
|
||||
} else {
|
||||
conf.curve = ECDSA_CURVE_SECP192R1;
|
||||
if (use_km_key == 0) {
|
||||
conf.efuse_key_blk = EFUSE_BLK_KEY0 + ECDSA_KEY_BLOCK_1;
|
||||
}
|
||||
len = 24;
|
||||
*len = 24;
|
||||
}
|
||||
|
||||
ecdsa_enable_and_reset();
|
||||
@ -242,24 +239,28 @@ static void test_ecdsa_export_pubkey(bool is_p256, bool use_km_key)
|
||||
bool process_again = false;
|
||||
|
||||
do {
|
||||
ecdsa_hal_export_pubkey(&conf, pub_x, pub_y, len);
|
||||
ecdsa_hal_export_pubkey(&conf, exported_pub_x, exported_pub_y, *len);
|
||||
|
||||
process_again = !ecdsa_hal_get_operation_result()
|
||||
|| !memcmp(pub_x, zeroes, len)
|
||||
|| !memcmp(pub_y, zeroes, len);
|
||||
|| !memcmp(exported_pub_x, zeroes, *len)
|
||||
|| !memcmp(exported_pub_y, zeroes, *len);
|
||||
|
||||
} while (process_again);
|
||||
|
||||
if (is_p256) {
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa256_pub_x, pub_x, len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa256_pub_y, pub_y, len);
|
||||
} else {
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa192_pub_x, pub_x, len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa192_pub_y, pub_y, len);
|
||||
}
|
||||
|
||||
ecdsa_disable();
|
||||
}
|
||||
|
||||
void test_ecdsa_export_pubkey(bool is_p256, uint8_t *ecdsa_pub_x, uint8_t *ecdsa_pub_y, bool use_km_key)
|
||||
{
|
||||
uint8_t pub_x[32] = {0};
|
||||
uint8_t pub_y[32] = {0};
|
||||
uint16_t len;
|
||||
test_ecdsa_export_pubkey_inner(is_p256, pub_x, pub_y, use_km_key, &len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa_pub_x, pub_x, len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(ecdsa_pub_y, pub_y, len);
|
||||
|
||||
}
|
||||
#endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */
|
||||
|
||||
|
||||
@ -322,12 +323,12 @@ TEST(ecdsa, ecdsa_SECP256R1_det_sign_and_verify)
|
||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
TEST(ecdsa, ecdsa_SECP192R1_export_pubkey)
|
||||
{
|
||||
test_ecdsa_export_pubkey(0, 0);
|
||||
test_ecdsa_export_pubkey(0, ecdsa192_pub_x, ecdsa192_pub_y, 0);
|
||||
}
|
||||
|
||||
TEST(ecdsa, ecdsa_SECP256R1_export_pubkey)
|
||||
{
|
||||
test_ecdsa_export_pubkey(1, 0);
|
||||
test_ecdsa_export_pubkey(1, ecdsa256_pub_x, ecdsa256_pub_y, 0);
|
||||
}
|
||||
#endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */
|
||||
|
||||
|
@ -0,0 +1,257 @@
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import os
|
||||
import struct
|
||||
from typing import Any
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.ciphers import algorithms
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher
|
||||
from cryptography.hazmat.primitives.ciphers import modes
|
||||
from ecdsa.curves import NIST256p
|
||||
|
||||
# Constants
|
||||
TEST_COUNT = 5
|
||||
|
||||
|
||||
# Helper functions
|
||||
def generate_random_key(size: int = 32) -> bytes:
|
||||
return os.urandom(size)
|
||||
|
||||
|
||||
def save_key_to_file(key: bytes, filename: str) -> None:
|
||||
with open(filename, 'wb') as file:
|
||||
file.write(key)
|
||||
|
||||
|
||||
def key_from_file_or_generate(filename: str, size: int = 32) -> bytes:
|
||||
if not os.path.exists(filename):
|
||||
key = generate_random_key(size)
|
||||
save_key_to_file(key, filename)
|
||||
|
||||
with open(filename, 'rb') as file:
|
||||
return file.read()
|
||||
|
||||
|
||||
def key_to_c_format(key: bytes) -> str:
|
||||
return ', '.join([f'0x{byte:02x}' for byte in key])
|
||||
|
||||
|
||||
def calculate_aes_cipher(data: bytes, key: bytes) -> Any:
|
||||
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
|
||||
encryptor = cipher.encryptor()
|
||||
return encryptor.update(data) + encryptor.finalize()
|
||||
|
||||
|
||||
def _flash_encryption_operation_aes_xts(input_data: bytes, flash_address: int, key: bytes, do_decrypt: bool = False) -> bytes:
|
||||
backend = default_backend()
|
||||
|
||||
indata = input_data
|
||||
|
||||
pad_left = flash_address % 0x80
|
||||
indata = (b'\x00' * pad_left) + indata
|
||||
|
||||
pad_right = (0x80 - (len(indata) % 0x80)) % 0x80
|
||||
indata += (b'\x00' * pad_right)
|
||||
|
||||
inblocks = [indata[i:i + 0x80] for i in range(0, len(indata), 0x80)]
|
||||
|
||||
output = b''
|
||||
for inblock in inblocks:
|
||||
tweak = struct.pack('<I', flash_address & ~0x7F) + (b'\x00' * 12)
|
||||
flash_address += 0x80
|
||||
cipher = Cipher(algorithms.AES(key), modes.XTS(tweak), backend=backend)
|
||||
encryptor = cipher.encryptor() if not do_decrypt else cipher.decryptor()
|
||||
|
||||
outblock = encryptor.update(inblock[::-1])
|
||||
output += outblock[::-1]
|
||||
|
||||
return output[pad_left:len(output) - pad_right]
|
||||
|
||||
|
||||
def generate_xts_test_data(key: bytes, base_flash_address: int = 0x120000) -> list:
|
||||
xts_test_data = []
|
||||
plaintext_data = bytes(range(1, 129))
|
||||
data_size = 16
|
||||
flash_address = base_flash_address
|
||||
for i in range(TEST_COUNT):
|
||||
data_size = (data_size * 2) % 256
|
||||
if (data_size < 16):
|
||||
data_size = 16
|
||||
input_data = plaintext_data[:data_size]
|
||||
flash_address = base_flash_address + (i * 0x100)
|
||||
|
||||
ciphertext = _flash_encryption_operation_aes_xts(input_data, flash_address, key)
|
||||
xts_test_data.append((data_size, flash_address, ciphertext[:data_size]))
|
||||
return xts_test_data
|
||||
|
||||
|
||||
def generate_ecdsa_256_key_and_pub_key(filename: str) -> tuple:
|
||||
with open(filename, 'rb') as f:
|
||||
private_number = int.from_bytes(f.read(), byteorder='big')
|
||||
|
||||
private_key = ec.derive_private_key(private_number, ec.SECP256R1())
|
||||
pem = private_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
)
|
||||
|
||||
with open('ecdsa_256_key.pem', 'wb') as pem_file:
|
||||
pem_file.write(pem)
|
||||
|
||||
public_key = private_key.public_key()
|
||||
pub_numbers = public_key.public_numbers()
|
||||
pubx = pub_numbers.x.to_bytes(32, byteorder='little')
|
||||
puby = pub_numbers.y.to_bytes(32, byteorder='little')
|
||||
|
||||
return pubx, puby
|
||||
|
||||
|
||||
def perform_ecc_point_multiplication(k1_int: int) -> Any:
|
||||
generator = NIST256p.generator.to_affine()
|
||||
k1_G = k1_int * generator
|
||||
return k1_G
|
||||
|
||||
|
||||
def generate_k1_G(key_file_path: str) -> tuple:
|
||||
k1_G = []
|
||||
if os.path.exists(key_file_path):
|
||||
with open(key_file_path, 'rb') as key_file:
|
||||
k1_bytes = key_file.read()
|
||||
|
||||
k1_int = int.from_bytes(k1_bytes, byteorder='big')
|
||||
k1_G_point = perform_ecc_point_multiplication(k1_int)
|
||||
k1_G = k1_G_point.to_bytes()[:64]
|
||||
|
||||
k1_G = k1_G[::-1]
|
||||
k1_G_x = k1_G[:32]
|
||||
k1_G_y = k1_G[32:]
|
||||
k1_G = k1_G_y + k1_G_x
|
||||
|
||||
return k1_G, k1_G
|
||||
|
||||
|
||||
def write_to_c_header(init_key: bytes, k1: bytes, k2_info: bytes, k1_encrypted_32: list,
|
||||
test_data_xts_aes_128: list, k1_encrypted_64: list,
|
||||
xts_test_data_xts_aes_256: list, pubx: bytes,
|
||||
puby: bytes, k1_G_0: bytes, k1_G_1: bytes) -> None:
|
||||
with open('key_manager_test_cases.h', 'w') as file:
|
||||
header_content = """#include <stdint.h>
|
||||
|
||||
#define TEST_COUNT 5
|
||||
|
||||
typedef struct test_xts_data {
|
||||
uint16_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint8_t ciphertext[128];
|
||||
} test_xts_data_t;
|
||||
|
||||
typedef struct test_ecdsa_data {
|
||||
uint8_t pubx[32];
|
||||
uint8_t puby[32];
|
||||
} test_ecdsa_data_t;
|
||||
|
||||
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];
|
||||
test_xts_data_t xts_test_data[TEST_COUNT];
|
||||
test_ecdsa_data_t ecdsa_test_data;
|
||||
} test_data_aes_mode_t;
|
||||
|
||||
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;
|
||||
|
||||
// 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 = {
|
||||
""" % (key_to_c_format(init_key), key_to_c_format(k2_info), key_to_c_format(k1_encrypted_32[0]), key_to_c_format(bytes(range(1, 129))))
|
||||
|
||||
for data_size, flash_address, ciphertext in test_data_xts_aes_128:
|
||||
header_content += f'\t\t{{.data_size = {data_size}, .data_offset = 0x{flash_address:x}, .ciphertext = {{{key_to_c_format(ciphertext)}}}}},\n'
|
||||
header_content += '\t}\n};\n\n'
|
||||
|
||||
# For 64-byte k1 key
|
||||
header_content += '// For 64-byte k1 key\n'
|
||||
header_content += 'test_data_aes_mode_t test_data_xts_aes_256 = {\n'
|
||||
header_content += f'\t.init_key = {{{key_to_c_format(init_key)}}},\n'
|
||||
header_content += f'\t.k2_info = {{{key_to_c_format(k2_info)}}},\n'
|
||||
header_content += f'\t.k1_encrypted = {{{{{key_to_c_format(k1_encrypted_64[0])}}}, {{{key_to_c_format(k1_encrypted_64[1])}}}}},\n'
|
||||
header_content += f'\t.plaintext_data = {{{key_to_c_format(bytes(range(1, 129)))}}},\n'
|
||||
header_content += ' .xts_test_data = {\n'
|
||||
|
||||
for data_size, flash_address, ciphertext in xts_test_data_xts_aes_256:
|
||||
header_content += f' {{.data_size = {data_size}, .data_offset = 0x{flash_address:x}, .ciphertext = {{{key_to_c_format(ciphertext)}}}}},\n'
|
||||
header_content += ' }\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[0]), key_to_c_format(pubx),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))
|
||||
|
||||
file.write(header_content)
|
||||
|
||||
|
||||
# Main script logic follows as per your provided structure
|
||||
init_key = key_from_file_or_generate('init_key.bin', 32)
|
||||
k2 = key_from_file_or_generate('k2.bin', 32)
|
||||
rand_num = key_from_file_or_generate('rand_num.bin', 32)
|
||||
|
||||
temp_result_inner = calculate_aes_cipher(k2, rand_num)
|
||||
temp_result_outer = calculate_aes_cipher(temp_result_inner + rand_num, init_key)
|
||||
k2_info = temp_result_outer
|
||||
|
||||
k1_32 = key_from_file_or_generate('k1.bin', 32)
|
||||
k1_64 = key_from_file_or_generate('k1_64.bin', 64)
|
||||
|
||||
k1_32_reversed = k1_32[::-1]
|
||||
|
||||
k1_64_reversed = k1_64[::-1]
|
||||
|
||||
k1_64_1 = k1_64[:32]
|
||||
k1_64_1_reversed = k1_64_1[::-1]
|
||||
k1_64_2 = k1_64[32:]
|
||||
k1_64_2_reversed = k1_64_2[::-1]
|
||||
|
||||
k1_encrypted_32 = [calculate_aes_cipher(k1_32_reversed, k2)]
|
||||
k1_encrypted_64 = [calculate_aes_cipher(k1_64_1_reversed, k2), calculate_aes_cipher(k1_64_2_reversed, k2)]
|
||||
|
||||
test_data_xts_aes_128 = generate_xts_test_data(k1_32)
|
||||
xts_test_data_xts_aes_256 = generate_xts_test_data(k1_64)
|
||||
|
||||
pubx, puby = generate_ecdsa_256_key_and_pub_key('k1.bin')
|
||||
|
||||
k1_G_0, k1_G_1 = generate_k1_G('k1.bin')
|
||||
|
||||
write_to_c_header(init_key, k1_32, k2_info, k1_encrypted_32, test_data_xts_aes_128, k1_encrypted_64, xts_test_data_xts_aes_256, pubx, puby, k1_G_0, k1_G_1)
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#define TEST_COUNT 5
|
||||
|
||||
typedef struct test_xts_data {
|
||||
uint16_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint8_t ciphertext[128];
|
||||
} test_xts_data_t;
|
||||
|
||||
typedef struct test_ecdsa_data {
|
||||
uint8_t pubx[32];
|
||||
uint8_t puby[32];
|
||||
} test_ecdsa_data_t;
|
||||
|
||||
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];
|
||||
test_xts_data_t xts_test_data[TEST_COUNT];
|
||||
test_ecdsa_data_t ecdsa_test_data;
|
||||
} test_data_aes_mode_t;
|
||||
|
||||
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;
|
||||
|
||||
// For 32-byte k1 key
|
||||
test_data_aes_mode_t test_data_xts_aes_128 = {
|
||||
.init_key = { 0x4d, 0x21, 0x64, 0x21, 0x8f, 0xa2, 0xe3, 0xa0, 0xab, 0x74, 0xb5, 0xab, 0x17, 0x9a, 0x5d, 0x08, 0x58, 0xf4, 0x22, 0x03, 0xbd, 0x52, 0xe7, 0x88, 0x3c, 0x22, 0x0f, 0x95, 0x89, 0x70, 0xe1, 0x93 },
|
||||
.k2_info = { 0xd8, 0xcd, 0x04, 0x45, 0xb4, 0x45, 0xc4, 0x15, 0xf6, 0x40, 0x1c, 0x7d, 0x90, 0x1b, 0x99, 0xa4, 0x79, 0x6b, 0xfb, 0x5b, 0x2a, 0x40, 0x60, 0xe1, 0xc1, 0xe1, 0x48, 0xcd, 0x46, 0x6b, 0x9b, 0x48, 0xda, 0x7a, 0x70, 0x0a, 0x78, 0x0b, 0x9d, 0xf9, 0x0e, 0xed, 0x91, 0xfc, 0xa5, 0xc2, 0x96, 0x05, 0x91, 0x76, 0xdb, 0x68, 0x84, 0x5d, 0x5e, 0x5b, 0xa6, 0xe9, 0x6b, 0x3b, 0x12, 0x50, 0x05, 0xc3 },
|
||||
.k1_encrypted = { { 0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a, 0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48 }, { } },
|
||||
.plaintext_data = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80 },
|
||||
.xts_test_data = {
|
||||
{.data_size = 32, .data_offset = 0x120000, .ciphertext = {0xe7, 0xf3, 0xb4, 0x51, 0xc6, 0x62, 0x8e, 0x25, 0x10, 0x12, 0xc2, 0x09, 0x82, 0x7b, 0x3e, 0x9a, 0x78, 0xe2, 0x00, 0x9a, 0x96, 0x02, 0x50, 0xeb, 0xff, 0xf1, 0xf8, 0x0d, 0xf6, 0xa6, 0xb8, 0xa1}},
|
||||
{.data_size = 64, .data_offset = 0x120100, .ciphertext = {0x3b, 0x54, 0xa8, 0x58, 0xe2, 0x63, 0x7a, 0xb0, 0x7c, 0xc7, 0x37, 0xd8, 0x1e, 0x89, 0x1e, 0x25, 0x39, 0x3d, 0x0d, 0x18, 0x14, 0xb3, 0x2e, 0x18, 0x15, 0xf6, 0xbd, 0xf8, 0xb6, 0x5f, 0x6b, 0x89, 0x1a, 0x0a, 0x53, 0x36, 0xf1, 0x5b, 0x1b, 0x18, 0xd3, 0xf4, 0x7b, 0xd5, 0xcd, 0x4f, 0x48, 0x7b, 0x11, 0xcf, 0xad, 0x6b, 0x79, 0x36, 0x1b, 0xda, 0x5a, 0xd3, 0x18, 0x44, 0xa0, 0xf3, 0xf2, 0xad}},
|
||||
{.data_size = 128, .data_offset = 0x120200, .ciphertext = {0x6b, 0x42, 0x10, 0x9f, 0x67, 0x72, 0x31, 0xc7, 0x8f, 0x63, 0xde, 0xc1, 0xf9, 0x84, 0x37, 0x74, 0xe5, 0x5a, 0xe4, 0x31, 0x1a, 0x2e, 0x45, 0x6b, 0xb5, 0xd4, 0xd0, 0x41, 0xe1, 0x2c, 0x0a, 0x43, 0xd9, 0x4c, 0xd5, 0x1c, 0x34, 0xc9, 0x29, 0x39, 0xc8, 0x09, 0xc3, 0xcd, 0x99, 0xaf, 0x3a, 0xe6, 0x4d, 0xae, 0xce, 0xfd, 0x0a, 0xd4, 0x8f, 0x81, 0x4c, 0x25, 0xc5, 0x5e, 0x3d, 0x82, 0x3d, 0x58, 0x55, 0xe5, 0xa4, 0xe4, 0x13, 0x2b, 0xa0, 0x04, 0x3a, 0x7a, 0x65, 0xfa, 0x7a, 0xfb, 0x28, 0x36, 0x1e, 0xfa, 0x71, 0x50, 0x80, 0xa5, 0x0c, 0xa6, 0x4e, 0x45, 0xf9, 0xd9, 0x05, 0xc1, 0x63, 0xa1, 0xf2, 0x7f, 0x54, 0x62, 0xf1, 0x5a, 0xe2, 0x5a, 0x5c, 0x06, 0x16, 0x71, 0xa9, 0x5f, 0xab, 0x7d, 0xc9, 0x85, 0x68, 0xc5, 0x3a, 0xfe, 0xc1, 0xe0, 0xc9, 0xc3, 0xd4, 0x33, 0x10, 0x89, 0x5e, 0x43}},
|
||||
{.data_size = 16, .data_offset = 0x120300, .ciphertext = {0xbe, 0xd7, 0x01, 0x8a, 0x60, 0xab, 0x0c, 0xb7, 0xb6, 0x14, 0x9e, 0x64, 0xbc, 0xca, 0xda, 0xaa}},
|
||||
{.data_size = 32, .data_offset = 0x120400, .ciphertext = {0xda, 0x84, 0x17, 0x3d, 0x4c, 0x85, 0x07, 0xe2, 0x56, 0x98, 0x69, 0x33, 0x1b, 0x9a, 0x01, 0x9e, 0x6c, 0x81, 0xd8, 0x90, 0x9e, 0x59, 0x92, 0x12, 0x6d, 0xba, 0x58, 0x09, 0x90, 0xe6, 0x50, 0x33}},
|
||||
}
|
||||
};
|
||||
|
||||
// For 64-byte k1 key
|
||||
test_data_aes_mode_t test_data_xts_aes_256 = {
|
||||
.init_key = {0x4d, 0x21, 0x64, 0x21, 0x8f, 0xa2, 0xe3, 0xa0, 0xab, 0x74, 0xb5, 0xab, 0x17, 0x9a, 0x5d, 0x08, 0x58, 0xf4, 0x22, 0x03, 0xbd, 0x52, 0xe7, 0x88, 0x3c, 0x22, 0x0f, 0x95, 0x89, 0x70, 0xe1, 0x93},
|
||||
.k2_info = {0xd8, 0xcd, 0x04, 0x45, 0xb4, 0x45, 0xc4, 0x15, 0xf6, 0x40, 0x1c, 0x7d, 0x90, 0x1b, 0x99, 0xa4, 0x79, 0x6b, 0xfb, 0x5b, 0x2a, 0x40, 0x60, 0xe1, 0xc1, 0xe1, 0x48, 0xcd, 0x46, 0x6b, 0x9b, 0x48, 0xda, 0x7a, 0x70, 0x0a, 0x78, 0x0b, 0x9d, 0xf9, 0x0e, 0xed, 0x91, 0xfc, 0xa5, 0xc2, 0x96, 0x05, 0x91, 0x76, 0xdb, 0x68, 0x84, 0x5d, 0x5e, 0x5b, 0xa6, 0xe9, 0x6b, 0x3b, 0x12, 0x50, 0x05, 0xc3},
|
||||
.k1_encrypted = {{0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a, 0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48}, {0x65, 0x9e, 0x12, 0x7f, 0xc0, 0x4a, 0xb6, 0x04, 0xa1, 0xd0, 0x38, 0x04, 0x6c, 0x8e, 0x1f, 0xc7, 0x03, 0x24, 0x3e, 0x75, 0x3c, 0x9d, 0x7a, 0xc2, 0xef, 0xd6, 0xf2, 0x60, 0x46, 0xfc, 0x07, 0x3f}},
|
||||
.plaintext_data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80},
|
||||
.xts_test_data = {
|
||||
{.data_size = 32, .data_offset = 0x120000, .ciphertext = {0x9b, 0xd8, 0x2b, 0xc6, 0xae, 0xcc, 0x9d, 0x0c, 0x38, 0x30, 0x85, 0x6a, 0x2b, 0x22, 0x2e, 0x34, 0x9f, 0xa2, 0xcd, 0xe8, 0xec, 0xe3, 0xc4, 0x21, 0xfe, 0xbb, 0x4a, 0x55, 0xf2, 0x4a, 0xe2, 0x14}},
|
||||
{.data_size = 64, .data_offset = 0x120100, .ciphertext = {0x1e, 0x36, 0x3f, 0xf6, 0xd6, 0x52, 0x34, 0xce, 0xc3, 0x58, 0x15, 0xa1, 0x15, 0x6f, 0x3d, 0x66, 0xa7, 0x90, 0x14, 0x71, 0xbb, 0x6d, 0x7e, 0x93, 0xf2, 0x4d, 0x5d, 0x74, 0xb2, 0xd7, 0x77, 0x32, 0x2e, 0x31, 0x16, 0x28, 0xd2, 0x10, 0x65, 0x81, 0x49, 0xc0, 0x56, 0xf0, 0x6d, 0x71, 0x5b, 0xc2, 0xf2, 0x01, 0x04, 0xbf, 0x97, 0x77, 0xe6, 0x57, 0xe5, 0xb5, 0xad, 0x73, 0xc0, 0x76, 0x91, 0xb6}},
|
||||
{.data_size = 128, .data_offset = 0x120200, .ciphertext = {0xcf, 0x7d, 0xdd, 0x69, 0x69, 0xf4, 0x3b, 0xcd, 0x65, 0x5d, 0xcf, 0xfc, 0xff, 0xd3, 0x45, 0x1c, 0x51, 0xab, 0x2e, 0x26, 0x5c, 0xdc, 0x5b, 0x5a, 0x6e, 0xbb, 0x18, 0x36, 0x55, 0xbe, 0xe7, 0x30, 0x7a, 0x07, 0x48, 0xd8, 0x1a, 0x34, 0xdc, 0xa6, 0x1e, 0xd6, 0x67, 0xa8, 0x90, 0xc3, 0xac, 0x26, 0x7a, 0x52, 0x67, 0x82, 0x71, 0xc9, 0x80, 0x8d, 0xed, 0x20, 0x83, 0x34, 0x10, 0x8e, 0xe5, 0x84, 0x81, 0xa5, 0xe2, 0x42, 0xf0, 0x53, 0xef, 0x93, 0x00, 0xfe, 0xbd, 0x74, 0x14, 0xac, 0x92, 0x37, 0x00, 0x45, 0xd5, 0x71, 0x29, 0xaf, 0x8b, 0x83, 0xe2, 0x20, 0x2e, 0xd0, 0xf6, 0xaa, 0x45, 0x9a, 0x6f, 0x59, 0xb9, 0x8d, 0xef, 0xcd, 0xb6, 0xf6, 0x25, 0x99, 0xd2, 0x32, 0x2e, 0x90, 0x8a, 0x3a, 0x5d, 0xd8, 0x3f, 0xbf, 0x84, 0x80, 0x89, 0xaa, 0x9c, 0xa8, 0x57, 0xc9, 0x1c, 0xc4, 0xaa, 0x64}},
|
||||
{.data_size = 16, .data_offset = 0x120300, .ciphertext = {0x1b, 0x7a, 0xf1, 0x35, 0x33, 0x22, 0x64, 0x74, 0x06, 0x6a, 0xc1, 0x0c, 0x39, 0xee, 0x1f, 0x9f}},
|
||||
{.data_size = 32, .data_offset = 0x120400, .ciphertext = {0x94, 0xd9, 0x01, 0x0f, 0xec, 0xcc, 0xb5, 0x22, 0x50, 0x8b, 0x8a, 0x3d, 0x01, 0x18, 0x29, 0xda, 0x53, 0x9b, 0xcf, 0x64, 0xac, 0x4f, 0x7b, 0x97, 0xf3, 0xff, 0xfd, 0x33, 0x96, 0x8a, 0xde, 0x27}},
|
||||
}
|
||||
};
|
||||
|
||||
test_data_aes_mode_t test_data_ecdsa = {
|
||||
.init_key = { 0x4d, 0x21, 0x64, 0x21, 0x8f, 0xa2, 0xe3, 0xa0, 0xab, 0x74, 0xb5, 0xab, 0x17, 0x9a, 0x5d, 0x08, 0x58, 0xf4, 0x22, 0x03, 0xbd, 0x52, 0xe7, 0x88, 0x3c, 0x22, 0x0f, 0x95, 0x89, 0x70, 0xe1, 0x93 },
|
||||
.k2_info = { 0xd8, 0xcd, 0x04, 0x45, 0xb4, 0x45, 0xc4, 0x15, 0xf6, 0x40, 0x1c, 0x7d, 0x90, 0x1b, 0x99, 0xa4, 0x79, 0x6b, 0xfb, 0x5b, 0x2a, 0x40, 0x60, 0xe1, 0xc1, 0xe1, 0x48, 0xcd, 0x46, 0x6b, 0x9b, 0x48, 0xda, 0x7a, 0x70, 0x0a, 0x78, 0x0b, 0x9d, 0xf9, 0x0e, 0xed, 0x91, 0xfc, 0xa5, 0xc2, 0x96, 0x05, 0x91, 0x76, 0xdb, 0x68, 0x84, 0x5d, 0x5e, 0x5b, 0xa6, 0xe9, 0x6b, 0x3b, 0x12, 0x50, 0x05, 0xc3 },
|
||||
.k1_encrypted = { { 0xeb, 0x83, 0x24, 0x7d, 0xf8, 0x40, 0xc9, 0x88, 0x5f, 0x5e, 0x58, 0x57, 0x25, 0xa9, 0x23, 0x4a, 0xa4, 0xc4, 0x12, 0x17, 0xf3, 0x9e, 0x1f, 0xa0, 0xa0, 0xfa, 0xd5, 0xbf, 0xb6, 0x6c, 0xb5, 0x48 }, { } },
|
||||
.ecdsa_test_data = {
|
||||
.pubx = { 0x8f, 0xc2, 0x37, 0x2e, 0x36, 0x77, 0x8f, 0xc7, 0x59, 0x18, 0xec, 0x39, 0x23, 0x16, 0x6b, 0x0b, 0x4f, 0xf8, 0x19, 0xa8, 0x9f, 0xd9, 0xf7, 0x59, 0x4d, 0x8a, 0x2d, 0x16, 0xd5, 0x84, 0xe1, 0x21 },
|
||||
.puby = { 0xf1, 0x8b, 0x1e, 0x2d, 0x7e, 0xc4, 0x8b, 0xf8, 0xe3, 0xc9, 0xb1, 0x54, 0xa4, 0x65, 0xed, 0x7d, 0xbc, 0x56, 0x1a, 0x66, 0xcd, 0x43, 0x10, 0x2e, 0x46, 0x2a, 0x3f, 0xfe, 0xdb, 0x9a, 0x28, 0xf9 }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
test_data_ecdh0_mode_t test_data_ecdh0 = {
|
||||
.plaintext_data = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80 },
|
||||
.k1 = {
|
||||
{ 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 },
|
||||
{ 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 },
|
||||
},
|
||||
.k1_G = {
|
||||
{ 0x8f, 0xc2, 0x37, 0x2e, 0x36, 0x77, 0x8f, 0xc7, 0x59, 0x18, 0xec, 0x39, 0x23, 0x16, 0x6b, 0x0b, 0x4f, 0xf8, 0x19, 0xa8, 0x9f, 0xd9, 0xf7, 0x59, 0x4d, 0x8a, 0x2d, 0x16, 0xd5, 0x84, 0xe1, 0x21, 0xf1, 0x8b, 0x1e, 0x2d, 0x7e, 0xc4, 0x8b, 0xf8, 0xe3, 0xc9, 0xb1, 0x54, 0xa4, 0x65, 0xed, 0x7d, 0xbc, 0x56, 0x1a, 0x66, 0xcd, 0x43, 0x10, 0x2e, 0x46, 0x2a, 0x3f, 0xfe, 0xdb, 0x9a, 0x28, 0xf9 },
|
||||
{ 0x8f, 0xc2, 0x37, 0x2e, 0x36, 0x77, 0x8f, 0xc7, 0x59, 0x18, 0xec, 0x39, 0x23, 0x16, 0x6b, 0x0b, 0x4f, 0xf8, 0x19, 0xa8, 0x9f, 0xd9, 0xf7, 0x59, 0x4d, 0x8a, 0x2d, 0x16, 0xd5, 0x84, 0xe1, 0x21, 0xf1, 0x8b, 0x1e, 0x2d, 0x7e, 0xc4, 0x8b, 0xf8, 0xe3, 0xc9, 0xb1, 0x54, 0xa4, 0x65, 0xed, 0x7d, 0xbc, 0x56, 0x1a, 0x66, 0xcd, 0x43, 0x10, 0x2e, 0x46, 0x2a, 0x3f, 0xfe, 0xdb, 0x9a, 0x28, 0xf9 },
|
||||
}
|
||||
};
|
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_efuse_chip.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_rom_crc.h"
|
||||
#include "hal/key_mgr_hal.h"
|
||||
#include "hal/key_mgr_ll.h"
|
||||
#include "hal/key_mgr_types.h"
|
||||
#include "hal/huk_types.h"
|
||||
#include "hal/huk_hal.h"
|
||||
#include "esp_key_mgr.h"
|
||||
#include "memory_checks.h"
|
||||
#include "unity_fixture.h"
|
||||
#include "hal_crypto_common.h"
|
||||
#include "rom/key_mgr.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_flash.h"
|
||||
#include "key_manager_test_cases.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
// For ECDSA tests
|
||||
#include "hal/ecdsa_hal.h"
|
||||
|
||||
const esp_partition_t *get_test_storage_partition(void)
|
||||
{
|
||||
/* This finds "storage" partition defined partition table */
|
||||
const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
|
||||
ESP_PARTITION_SUBTYPE_ANY, "storage");
|
||||
if (!result) {
|
||||
/* means partition table set wrong */
|
||||
printf("ERROR in obtaining storage partition");
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void print_data_in_hex(const uint8_t *data, int size, const char *info_str)
|
||||
{
|
||||
printf("%s: 0x", info_str);
|
||||
for(int i = 0 ; i < size; i++) {
|
||||
printf("%02x", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void test_xts_aes_key_aes_mode(test_data_aes_mode_t *test_data)
|
||||
{
|
||||
const esp_partition_t *partition = get_test_storage_partition();
|
||||
ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size));
|
||||
|
||||
for (int i = 0; i < TEST_COUNT; i++) {
|
||||
uint32_t address = test_data->xts_test_data[i].data_offset;
|
||||
uint32_t data_size = test_data->xts_test_data[i].data_size;
|
||||
ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, test_data->plaintext_data, data_size));
|
||||
static uint8_t read_data[128];
|
||||
ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, address, data_size));
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test_data->xts_test_data[i].ciphertext, read_data, data_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_xts_aes_key_ecdh0_mode(test_data_ecdh0_mode_t *test_data)
|
||||
{
|
||||
const esp_partition_t *partition = get_test_storage_partition();
|
||||
ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size));
|
||||
|
||||
uint32_t address = partition->address;
|
||||
uint32_t data_size = 32;
|
||||
|
||||
print_data_in_hex(test_data->plaintext_data, data_size, "Plaintext data");
|
||||
|
||||
ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, address, test_data->plaintext_data, data_size));
|
||||
static uint8_t read_data[128];
|
||||
ESP_ERROR_CHECK(esp_flash_read(NULL, read_data, address, data_size));
|
||||
print_data_in_hex(read_data, data_size, "Encrypted data");
|
||||
}
|
||||
|
||||
static void key_mgr_test_xts_aes_128(void)
|
||||
{
|
||||
static esp_key_mgr_aes_key_config_t key_config;
|
||||
memcpy(key_config.k2_info, (uint8_t*) test_data_xts_aes_128.k2_info, KEY_MGR_K2_INFO_SIZE);
|
||||
memcpy(key_config.k1_encrypted, (uint8_t*) test_data_xts_aes_128.k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE);
|
||||
memcpy(key_config.sw_init_key, (uint8_t*) test_data_xts_aes_128.init_key, KEY_MGR_SW_INIT_KEY_SIZE);
|
||||
key_config.use_pre_generated_sw_init_key = 1;
|
||||
key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_aes_mode(&key_config, &key_recovery_info));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
test_xts_aes_key_aes_mode(&test_data_xts_aes_128);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
|
||||
}
|
||||
|
||||
static void key_mgr_test_xts_aes_256_aes_mode(void)
|
||||
{
|
||||
static esp_key_mgr_aes_key_config_t key_config;
|
||||
memcpy(key_config.k2_info, (uint8_t*) test_data_xts_aes_256.k2_info, KEY_MGR_K2_INFO_SIZE);
|
||||
memcpy(key_config.k1_encrypted[0], (uint8_t*) test_data_xts_aes_256.k1_encrypted[0], KEY_MGR_K1_ENCRYPTED_SIZE);
|
||||
memcpy(key_config.k1_encrypted[1], (uint8_t*) test_data_xts_aes_256.k1_encrypted[1], KEY_MGR_K1_ENCRYPTED_SIZE);
|
||||
memcpy(key_config.sw_init_key, (uint8_t*) test_data_xts_aes_256.init_key, KEY_MGR_SW_INIT_KEY_SIZE);
|
||||
key_config.use_pre_generated_sw_init_key = 1;
|
||||
key_config.key_type = ESP_KEY_MGR_XTS_AES_256_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_aes_mode(&key_config, &key_recovery_info));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
test_xts_aes_key_aes_mode(&test_data_xts_aes_256);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
}
|
||||
|
||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
extern void test_ecdsa_export_pubkey(bool is_p256, uint8_t *ecdsa_pub_x, uint8_t *ecdsa_pub_y, bool use_km_key);
|
||||
extern void test_ecdsa_export_pubkey_inner(bool is_p256, uint8_t *exported_pub_x, uint8_t *exported_pub_y, bool use_km_key, uint16_t *len);
|
||||
#endif
|
||||
|
||||
extern void test_ecdsa_sign_and_verify(bool is_p256, uint8_t* sha, uint8_t* pub_x, uint8_t* pub_y, bool use_km_key, ecdsa_sign_type_t k_type);
|
||||
|
||||
/*
|
||||
const uint8_t message[32] = { 0xDF, 0xDE, 0xD7, 0x4A, 0x47, 0xB1, 0x4F, 0x73, 0x00, 0x21, 0x62, 0xC7, 0x66, 0x6D, 0xA3, 0x95, 0x66, 0x19, 0x62, 0x7F, 0x71, 0x7B, 0x3C, 0x66, 0x82, 0xD3, 0x9F, 0x71, 0xAC, 0x9C, 0xC3, 0x39 };
|
||||
*/
|
||||
|
||||
/* sha256 digest of the above message */
|
||||
uint8_t sha256_digest[32] = { 0x47, 0xA6, 0xEF, 0xBE, 0x39, 0x5E, 0xE4, 0xAE, 0x2B, 0xEC, 0x83, 0xB1, 0xED, 0xAF, 0xC6, 0x78, 0x57, 0x7A, 0x16, 0x8C, 0x22, 0x16, 0x13, 0xE2, 0xAC, 0xA8, 0x50, 0xD5, 0x67, 0x95, 0x9F, 0x71 };
|
||||
|
||||
void test_ecdsa_key_aes_mode(test_data_aes_mode_t *ecdsa_test_data, ecdsa_sign_type_t k_type)
|
||||
{
|
||||
test_ecdsa_sign_and_verify(1, sha256_digest, ecdsa_test_data->ecdsa_test_data.pubx, ecdsa_test_data->ecdsa_test_data.puby, 1, k_type);
|
||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||
test_ecdsa_export_pubkey(1, ecdsa_test_data->ecdsa_test_data.pubx, ecdsa_test_data->ecdsa_test_data.puby, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, bool use_km_key, ecdsa_sign_type_t k_type);
|
||||
|
||||
extern int test_ecdsa_verify(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, uint8_t *pub_x, uint8_t *pub_y);
|
||||
|
||||
void key_mgr_test_ecdsa_key(bool is_p256, ecdsa_sign_type_t k_type)
|
||||
{
|
||||
uint8_t pub_x[32] = {};
|
||||
uint8_t pub_y[32] = {};
|
||||
uint8_t r_le[32] = {0};
|
||||
uint8_t s_le[32] = {0};
|
||||
|
||||
test_ecdsa_sign(is_p256, sha256_digest, r_le, s_le, 1, k_type);
|
||||
|
||||
print_data_in_hex(sha256_digest, sizeof(sha256_digest), "ECDSA message sha256 digest");
|
||||
print_data_in_hex(r_le, sizeof(r_le), "ECDSA signature r_le");
|
||||
print_data_in_hex(s_le, sizeof(s_le), "ECDSA signature s_le");
|
||||
|
||||
// Export the pubkey from ECDSA peripheral
|
||||
uint16_t pubkey_len = 0;
|
||||
test_ecdsa_export_pubkey_inner(is_p256, pub_x, pub_y, 1, &pubkey_len);
|
||||
|
||||
print_data_in_hex(pub_x, pubkey_len, "ECDSA key pubx");
|
||||
print_data_in_hex(pub_y, pubkey_len, "ECDSA key puby");
|
||||
TEST_ASSERT_EQUAL(0, test_ecdsa_verify(is_p256, sha256_digest, r_le, s_le, pub_x, pub_y));
|
||||
|
||||
}
|
||||
|
||||
static void key_mgr_test_ecdsa_p256_aes_mode(void)
|
||||
{
|
||||
static esp_key_mgr_aes_key_config_t key_config;
|
||||
memcpy(key_config.k2_info, (uint8_t*) test_data_ecdsa.k2_info, KEY_MGR_K2_INFO_SIZE);
|
||||
memcpy(key_config.k1_encrypted, (uint8_t*) test_data_ecdsa.k1_encrypted, KEY_MGR_K1_ENCRYPTED_SIZE);
|
||||
memcpy(key_config.sw_init_key, (uint8_t*) test_data_ecdsa.init_key, KEY_MGR_SW_INIT_KEY_SIZE);
|
||||
key_config.use_pre_generated_sw_init_key = 1;
|
||||
key_config.key_type = ESP_KEY_MGR_ECDSA_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_aes_mode(&key_config, &key_recovery_info));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE
|
||||
test_ecdsa_key_aes_mode(&test_data_ecdsa, ECDSA_K_TYPE_DETERMINISITIC);
|
||||
#endif
|
||||
test_ecdsa_key_aes_mode(&test_data_ecdsa, ECDSA_K_TYPE_TRNG);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
}
|
||||
|
||||
static void key_mgr_test_xts_aes_128_ecdh0_mode(void)
|
||||
{
|
||||
printf("\nKey Manager ECDH0 deployment: XTS_AES_128 key\n");
|
||||
static esp_key_mgr_ecdh0_key_config_t key_config;
|
||||
memcpy(key_config.k1_G[0], (uint8_t*) test_data_ecdh0.k1_G[0], KEY_MGR_ECDH0_INFO_SIZE);
|
||||
key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
static esp_key_mgr_ecdh0_info_t ecdh0_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_ecdh0_mode(&key_config, &key_recovery_info, &ecdh0_info));
|
||||
|
||||
print_data_in_hex(ecdh0_info.k2_G[0], KEY_MGR_ECDH0_INFO_SIZE, "K2_G");
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
test_xts_aes_key_ecdh0_mode(&test_data_ecdh0);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
}
|
||||
|
||||
static void key_mgr_test_xts_aes_256_ecdh0_mode(void)
|
||||
{
|
||||
printf("\nKey Manager ECDH0 deployment: XTS_AES_256 key\n");
|
||||
static esp_key_mgr_ecdh0_key_config_t key_config;
|
||||
memcpy(key_config.k1_G[0], (uint8_t*) test_data_ecdh0.k1_G[0], KEY_MGR_ECDH0_INFO_SIZE);
|
||||
memcpy(key_config.k1_G[1], (uint8_t*) test_data_ecdh0.k1_G[1], KEY_MGR_ECDH0_INFO_SIZE);
|
||||
key_config.key_type = ESP_KEY_MGR_XTS_AES_256_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
static esp_key_mgr_ecdh0_info_t ecdh0_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_ecdh0_mode(&key_config, &key_recovery_info, &ecdh0_info));
|
||||
|
||||
print_data_in_hex(ecdh0_info.k2_G[0], KEY_MGR_ECDH0_INFO_SIZE, "K2_G_0");
|
||||
print_data_in_hex(ecdh0_info.k2_G[1], KEY_MGR_ECDH0_INFO_SIZE, "K2_G_1");
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
test_xts_aes_key_ecdh0_mode(&test_data_ecdh0);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
}
|
||||
|
||||
static void key_mgr_test_ecdsa_ecdh0_mode(void)
|
||||
{
|
||||
printf("\nKey Manager ECDH0 deployment: ECDSA_256 key\n");
|
||||
static esp_key_mgr_ecdh0_key_config_t key_config;
|
||||
memcpy(key_config.k1_G[0], (uint8_t*) test_data_ecdh0.k1_G[0], KEY_MGR_ECDH0_INFO_SIZE);
|
||||
key_config.key_type = ESP_KEY_MGR_ECDSA_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
static esp_key_mgr_ecdh0_info_t ecdh0_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_ecdh0_mode(&key_config, &key_recovery_info, &ecdh0_info));
|
||||
|
||||
print_data_in_hex(ecdh0_info.k2_G[0], KEY_MGR_ECDH0_INFO_SIZE, "K2_G");
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE
|
||||
key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_DETERMINISITIC);
|
||||
#endif
|
||||
key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_TRNG);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
}
|
||||
|
||||
static void key_mgr_test_ecdsa_random_mode(void)
|
||||
{
|
||||
printf("\nKey Manager Random deployment: ECDSA_256 key\n");
|
||||
static esp_key_mgr_random_key_config_t key_config;
|
||||
key_config.key_type = ESP_KEY_MGR_ECDSA_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_recovery_info));
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
|
||||
#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE
|
||||
key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_DETERMINISITIC);
|
||||
#endif
|
||||
key_mgr_test_ecdsa_key(1, ECDSA_K_TYPE_TRNG);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
|
||||
static void test_xts_aes_key_random_mode(void)
|
||||
{
|
||||
const esp_partition_t *partition = get_test_storage_partition();
|
||||
ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size));
|
||||
uint8_t plaintext_data[1024] = {[0 ... 1023] = 0xBE};
|
||||
const int write_size = 16;
|
||||
for (int i = 0; i < sizeof(plaintext_data) / write_size; i++) {
|
||||
printf("\n i = %d\n", i);
|
||||
ESP_ERROR_CHECK(esp_flash_write_encrypted(NULL, partition->address + (i * write_size), plaintext_data, write_size));
|
||||
static uint8_t read_data[128];
|
||||
ESP_ERROR_CHECK(esp_partition_read(partition, write_size * i, read_data, write_size));
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext_data + (i * write_size), read_data, write_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void key_mgr_test_xts_aes_128_random_mode(void)
|
||||
{
|
||||
static esp_key_mgr_random_key_config_t key_config;
|
||||
key_config.key_type = ESP_KEY_MGR_XTS_AES_128_KEY;
|
||||
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_recovery_info));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
test_xts_aes_key_random_mode();
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
|
||||
}
|
||||
|
||||
static void key_mgr_test_xts_aes_256_random_mode(void)
|
||||
{
|
||||
static esp_key_mgr_random_key_config_t key_config;
|
||||
key_config.key_type = ESP_KEY_MGR_XTS_AES_256_KEY;
|
||||
static esp_key_mgr_key_recovery_info_t key_recovery_info;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deploy_key_in_random_mode(&key_config, &key_recovery_info));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_activate_key(&key_recovery_info));
|
||||
test_xts_aes_key_random_mode();
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_key_mgr_deactivate_key(key_recovery_info.key_type));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_GROUP(key_manager);
|
||||
|
||||
TEST_SETUP(key_manager)
|
||||
{
|
||||
test_utils_record_free_mem();
|
||||
TEST_ESP_OK(test_utils_set_leak_level(700, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(key_manager)
|
||||
{
|
||||
test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL),
|
||||
test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL));
|
||||
}
|
||||
|
||||
TEST(key_manager, xts_aes_128_key_aes_deployment)
|
||||
{
|
||||
key_mgr_test_xts_aes_128();
|
||||
}
|
||||
|
||||
TEST(key_manager, xts_aes_256_key_aes_deployment)
|
||||
{
|
||||
key_mgr_test_xts_aes_256_aes_mode();
|
||||
}
|
||||
|
||||
TEST(key_manager, ecdsa_key_aes_deployment)
|
||||
{
|
||||
key_mgr_test_ecdsa_p256_aes_mode();
|
||||
}
|
||||
|
||||
TEST(key_manager, xts_key_ecdh0_deployment)
|
||||
{
|
||||
key_mgr_test_xts_aes_128_ecdh0_mode();
|
||||
key_mgr_test_xts_aes_256_ecdh0_mode();
|
||||
}
|
||||
|
||||
TEST(key_manager, ecdsa_key_ecdh0_deployment)
|
||||
{
|
||||
key_mgr_test_ecdsa_ecdh0_mode();
|
||||
}
|
||||
|
||||
TEST(key_manager, ecdsa_key_random_deployment)
|
||||
{
|
||||
key_mgr_test_ecdsa_random_mode();
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
TEST(key_manager, xts_key_random_deployment)
|
||||
{
|
||||
key_mgr_test_xts_aes_128_random_mode();
|
||||
key_mgr_test_xts_aes_256_random_mode();
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_GROUP_RUNNER(key_manager)
|
||||
{
|
||||
RUN_TEST_CASE(key_manager, xts_aes_128_key_aes_deployment);
|
||||
RUN_TEST_CASE(key_manager, xts_aes_256_key_aes_deployment);
|
||||
RUN_TEST_CASE(key_manager, ecdsa_key_aes_deployment);
|
||||
RUN_TEST_CASE(key_manager, xts_key_ecdh0_deployment);
|
||||
RUN_TEST_CASE(key_manager, ecdsa_key_ecdh0_deployment);
|
||||
RUN_TEST_CASE(key_manager, ecdsa_key_random_deployment);
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
RUN_TEST_CASE(key_manager, xts_key_random_deployment);
|
||||
#endif
|
||||
|
||||
}
|
@ -1,17 +1,153 @@
|
||||
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import binascii
|
||||
import os
|
||||
import subprocess
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from cryptography import exceptions
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.asymmetric import utils
|
||||
from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1
|
||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||
from ecdsa import NIST256p
|
||||
from ecdsa.ellipticcurve import Point
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
def load_ecdsa_key(filename: str) -> SECP256R1:
|
||||
with open(filename, 'rb') as key_file:
|
||||
return load_pem_private_key(key_file.read(), password=None, backend=default_backend())
|
||||
|
||||
|
||||
def test_xts_aes_encryption(negotiated_key: bytes, plaintext_data: bytes, encrypted_data: bytes) -> None:
|
||||
with open('test/negotiated_key.bin', 'wb+') as key_file:
|
||||
key_file.write(negotiated_key)
|
||||
|
||||
with open('test/plaintext.bin', 'wb+') as plaintext_file:
|
||||
plaintext_file.write(plaintext_data)
|
||||
|
||||
command = [
|
||||
'espsecure.py',
|
||||
'encrypt_flash_data',
|
||||
'--aes_xts',
|
||||
'--keyfile', 'test/negotiated_key.bin',
|
||||
'--address', '0x120000',
|
||||
'--output', 'test/enc-data.bin',
|
||||
'test/plaintext.bin'
|
||||
]
|
||||
result = subprocess.run(command, capture_output=True, text=True)
|
||||
assert result.returncode == 0, f'Command failed with error: {result.stderr}'
|
||||
|
||||
with open('test/enc-data.bin', 'rb') as enc_file:
|
||||
calculated_enc_data = enc_file.read()
|
||||
|
||||
assert calculated_enc_data == encrypted_data, 'Calculated data does not match encrypted data obtained from firmware'
|
||||
|
||||
|
||||
def calculate_key_manager_ecdh0_negotiated_key(k2_G_hex: str, k1_ecdsa_key: str) -> Any:
|
||||
k2_G_bytes_le = binascii.unhexlify(k2_G_hex)
|
||||
|
||||
k2_G_bytes_x_be = bytes(reversed(k2_G_bytes_le[:32]))
|
||||
k2_G_bytes_y_be = bytes(reversed(k2_G_bytes_le[32:]))
|
||||
|
||||
k2_G_bytes_be = k2_G_bytes_x_be + k2_G_bytes_y_be
|
||||
|
||||
curve = NIST256p.curve
|
||||
k2_G = Point.from_bytes(curve, k2_G_bytes_be)
|
||||
|
||||
# Load the ECDSA private key (k1)
|
||||
k1_key = load_ecdsa_key(k1_ecdsa_key)
|
||||
k1_int = k1_key.private_numbers().private_value
|
||||
|
||||
# Convert the integer to bytes in big endian format
|
||||
k1_bytes_big_endian = k1_int.to_bytes((k1_int.bit_length() + 7) // 8, byteorder='big')
|
||||
|
||||
# Reverse the bytes to get little endian format
|
||||
k1_bytes_little_endian = k1_bytes_big_endian[::-1]
|
||||
|
||||
k1_int = int.from_bytes(k1_bytes_little_endian, byteorder='little')
|
||||
|
||||
# Calculate k1*k2*G
|
||||
k1_k2_G = k1_int * k2_G
|
||||
|
||||
# Extract the x-coordinate of the result and save it as the shared secret
|
||||
negotiated_key = k1_k2_G.to_bytes()[:32]
|
||||
return negotiated_key
|
||||
|
||||
|
||||
def test_ecdsa_key(negotiated_key: bytes, digest: bytes, signature_r_le: bytes, signature_s_le: bytes, pubx: bytes, puby: bytes) -> None:
|
||||
r = int.from_bytes(signature_r_le, 'little')
|
||||
s = int.from_bytes(signature_s_le, 'little')
|
||||
signature = utils.encode_dss_signature(r, s)
|
||||
pubx_int = int.from_bytes(pubx, 'little')
|
||||
puby_int = int.from_bytes(puby, 'little')
|
||||
private_number = int.from_bytes(negotiated_key, byteorder='big')
|
||||
ecdsa_private_key = ec.derive_private_key(private_number, ec.SECP256R1())
|
||||
# Get the public key
|
||||
public_key = ecdsa_private_key.public_key()
|
||||
# Extract the pubx and puby values
|
||||
calc_pubx, calc_puby = public_key.public_numbers().x, public_key.public_numbers().y
|
||||
|
||||
assert calc_pubx == pubx_int, 'Public key calculated should match with public key obtained'
|
||||
assert calc_puby == puby_int, 'Public key calculated should match with public key obtained'
|
||||
|
||||
try:
|
||||
public_key.verify(signature, digest, ec.ECDSA(utils.Prehashed(hashes.SHA256())))
|
||||
print('Valid signature')
|
||||
except exceptions.InvalidSignature:
|
||||
print('Invalid signature')
|
||||
raise
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.generic
|
||||
def test_crypto(dut: Dut) -> None:
|
||||
# if the env variable IDF_FPGA_ENV is set, we would need a longer timeout
|
||||
# as tests for efuses burning security peripherals would be run
|
||||
timeout = 600 if os.environ.get('IDF_ENV_FPGA') else 60
|
||||
# only expect key manager result if it is supported for the SoC
|
||||
if dut.app.sdkconfig.get('SOC_KEY_MANAGER_SUPPORTED'):
|
||||
print('Key Manager is supported')
|
||||
|
||||
# Test for ECDH0 deployment XTS-AES-128 key
|
||||
dut.expect('Key Manager ECDH0 deployment: XTS_AES_128 key', timeout=timeout)
|
||||
k2_G = dut.expect(r'K2_G: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
plaintext_data = dut.expect(r'Plaintext data: 0x([0-9a-fA-F]+)', timeout=timeout)[1]
|
||||
plaintext_data = binascii.unhexlify(plaintext_data)
|
||||
encrypted_data = dut.expect(r'Encrypted data: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
encrypted_data = binascii.unhexlify(encrypted_data)
|
||||
negotiated_key = calculate_key_manager_ecdh0_negotiated_key(k2_G, 'main/key_manager/k1_ecdsa.pem')
|
||||
test_xts_aes_encryption(negotiated_key, plaintext_data, encrypted_data)
|
||||
|
||||
# Test for ECDH0 deployment XTS-AES-256 key
|
||||
dut.expect('Key Manager ECDH0 deployment: XTS_AES_256 key', timeout=timeout)
|
||||
k2_G_0 = dut.expect(r'K2_G_0: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
k2_G_1 = dut.expect(r'K2_G_1: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
encrypted_data = dut.expect(r'Encrypted data: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
encrypted_data = binascii.unhexlify(encrypted_data)
|
||||
negotiated_key_0 = calculate_key_manager_ecdh0_negotiated_key(k2_G_0, 'main/key_manager/k1_ecdsa.pem')
|
||||
negotiated_key_1 = calculate_key_manager_ecdh0_negotiated_key(k2_G_1, 'main/key_manager/k1_ecdsa.pem')
|
||||
negotiated_key = negotiated_key_0 + negotiated_key_1
|
||||
test_xts_aes_encryption(negotiated_key, plaintext_data, encrypted_data)
|
||||
# Test for ECDH0 deployment ECDSA-256 key
|
||||
dut.expect('Key Manager ECDH0 deployment: ECDSA_256 key', timeout=timeout)
|
||||
k2_G = dut.expect(r'K2_G: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
digest = dut.expect(r'ECDSA message sha256 digest: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
digest = binascii.unhexlify(digest)
|
||||
signature_r_le = dut.expect(r'ECDSA signature r_le: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
signature_r_le = binascii.unhexlify(signature_r_le)
|
||||
signature_s_le = dut.expect(r'ECDSA signature s_le: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
signature_s_le = binascii.unhexlify(signature_s_le)
|
||||
pub_x = dut.expect(r'ECDSA key pubx: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
pub_x = binascii.unhexlify(pub_x)
|
||||
pub_y = dut.expect(r'ECDSA key puby: 0x([0-9a-fA-F]+)', timeout=timeout)[1].decode()
|
||||
pub_y = binascii.unhexlify(pub_y)
|
||||
negotiated_key = calculate_key_manager_ecdh0_negotiated_key(k2_G, 'main/key_manager/k1_ecdsa.pem')
|
||||
test_ecdsa_key(negotiated_key, digest, signature_r_le, signature_s_le, pub_x, pub_y)
|
||||
|
||||
test_numbers = dut.expect(r'(\d+) Tests (\d+) Failures (\d+) Ignored', timeout=timeout)
|
||||
failures = test_numbers.group(2).decode()
|
||||
|
Loading…
x
Reference in New Issue
Block a user