mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat: update mbedTLS test apps to PSA APIs
This commit is contained in:
committed by
Mahavir Jain
parent
1d7c30c533
commit
45966c2009
@@ -16,7 +16,7 @@
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 900
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
|
||||
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 13500
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 15500
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 650000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 36000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 960000
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 1000
|
||||
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
|
||||
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 18000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 23000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 700000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 45000
|
||||
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 1300000
|
||||
|
||||
@@ -3,8 +3,13 @@ set(TEST_CRTS "crts/server_cert_chain.pem"
|
||||
"crts/server_cert_bundle"
|
||||
"crts/bad_md_crt.pem"
|
||||
"crts/wrong_sig_crt_esp32_com.pem"
|
||||
"crts/correct_sig_crt_esp32_com.pem")
|
||||
idf_component_register(SRC_DIRS "."
|
||||
"crts/correct_sig_crt_esp32_com.pem"
|
||||
"crts/ecdsa_cert_bundle"
|
||||
"crts/ecdsa_correct_sig_crt.pem"
|
||||
"crts/ecdsa_wrong_sig_crt.pem")
|
||||
|
||||
idf_component_register(
|
||||
SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES efuse cmock test_utils mbedtls esp_timer unity spi_flash esp_psram esp_security
|
||||
EMBED_TXTFILES ${TEST_CRTS}
|
||||
@@ -13,7 +18,6 @@ idf_component_register(SRC_DIRS "."
|
||||
idf_component_get_property(mbedtls mbedtls COMPONENT_LIB)
|
||||
target_compile_definitions(${mbedtls} INTERFACE "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedtls PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedcrypto PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
target_compile_definitions(mbedx509 PUBLIC "-DMBEDTLS_DEPRECATED_WARNING")
|
||||
|
||||
# Add linker wrap option to override esp_ds_finish_sign
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "psa/crypto.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
#include "mbedtls/aes.h"
|
||||
#include "memory_checks.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_newlib.h"
|
||||
#include "esp_random.h"
|
||||
|
||||
#define CALL_SZ (32 * 1024)
|
||||
|
||||
/* setUp runs before every test */
|
||||
void setUp(void)
|
||||
@@ -17,8 +21,25 @@ void setUp(void)
|
||||
// Execute mbedtls_aes_init operation to allocate AES interrupt
|
||||
// allocation memory which is considered as leak otherwise
|
||||
#if SOC_AES_SUPPORTED
|
||||
mbedtls_aes_context ctx;
|
||||
mbedtls_aes_init(&ctx);
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
memset(iv, 0xEE, 16);
|
||||
memset(key, 0x44, 16);
|
||||
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
psa_import_key(&attributes, key, sizeof(key), &key_id);
|
||||
|
||||
size_t output_length = 0;
|
||||
psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, buf, CALL_SZ, buf, CALL_SZ, &output_length);
|
||||
heap_caps_free(buf);
|
||||
psa_destroy_key(key_id);
|
||||
#endif // SOC_AES_SUPPORTED
|
||||
|
||||
test_utils_record_free_mem();
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICQjCCAcmgAwIBAgIUTbvKUa+55zFxQhgDIQ91RdGXEXIwCgYIKoZIzj0EAwQw
|
||||
YDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxFjAU
|
||||
BgNVBAoMDVRlc3QgRUNEU0EgQ0ExGzAZBgNVBAMMElRlc3QgRUNEU0EgUm9vdCBD
|
||||
QTAeFw0yNTExMDMwODAzNTdaFw0yNjExMDMwODAzNTdaMGIxCzAJBgNVBAYTAlVT
|
||||
MQ0wCwYDVQQIDARUZXN0MQ0wCwYDVQQHDARUZXN0MRQwEgYDVQQKDAtUZXN0IFNl
|
||||
cnZlcjEfMB0GA1UEAwwWZWNkc2EtdGVzdC5leGFtcGxlLmNvbTB2MBAGByqGSM49
|
||||
AgEGBSuBBAAiA2IABFd+Bd6HtASMpEytx+QfDk8I0DX73EKQ3tR2TUJuhg7B2epc
|
||||
qqmMXZ5KQpOY/+V0kv1WyLCDisw7vP6d4yQjokSJqEnaO3af5TJh0WCjWJsVtNZy
|
||||
VAQMS9lxSZW1a1lle6NCMEAwHQYDVR0OBBYEFNJ2LzJjqMZXRjY0NNvVTS3Crsjh
|
||||
MB8GA1UdIwQYMBaAFElMhoUHf0Loi7Kzcpp0t4AfUBsuMAoGCCqGSM49BAMEA2cA
|
||||
MGQCMCiXh9m1BOkedod4lVzKLx535sLbFM7OxnYFxYOCK4Q3djtgxjy0OFmlyD5I
|
||||
YLUfxAIwO35NHh06OMyOI85NJbOYD2oPDiju/1JYHhER9rPAFrJJtwKGhNlMufqk
|
||||
V+9SwUK2
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICQjCCAcmgAwIBAgIUTbvKUa+55zFxQhgDIQ91RdGXEXIwCgYIKoZIzj0EAwQw
|
||||
YDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxFjAU
|
||||
BgNVBAoMDVRlc3QgRUNEU0EgQ0ExGzAZBgNVBAMMElRlc3QgRUNEU0EgUm9vdCBD
|
||||
QTAeFw0yNTExMDMwODAzNTdaFw0yNjExMDMwODAzNTdaMGIxCzAJBgNVBAYTAlVT
|
||||
MQ0wCwYDVQQIDARUZXN0MQ0wCwYDVQQHDARUZXN0MRQwEgYDVQQKDAtUZXN0IFNl
|
||||
cnZlcjEfMB0GA1UEAwwWZWNkc2EtdGVzdC5leGFtcGxlLmNvbTB2MBAGByqGSM49
|
||||
AgEGBSuBBAAiA2IABFd+Bd6HtASMpEytx+QfDk8I0DX73EKQ3tR2TUJuhg7B2epc
|
||||
qqmMXZ5KQpOY/+V0kv1WyLCDisw7vP6d4yQjokSJqEnaO3af5TJh0WCjWJsVtNZy
|
||||
VAQMS9lxSZW1a1lle6NCMEAwHQYDVR0OBBYEFNJ2LzJjqMZXRjY0NNvVTS3Crsjh
|
||||
MB8GA1UdIwQYMBaAFElMhoUHf0Loi7Kzcpp0t4AfUBsuMAoGCCqGSM49BAMEA2cA
|
||||
MGQCMCiXh9m1BOkedod4lVzKMx535sLbFM7OxnYFxYOCK4Q3djtgxjy0OFmlyD5I
|
||||
YLUfxAIwO35NHh06OMyOI85NJbOYD2oPDiju/1JYHhER9rPAFrJJtwKGhNlMufqk
|
||||
V+9SwUK2
|
||||
-----END CERTIFICATE-----
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,885 +0,0 @@
|
||||
/* mbedTLS GCM test
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_utils.h"
|
||||
#include "ccomp_timer.h"
|
||||
#include "sys/param.h"
|
||||
|
||||
#if CONFIG_MBEDTLS_HARDWARE_AES
|
||||
|
||||
/*
|
||||
Python example code for generating test vectors
|
||||
|
||||
import os, binascii
|
||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||
|
||||
def as_c_array(byte_arr):
|
||||
hex_str = ''
|
||||
for idx, byte in enumerate(byte_arr):
|
||||
hex_str += "0x{:02x}, ".format(byte)
|
||||
bytes_per_line = 8
|
||||
if idx % bytes_per_line == bytes_per_line - 1:
|
||||
hex_str += '\n'
|
||||
|
||||
return hex_str
|
||||
|
||||
key = b'\x44' * 16
|
||||
iv = b'\xEE' * 16
|
||||
data = b'\xAA' * 3200
|
||||
aad = b'\x76' * 16
|
||||
|
||||
aesgcm = AESGCM(key)
|
||||
|
||||
ct = aesgcm.encrypt(iv, data, aad)
|
||||
|
||||
print(as_c_array(ct))
|
||||
*/
|
||||
|
||||
TEST_CASE("mbedtls GCM stream test", "[aes-gcm]")
|
||||
{
|
||||
|
||||
const unsigned SZ = 100;
|
||||
mbedtls_gcm_context ctx;
|
||||
uint8_t nonce[16];
|
||||
uint8_t key[16];
|
||||
uint8_t tag[16];
|
||||
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
|
||||
|
||||
const uint8_t expected_cipher[] = {
|
||||
0x03, 0x92, 0x13, 0x49, 0x1f, 0x1f, 0x24, 0x41,
|
||||
0xe8, 0xeb, 0x89, 0x47, 0x50, 0x0a, 0xce, 0xa3,
|
||||
0xc7, 0x1c, 0x10, 0x70, 0xb0, 0x89, 0x82, 0x5e,
|
||||
0x0f, 0x4a, 0x23, 0xee, 0xd2, 0xfc, 0xff, 0x45,
|
||||
0x61, 0x4c, 0xd1, 0xfb, 0x6d, 0xe2, 0xbe, 0x67,
|
||||
0x6f, 0x94, 0x72, 0xa3, 0xe7, 0x04, 0x99, 0xb3,
|
||||
0x4a, 0x46, 0xf9, 0x2b, 0xaf, 0xac, 0xa9, 0x0e,
|
||||
0x43, 0x7e, 0x8b, 0xc4, 0xbf, 0x49, 0xa4, 0x83,
|
||||
0x9c, 0x31, 0x11, 0x1c, 0x09, 0xac, 0x90, 0xdf,
|
||||
0x00, 0x34, 0x08, 0xe5, 0x70, 0xa3, 0x7e, 0x4b,
|
||||
0x36, 0x48, 0x5a, 0x3f, 0x28, 0xc7, 0x1c, 0xd9,
|
||||
0x1b, 0x1b, 0x49, 0x96, 0xe9, 0x7c, 0xea, 0x54,
|
||||
0x7c, 0x71, 0x29, 0x0d
|
||||
};
|
||||
const uint8_t expected_tag[] = {
|
||||
0x35, 0x1c, 0x21, 0xc6, 0xbc, 0x6b, 0x18, 0x52,
|
||||
0x90, 0xe1, 0xf2, 0x5b, 0xe1, 0xf6, 0x15, 0xee,
|
||||
};
|
||||
|
||||
|
||||
memset(nonce, 0x89, 16);
|
||||
memset(key, 0x56, 16);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *ciphertext = heap_caps_malloc(SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *plaintext = heap_caps_malloc(SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *decryptedtext = heap_caps_malloc(SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
|
||||
memset(plaintext, 0xAB, SZ);
|
||||
/* Test that all the end results are the same
|
||||
no matter how many bytes we encrypt each call
|
||||
*/
|
||||
for (int bytes_to_process = 16; bytes_to_process < SZ; bytes_to_process = bytes_to_process + 16) {
|
||||
memset(nonce, 0x89, 16);
|
||||
memset(ciphertext, 0x0, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
memset(tag, 0x0, 16);
|
||||
|
||||
mbedtls_gcm_init(&ctx);
|
||||
mbedtls_gcm_setkey(&ctx, cipher, key, 128);
|
||||
mbedtls_gcm_starts( &ctx, MBEDTLS_AES_ENCRYPT, nonce, sizeof(nonce) );
|
||||
mbedtls_gcm_update_ad( &ctx, NULL, 0 );
|
||||
|
||||
size_t olen;
|
||||
// Encrypt
|
||||
for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) {
|
||||
// Limit length of last call to avoid exceeding buffer size
|
||||
size_t length = (idx + bytes_to_process > SZ) ? (SZ - idx) : bytes_to_process;
|
||||
mbedtls_gcm_update(&ctx, plaintext + idx, length, ciphertext + idx, length, &olen);
|
||||
}
|
||||
mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag, sizeof(tag) );
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag, sizeof(tag));
|
||||
|
||||
// Decrypt
|
||||
memset(nonce, 0x89, 16);
|
||||
mbedtls_gcm_free( &ctx );
|
||||
|
||||
mbedtls_gcm_init(&ctx);
|
||||
mbedtls_gcm_setkey(&ctx, cipher, key, 128);
|
||||
mbedtls_gcm_starts( &ctx, MBEDTLS_AES_DECRYPT, nonce, sizeof(nonce));
|
||||
mbedtls_gcm_update_ad( &ctx, NULL, 0 );
|
||||
|
||||
for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) {
|
||||
// Limit length of last call to avoid exceeding buffer size
|
||||
|
||||
size_t length = (idx + bytes_to_process > SZ) ? (SZ - idx) : bytes_to_process;
|
||||
mbedtls_gcm_update(&ctx, ciphertext + idx, length, decryptedtext + idx, length, &olen);
|
||||
}
|
||||
mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag, sizeof(tag) );
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
mbedtls_gcm_free( &ctx );
|
||||
}
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls AES GCM self-tests", "[aes-gcm]")
|
||||
{
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_gcm_self_test(1), "AES GCM self-test should pass.");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t *plaintext;
|
||||
size_t plaintext_length;
|
||||
uint32_t output_caps;
|
||||
uint8_t *add_buf;
|
||||
size_t add_length;
|
||||
uint8_t *iv;
|
||||
size_t iv_length;
|
||||
uint8_t *key;
|
||||
size_t key_bits;
|
||||
size_t tag_len;
|
||||
} aes_gcm_test_cfg_t;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t *expected_tag;
|
||||
const uint8_t *ciphertext_last_block; // Last block of the ciphertext
|
||||
} aes_gcm_test_expected_res_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
AES_GCM_TEST_CRYPT_N_TAG,
|
||||
AES_GCM_TEST_START_UPDATE_FINISH,
|
||||
} aes_gcm_test_type_t;
|
||||
|
||||
static void aes_gcm_test(aes_gcm_test_cfg_t *cfg, aes_gcm_test_expected_res_t *res, aes_gcm_test_type_t aes_gcm_type)
|
||||
{
|
||||
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
|
||||
mbedtls_gcm_context ctx;
|
||||
|
||||
uint8_t tag_buf_encrypt[16] = {};
|
||||
uint8_t tag_buf_decrypt[16] = {};
|
||||
uint8_t iv_buf[16] = {};
|
||||
|
||||
uint8_t *ciphertext = heap_caps_malloc(cfg->plaintext_length, cfg->output_caps);
|
||||
uint8_t *output = heap_caps_malloc(cfg->plaintext_length, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
if (cfg->plaintext_length != 0) {
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(output);
|
||||
}
|
||||
|
||||
memset(ciphertext, 0, cfg->plaintext_length);
|
||||
memset(output, 0, cfg->plaintext_length);
|
||||
memcpy(iv_buf, cfg->iv, cfg->iv_length);
|
||||
|
||||
mbedtls_gcm_init(&ctx);
|
||||
mbedtls_gcm_setkey(&ctx, cipher, cfg->key, cfg->key_bits);
|
||||
size_t olen;
|
||||
/* Encrypt and tag */
|
||||
if (aes_gcm_type == AES_GCM_TEST_CRYPT_N_TAG) {
|
||||
mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_AES_ENCRYPT, cfg->plaintext_length, iv_buf, cfg->iv_length, cfg->add_buf, cfg->add_length, cfg->plaintext, ciphertext, cfg->tag_len, tag_buf_encrypt);
|
||||
} else if (aes_gcm_type == AES_GCM_TEST_START_UPDATE_FINISH) {
|
||||
TEST_ASSERT(mbedtls_gcm_starts( &ctx, MBEDTLS_AES_ENCRYPT, iv_buf, cfg->iv_length) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_update_ad( &ctx, cfg->add_buf, cfg->add_length) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_update( &ctx, cfg->plaintext, cfg->plaintext_length, ciphertext, cfg->plaintext_length, &olen) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf_encrypt, cfg->tag_len) == 0 );
|
||||
}
|
||||
size_t offset = cfg->plaintext_length > 16 ? cfg->plaintext_length - 16 : 0;
|
||||
/* Sanity check: make sure the last ciphertext block matches what we expect to see. */
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(res->ciphertext_last_block, ciphertext + offset, MIN(16, cfg->plaintext_length));
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(res->expected_tag, tag_buf_encrypt, cfg->tag_len);
|
||||
|
||||
|
||||
/* Decrypt and authenticate */
|
||||
if (aes_gcm_type == AES_GCM_TEST_CRYPT_N_TAG) {
|
||||
TEST_ASSERT(mbedtls_gcm_auth_decrypt(&ctx, cfg->plaintext_length, iv_buf, cfg->iv_length, cfg->add_buf, cfg->add_length, res->expected_tag, cfg->tag_len, ciphertext, output) == 0);
|
||||
} else if (aes_gcm_type == AES_GCM_TEST_START_UPDATE_FINISH) {
|
||||
TEST_ASSERT(mbedtls_gcm_starts( &ctx, MBEDTLS_AES_DECRYPT, iv_buf, cfg->iv_length) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_update_ad( &ctx, cfg->add_buf, cfg->add_length) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_update( &ctx, ciphertext, cfg->plaintext_length, output, cfg->plaintext_length, &olen) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf_decrypt, cfg->tag_len) == 0 );
|
||||
|
||||
/* mbedtls_gcm_auth_decrypt already checks tag so only needed for AES_GCM_TEST_START_UPDATE_FINISH */
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(res->expected_tag, tag_buf_decrypt, cfg->tag_len);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(cfg->plaintext, output, cfg->plaintext_length);
|
||||
mbedtls_gcm_free( &ctx );
|
||||
free(ciphertext);
|
||||
free(output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("mbedtls AES GCM", "[aes-gcm]")
|
||||
{
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
uint8_t add[30];
|
||||
|
||||
memset(iv, 0xB1, sizeof(iv));
|
||||
memset(key, 0x27, sizeof(key));
|
||||
memset(add, 0x90, sizeof(add));
|
||||
|
||||
size_t length[] = {10, 16, 500, 5000, 12345};
|
||||
|
||||
const uint8_t expected_last_block[][16] = {
|
||||
|
||||
{
|
||||
0x37, 0x99, 0x4b, 0x16, 0x5f, 0x8d, 0x27, 0xb1,
|
||||
0x60, 0x72
|
||||
},
|
||||
|
||||
{
|
||||
0x37, 0x99, 0x4b, 0x16, 0x5f, 0x8d, 0x27, 0xb1,
|
||||
0x60, 0x72, 0x9a, 0x81, 0x8d, 0x3c, 0x69, 0x66
|
||||
},
|
||||
|
||||
{
|
||||
0x9d, 0x7a, 0xac, 0x84, 0xe3, 0x70, 0x43, 0x0f,
|
||||
0xa7, 0x83, 0x43, 0xc9, 0x04, 0xf8, 0x7d, 0x48
|
||||
},
|
||||
|
||||
{
|
||||
0xee, 0xfd, 0xab, 0x2a, 0x09, 0x44, 0x41, 0x6a,
|
||||
0x91, 0xb0, 0x74, 0x24, 0xee, 0x35, 0xb1, 0x39
|
||||
},
|
||||
|
||||
{
|
||||
0x51, 0xf7, 0x1f, 0x67, 0x1a, 0x4a, 0x12, 0x37,
|
||||
0x60, 0x3b, 0x68, 0x01, 0x20, 0x4f, 0xf3, 0xd9
|
||||
},
|
||||
};
|
||||
|
||||
const uint8_t expected_tag[][16] = {
|
||||
|
||||
{
|
||||
0x06, 0x4f, 0xb5, 0x91, 0x12, 0x24, 0xb4, 0x24,
|
||||
0x0b, 0xc2, 0x85, 0x59, 0x6a, 0x7c, 0x1f, 0xc9
|
||||
},
|
||||
|
||||
{
|
||||
0x45, 0xc2, 0xa8, 0xfe, 0xff, 0x49, 0x1f, 0x45,
|
||||
0x8e, 0x29, 0x74, 0x41, 0xed, 0x9b, 0x54, 0x28
|
||||
},
|
||||
|
||||
{
|
||||
0xe1, 0xf9, 0x40, 0xfa, 0x29, 0x6f, 0x30, 0xae,
|
||||
0xb6, 0x9b, 0x33, 0xdb, 0x8a, 0xf9, 0x70, 0xc4
|
||||
},
|
||||
|
||||
{
|
||||
0x22, 0xe1, 0x22, 0x34, 0x0c, 0x91, 0x0b, 0xcf,
|
||||
0xa3, 0x42, 0xe0, 0x48, 0xe6, 0xfe, 0x2e, 0x28
|
||||
},
|
||||
|
||||
{
|
||||
0xfb, 0xfe, 0x5a, 0xed, 0x26, 0x5c, 0x5e, 0x66,
|
||||
0x4e, 0xb2, 0x48, 0xce, 0xe9, 0x88, 0x1c, 0xe0
|
||||
},
|
||||
};
|
||||
|
||||
aes_gcm_test_cfg_t cfg = {
|
||||
.output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL,
|
||||
.iv = iv,
|
||||
.iv_length = sizeof(iv),
|
||||
.key = key,
|
||||
.key_bits = 8 * sizeof(key),
|
||||
.add_buf = add,
|
||||
.add_length = sizeof(add),
|
||||
.tag_len = 16
|
||||
};
|
||||
|
||||
aes_gcm_test_expected_res_t res = {
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(length) / sizeof(length[0]); i++) {
|
||||
printf("Test AES-GCM with plaintext length = %d\n", length[i]);
|
||||
uint8_t *input = heap_caps_malloc(length[i], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT(input != NULL || length[i] == 0);
|
||||
memset(input, 0x36, length[i]);
|
||||
|
||||
cfg.plaintext = input;
|
||||
cfg.plaintext_length = length[i];
|
||||
res.expected_tag = expected_tag[i];
|
||||
res.ciphertext_last_block = expected_last_block[i],
|
||||
|
||||
aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG);
|
||||
aes_gcm_test(&cfg, &res, AES_GCM_TEST_START_UPDATE_FINISH);
|
||||
|
||||
free(input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls AES GCM - Different add messages", "[aes-gcm]")
|
||||
{
|
||||
const unsigned CALL_SZ = 160;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
uint8_t *input = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(input);
|
||||
|
||||
memset(input, 0x67, CALL_SZ);
|
||||
memset(iv, 0xA2, sizeof(iv));
|
||||
memset(key, 0x48, sizeof(key));
|
||||
|
||||
const uint8_t expected_last_block[] = {
|
||||
0xcd, 0xb9, 0xad, 0x6f, 0xc9, 0x35, 0x21, 0x0d,
|
||||
0xc9, 0x5d, 0xea, 0xd9, 0xf7, 0x1d, 0x43, 0xed
|
||||
};
|
||||
|
||||
size_t add_len[] = {0, 10, 16, 500, 5000};
|
||||
|
||||
const uint8_t expected_tag[][16] = {
|
||||
{
|
||||
0xe3, 0x91, 0xad, 0x40, 0x96, 0xb7, 0x8c, 0x53,
|
||||
0x4d, 0x15, 0x7d, 0x55, 0x15, 0xdf, 0x10, 0x69
|
||||
},
|
||||
|
||||
{
|
||||
0xc2, 0x38, 0x36, 0xe9, 0x12, 0x72, 0x5b, 0x31,
|
||||
0x0c, 0xde, 0xb5, 0xc9, 0x8c, 0xa3, 0xcb, 0xe7
|
||||
},
|
||||
|
||||
{
|
||||
0x57, 0x10, 0x22, 0x91, 0x65, 0xfa, 0x89, 0xba,
|
||||
0x0a, 0x3e, 0xc1, 0x7c, 0x93, 0x6e, 0x35, 0xac
|
||||
},
|
||||
|
||||
{
|
||||
0x3c, 0x28, 0x03, 0xc2, 0x14, 0x40, 0xec, 0xb6,
|
||||
0x25, 0xfb, 0xdd, 0x55, 0xa0, 0xb2, 0x47, 0x7b
|
||||
},
|
||||
|
||||
{
|
||||
0xfa, 0x66, 0x4a, 0x97, 0x2d, 0x02, 0x32, 0x5b,
|
||||
0x92, 0x94, 0xf1, 0x00, 0x1c, 0xfa, 0xe3, 0x07
|
||||
}
|
||||
};
|
||||
|
||||
aes_gcm_test_cfg_t cfg = {
|
||||
.plaintext = input,
|
||||
.plaintext_length = CALL_SZ,
|
||||
.output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL,
|
||||
.iv = iv,
|
||||
.iv_length = sizeof(iv),
|
||||
.key = key,
|
||||
.key_bits = 8 * sizeof(key),
|
||||
.tag_len = 16
|
||||
};
|
||||
|
||||
aes_gcm_test_expected_res_t res = {
|
||||
.ciphertext_last_block = expected_last_block,
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(add_len) / sizeof(add_len[0]); i++) {
|
||||
printf("Test AES-GCM with add length = %d\n", add_len[i]);
|
||||
uint8_t *add = heap_caps_malloc(add_len[i], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT(add != NULL || add_len[i] == 0);
|
||||
memset(add, 0x12, add_len[i]);
|
||||
|
||||
cfg.add_buf = add;
|
||||
cfg.add_length = add_len[i];
|
||||
res.expected_tag = expected_tag[i];
|
||||
|
||||
aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG);
|
||||
aes_gcm_test(&cfg, &res, AES_GCM_TEST_START_UPDATE_FINISH);
|
||||
|
||||
free(add);
|
||||
}
|
||||
free(input);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("mbedtls AES GCM performance, start, update, ret", "[aes-gcm]")
|
||||
{
|
||||
const unsigned CALL_SZ = 16 * 3200;
|
||||
mbedtls_gcm_context ctx;
|
||||
float elapsed_usec;
|
||||
unsigned char tag_buf[16];
|
||||
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
uint8_t aad[16];
|
||||
size_t olen;
|
||||
memset(iv, 0xEE, 16);
|
||||
memset(key, 0x44, 16);
|
||||
memset(aad, 0x76, 16);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
|
||||
mbedtls_gcm_init(&ctx);
|
||||
mbedtls_gcm_setkey( &ctx, cipher, key, 128);
|
||||
|
||||
ccomp_timer_start();
|
||||
|
||||
memset(buf, 0xAA, CALL_SZ);
|
||||
|
||||
TEST_ASSERT(mbedtls_gcm_starts( &ctx, MBEDTLS_AES_ENCRYPT, iv, sizeof(iv) ) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_update_ad( &ctx, aad, sizeof(aad)) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_update( &ctx, buf, CALL_SZ, buf, CALL_SZ, &olen) == 0 );
|
||||
TEST_ASSERT(mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 ) == 0 );
|
||||
|
||||
elapsed_usec = ccomp_timer_stop();
|
||||
|
||||
/* Sanity check: make sure the last ciphertext block matches
|
||||
what we expect to see.
|
||||
*/
|
||||
const uint8_t expected_last_block[] = {
|
||||
0xd4, 0x25, 0x88, 0xd4, 0x32, 0x52, 0x3d, 0x6f,
|
||||
0xae, 0x49, 0x19, 0xb5, 0x95, 0x01, 0xde, 0x7d,
|
||||
};
|
||||
|
||||
const uint8_t expected_tag[] = {
|
||||
0xf5, 0x10, 0x1f, 0x21, 0x5b, 0x07, 0x0d, 0x3f,
|
||||
0xac, 0xc9, 0xd0, 0x42, 0x45, 0xef, 0xc7, 0xfa,
|
||||
};
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag_buf, 16);
|
||||
|
||||
free(buf);
|
||||
|
||||
// bytes/usec = MB/sec
|
||||
float mb_sec = CALL_SZ / elapsed_usec;
|
||||
printf("GCM encryption rate %.3fMB/sec\n", mb_sec);
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_GCM
|
||||
// Don't put a hard limit on software AES performance
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(AES_GCM_UPDATE_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls AES GCM performance, crypt-and-tag", "[aes-gcm]")
|
||||
{
|
||||
const unsigned CALL_SZ = 16 * 3200;
|
||||
mbedtls_gcm_context ctx;
|
||||
float elapsed_usec;
|
||||
unsigned char tag_buf[16] = {};
|
||||
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
uint8_t aad[16];
|
||||
|
||||
memset(iv, 0xEE, 16);
|
||||
memset(key, 0x44, 16);
|
||||
memset(aad, 0x76, 16);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
|
||||
mbedtls_gcm_init(&ctx);
|
||||
mbedtls_gcm_setkey( &ctx, cipher, key, 128);
|
||||
|
||||
memset(buf, 0xAA, CALL_SZ);
|
||||
|
||||
ccomp_timer_start();
|
||||
mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, sizeof(iv), aad, sizeof(aad), buf, buf, 16, tag_buf);
|
||||
|
||||
elapsed_usec = ccomp_timer_stop();
|
||||
|
||||
/* Sanity check: make sure the last ciphertext block matches
|
||||
what we expect to see.
|
||||
*/
|
||||
|
||||
const uint8_t expected_last_block[] = {
|
||||
0xd4, 0x25, 0x88, 0xd4, 0x32, 0x52, 0x3d, 0x6f,
|
||||
0xae, 0x49, 0x19, 0xb5, 0x95, 0x01, 0xde, 0x7d,
|
||||
};
|
||||
|
||||
const uint8_t expected_tag[] = {
|
||||
0xf5, 0x10, 0x1f, 0x21, 0x5b, 0x07, 0x0d, 0x3f,
|
||||
0xac, 0xc9, 0xd0, 0x42, 0x45, 0xef, 0xc7, 0xfa,
|
||||
};
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag_buf, 16);
|
||||
|
||||
free(buf);
|
||||
|
||||
// bytes/usec = MB/sec
|
||||
float mb_sec = CALL_SZ / elapsed_usec;
|
||||
printf("GCM encryption rate %.3fMB/sec\n", mb_sec);
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_GCM
|
||||
// Don't put a hard limit on software AES performance
|
||||
TEST_PERFORMANCE_CCOMP_GREATER_THAN(AES_GCM_CRYPT_TAG_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls AES GCM - Combine different IV/Key/Plaintext/AAD lengths", "[aes-gcm]")
|
||||
{
|
||||
#define IV_BYTES_VALUE 0xA2
|
||||
#define KEY_BYTES_VALUE 0x48
|
||||
#define INPUT_BYTES_VALUE 0x36
|
||||
#define ADD_BYTES_VALUE 0x12
|
||||
|
||||
uint8_t iv[16];
|
||||
uint8_t key[32];
|
||||
|
||||
memset(iv, IV_BYTES_VALUE, sizeof(iv));
|
||||
memset(key, KEY_BYTES_VALUE, sizeof(key));
|
||||
|
||||
/* Key length is: 16 bytes, 32 bytes */
|
||||
size_t key_length[] = {16, 32};
|
||||
|
||||
/* IV length is: 12 bytes (standard), 16 bytes */
|
||||
size_t iv_length[] = {12, 16};
|
||||
|
||||
/* Plaintext length is: a multiple of 16 bytes, a non-multiple of 16 bytes */
|
||||
size_t length[] = {160, 321};
|
||||
|
||||
/* Add len is: 0, a multiple of 16 bytes, a non-multiple of 16 bytes */
|
||||
size_t add_len[] = {0, 160, 321};
|
||||
|
||||
/*indexes: Key - IV - Plaintext */
|
||||
const uint8_t expected_last_block[2][2][2][16] = {
|
||||
{
|
||||
/* 16 byte key */
|
||||
|
||||
{
|
||||
{
|
||||
0xa2, 0x1e, 0x23, 0x3c, 0xfc, 0x7c, 0xec, 0x9a,
|
||||
0x91, 0xe5, 0xdb, 0x3a, 0xe5, 0x0c, 0x3f, 0xc2,
|
||||
},
|
||||
|
||||
{
|
||||
0xa8, 0xeb, 0x40, 0x9b, 0x7b, 0x87, 0x07,
|
||||
0x68, 0x17, 0x5c, 0xc0, 0xb7, 0xb4, 0xb3, 0x81,
|
||||
0xbe,
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
0x9c, 0xe8, 0xfc, 0x3e, 0x98, 0x64, 0x70, 0x5c,
|
||||
0x98, 0x0c, 0xbb, 0x88, 0xa6, 0x4c, 0x12, 0xbc
|
||||
},
|
||||
|
||||
{
|
||||
0x8b, 0x66, 0xf5, 0xbc, 0x56, 0x59, 0xae,
|
||||
0xf0, 0x9e, 0x5c, 0xdb, 0x6d, 0xfc, 0x1f, 0x2e,
|
||||
0x00
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
/* 32 byte key */
|
||||
{
|
||||
{
|
||||
0xde, 0xc2, 0xd3, 0xeb, 0x5e, 0x03, 0x53, 0x4b,
|
||||
0x04, 0x0d, 0x63, 0xf1, 0xd8, 0x5b, 0x1f, 0x85,
|
||||
},
|
||||
|
||||
{
|
||||
0xb5, 0x53, 0x8e, 0xd3, 0xab, 0x10, 0xf1,
|
||||
0x77, 0x41, 0x92, 0xea, 0xdd, 0xdd, 0x9e, 0x5d,
|
||||
0x40,
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
0x3b, 0xc7, 0xf0, 0x3f, 0xba, 0x97, 0xbd, 0xa0,
|
||||
0xa5, 0x48, 0xf3, 0x7a, 0xde, 0x23, 0x19, 0x7a,
|
||||
},
|
||||
|
||||
{
|
||||
0x57, 0xc7, 0x4d, 0xe3, 0x79, 0x5e, 0xbd,
|
||||
0x0d, 0xd7, 0x6a, 0xef, 0x1f, 0x54, 0x29, 0xa6,
|
||||
0xd7,
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/*indexes: Key - IV - Plaintext - Add len*/
|
||||
const uint8_t expected_tag[2][2][2][3][16] = {
|
||||
{
|
||||
{
|
||||
{
|
||||
// Plaintext 160 bytes
|
||||
{
|
||||
0x67, 0x92, 0xb1, 0x7f, 0x44, 0x1f, 0x95, 0xfb,
|
||||
0x33, 0x76, 0x66, 0xb7, 0x4f, 0x3e, 0xec, 0x4d,
|
||||
},
|
||||
|
||||
{
|
||||
0xb1, 0x99, 0xed, 0x1b, 0x4e, 0x12, 0x87, 0x5e,
|
||||
0xf4, 0xe3, 0x81, 0xd8, 0x96, 0x07, 0xda, 0xff,
|
||||
},
|
||||
|
||||
{
|
||||
0x73, 0x35, 0x0c, 0xf5, 0x70, 0x1e, 0xc0, 0x99,
|
||||
0x34, 0xba, 0x1a, 0x50, 0x23, 0xac, 0x21, 0x33,
|
||||
},
|
||||
},
|
||||
{
|
||||
// Plaintext 321 bytes
|
||||
{
|
||||
0x2d, 0xf6, 0xd0, 0x7a, 0x75, 0x4d, 0x9d,
|
||||
0xb5, 0x9d, 0x43, 0xbf, 0x57, 0x10, 0xa3, 0xff,
|
||||
0x3d
|
||||
},
|
||||
|
||||
{
|
||||
0x06, 0x91, 0xe4, 0x38, 0x3a, 0xe1, 0x6e,
|
||||
0x2d, 0x83, 0x68, 0x2e, 0xb0, 0x26, 0x2f, 0xe4,
|
||||
0x78
|
||||
},
|
||||
|
||||
{
|
||||
0x1b, 0x58, 0x2f, 0x9b, 0xe9, 0xe0, 0xe0,
|
||||
0x43, 0x83, 0x08, 0xec, 0x58, 0x3a, 0x78, 0xe9,
|
||||
0x69,
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
// Plaintext 160 bytes
|
||||
{
|
||||
0x77, 0xe5, 0x2e, 0x2d, 0x94, 0xb8, 0x03, 0x61,
|
||||
0x7a, 0xd5, 0x0c, 0x3c, 0x9c, 0x40, 0x92, 0x9b
|
||||
},
|
||||
|
||||
{
|
||||
0xa1, 0xee, 0x72, 0x49, 0x9e, 0xb5, 0x11, 0xc4,
|
||||
0xbd, 0x40, 0xeb, 0x53, 0x45, 0x79, 0xa4, 0x29
|
||||
},
|
||||
|
||||
{
|
||||
0x63, 0x42, 0x93, 0xa7, 0xa0, 0xb9, 0x56, 0x03,
|
||||
0x7d, 0x19, 0x70, 0xdb, 0xf0, 0xd2, 0x5f, 0xe5
|
||||
},
|
||||
},
|
||||
{
|
||||
// Plaintext 321 bytes
|
||||
{
|
||||
0x50, 0xa3, 0x79, 0xfc, 0x17, 0xb8, 0xf4,
|
||||
0xf6, 0x14, 0xaa, 0x4a, 0xe7, 0xd4, 0xa0, 0xea,
|
||||
0xee
|
||||
},
|
||||
|
||||
{
|
||||
0x7b, 0xc4, 0x4d, 0xbe, 0x58, 0x14, 0x07,
|
||||
0x6e, 0x0a, 0x81, 0xdb, 0x00, 0xe2, 0x2c, 0xf1,
|
||||
0xab
|
||||
},
|
||||
|
||||
{
|
||||
0x66, 0x0d, 0x86, 0x1d, 0x8b, 0x15, 0x89,
|
||||
0x00, 0x0a, 0xe1, 0x19, 0xe8, 0xfe, 0x7b, 0xfc,
|
||||
0xba
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
// Plaintext 160 bytes
|
||||
{
|
||||
0x04, 0x04, 0x15, 0xb1, 0xd3, 0x98, 0x15, 0x45,
|
||||
0xa2, 0x44, 0xba, 0x4a, 0xde, 0xc2, 0x8d, 0xd6,
|
||||
},
|
||||
|
||||
{
|
||||
0x94, 0x3e, 0xc3, 0x5d, 0xdc, 0x42, 0xf6, 0x4c,
|
||||
0x80, 0x15, 0xe4, 0xb9, 0x0b, 0xc9, 0x87, 0x01,
|
||||
},
|
||||
|
||||
{
|
||||
0x93, 0x6e, 0x26, 0x5b, 0x7e, 0x17, 0xc8, 0x73,
|
||||
0x9b, 0x71, 0x31, 0x7a, 0x8b, 0x0e, 0x19, 0x89,
|
||||
}
|
||||
},
|
||||
{
|
||||
// Plaintext 321 bytes
|
||||
{
|
||||
0x99, 0x5e, 0x77, 0x28, 0x8b, 0xa8, 0x9b,
|
||||
0xb3, 0x35, 0xc3, 0x99, 0x90, 0xd4, 0x5d, 0x63,
|
||||
0xa7,
|
||||
},
|
||||
|
||||
{
|
||||
0xbc, 0xc2, 0x9f, 0xe6, 0x38, 0xef, 0xf5,
|
||||
0x11, 0x76, 0x09, 0x17, 0x3a, 0xd4, 0x91, 0xee,
|
||||
0xfe,
|
||||
},
|
||||
|
||||
{
|
||||
0x9f, 0xa6, 0x23, 0x5a, 0x4d, 0x78, 0xae,
|
||||
0xce, 0x10, 0x35, 0xc1, 0x0c, 0x6e, 0xc2, 0x4e,
|
||||
0xe8,
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
// Plaintext 160 bytes
|
||||
{
|
||||
0xfb, 0x74, 0x7e, 0x21, 0xf2, 0xe7, 0xe3, 0xf5,
|
||||
0xfa, 0xc8, 0x23, 0xab, 0x54, 0x9a, 0xb9, 0xcf,
|
||||
},
|
||||
|
||||
{
|
||||
0x6b, 0x4e, 0xa8, 0xcd, 0xfd, 0x3d, 0x00, 0xfc,
|
||||
0xd8, 0x99, 0x7d, 0x58, 0x81, 0x91, 0xb3, 0x18,
|
||||
},
|
||||
|
||||
{
|
||||
0x6c, 0x1e, 0x4d, 0xcb, 0x5f, 0x68, 0x3e, 0xc3,
|
||||
0xc3, 0xfd, 0xa8, 0x9b, 0x01, 0x56, 0x2d, 0x90,
|
||||
},
|
||||
},
|
||||
{
|
||||
// Plaintext 321 bytes
|
||||
{
|
||||
0xcd, 0x49, 0x75, 0x4c, 0x2a, 0x62, 0x65,
|
||||
0x6f, 0xfe, 0x14, 0xc2, 0x5d, 0x41, 0x07, 0x24,
|
||||
0x55
|
||||
},
|
||||
|
||||
{
|
||||
0xe8, 0xd5, 0x9d, 0x82, 0x99, 0x25, 0x0b,
|
||||
0xcd, 0xbd, 0xde, 0x4c, 0xf7, 0x41, 0xcb, 0xa9,
|
||||
0x0c,
|
||||
},
|
||||
|
||||
{
|
||||
0xcb, 0xb1, 0x21, 0x3e, 0xec, 0xb2, 0x50,
|
||||
0x12, 0xdb, 0xe2, 0x9a, 0xc1, 0xfb, 0x98, 0x09,
|
||||
0x1a,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
aes_gcm_test_cfg_t cfg = {
|
||||
.output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL,
|
||||
.tag_len = 16
|
||||
};
|
||||
|
||||
|
||||
for (int i_key = 0; i_key < sizeof(key_length) / sizeof(key_length[0]); i_key++) {
|
||||
printf("Test AES-GCM with key length = %d\n", key_length[i_key]);
|
||||
|
||||
cfg.key = key;
|
||||
cfg.key_bits = 8 * key_length[i_key];
|
||||
|
||||
for (int i_iv = 0; i_iv < sizeof(iv_length) / sizeof(iv_length[0]); i_iv++) {
|
||||
printf("Test AES-GCM with IV length = %d\n", iv_length[i_iv]);
|
||||
|
||||
cfg.iv = iv;
|
||||
cfg.iv_length = iv_length[i_iv];
|
||||
|
||||
for (int i_len = 0; i_len < sizeof(length) / sizeof(length[0]); i_len++) {
|
||||
printf("Test AES-GCM with plaintext length = %d\n", length[i_len]);
|
||||
uint8_t *input = heap_caps_malloc(length[i_len], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT(input != NULL || length[i_len] == 0);
|
||||
memset(input, INPUT_BYTES_VALUE, length[i_len]);
|
||||
cfg.plaintext = input;
|
||||
cfg.plaintext_length = length[i_len];
|
||||
|
||||
aes_gcm_test_expected_res_t res = {0};
|
||||
|
||||
for (int i_add = 0; i_add < sizeof(add_len) / sizeof(add_len[0]); i_add++) {
|
||||
|
||||
printf("Test AES-GCM with add length = %d\n", add_len[i_add]);
|
||||
uint8_t *add = heap_caps_malloc(add_len[i_add], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT(add != NULL || add_len[i_add] == 0);
|
||||
memset(add, ADD_BYTES_VALUE, add_len[i_add]);
|
||||
|
||||
cfg.add_buf = add;
|
||||
cfg.add_length = add_len[i_add];
|
||||
|
||||
res.expected_tag = expected_tag[i_key][i_iv][i_len][i_add];
|
||||
res.ciphertext_last_block = expected_last_block[i_key][i_iv][i_len],
|
||||
|
||||
aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG);
|
||||
|
||||
free(add);
|
||||
}
|
||||
free(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls AES GCM - Different Authentication Tag lengths", "[aes-gcm]")
|
||||
{
|
||||
const unsigned CALL_SZ = 160;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
uint8_t aad[16];
|
||||
uint8_t *input = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(input);
|
||||
|
||||
memset(input, 0x67, CALL_SZ);
|
||||
memset(iv, 0xA2, sizeof(iv));
|
||||
memset(key, 0x48, sizeof(key));
|
||||
memset(aad, 0x12, sizeof(aad));
|
||||
|
||||
size_t tag_len[] = {4, 8, 11, 16};
|
||||
|
||||
const uint8_t expected_last_block[] = {
|
||||
0xcd, 0xb9, 0xad, 0x6f, 0xc9, 0x35, 0x21, 0x0d,
|
||||
0xc9, 0x5d, 0xea, 0xd9, 0xf7, 0x1d, 0x43, 0xed
|
||||
};
|
||||
|
||||
const uint8_t expected_tag[16] = {
|
||||
0x57, 0x10, 0x22, 0x91, 0x65, 0xfa, 0x89, 0xba,
|
||||
0x0a, 0x3e, 0xc1, 0x7c, 0x93, 0x6e, 0x35, 0xac
|
||||
};
|
||||
|
||||
aes_gcm_test_cfg_t cfg = {
|
||||
.plaintext = input,
|
||||
.plaintext_length = CALL_SZ,
|
||||
.output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL,
|
||||
.add_buf = aad,
|
||||
.add_length = sizeof(aad),
|
||||
.iv = iv,
|
||||
.iv_length = sizeof(iv),
|
||||
.key = key,
|
||||
.key_bits = 8 * sizeof(key),
|
||||
};
|
||||
|
||||
aes_gcm_test_expected_res_t res = {
|
||||
.expected_tag = expected_tag,
|
||||
.ciphertext_last_block = expected_last_block,
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(tag_len) / sizeof(tag_len[0]); i++) {
|
||||
printf("Test AES-GCM with tag length = %d\n", tag_len[i]);
|
||||
cfg.tag_len = tag_len[i];
|
||||
aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG);
|
||||
aes_gcm_test(&cfg, &res, AES_GCM_TEST_START_UPDATE_FINISH);
|
||||
}
|
||||
free(input);
|
||||
}
|
||||
|
||||
#endif //CONFIG_MBEDTLS_HARDWARE_AES
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "psa/crypto.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_heap_caps.h"
|
||||
@@ -22,25 +22,48 @@ TEST_CASE("mbedtls AES performance", "[aes][timeout=60]")
|
||||
{
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 32 * 1024;
|
||||
mbedtls_aes_context ctx;
|
||||
float elapsed_usec;
|
||||
uint8_t iv[16];
|
||||
uint8_t key[16];
|
||||
|
||||
psa_status_t status;
|
||||
|
||||
memset(iv, 0xEE, 16);
|
||||
memset(key, 0x44, 16);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
mbedtls_aes_init(&ctx);
|
||||
mbedtls_aes_setkey_enc(&ctx, key, 128);
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
status = psa_import_key(&attributes, key, sizeof(key), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
TEST_FAIL_MESSAGE("Failed to import key");
|
||||
}
|
||||
|
||||
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||
status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Failed to setup AES encryption with status: %ld\n", status);
|
||||
TEST_FAIL_MESSAGE("Failed to setup AES encryption");
|
||||
}
|
||||
|
||||
status = psa_cipher_set_iv(&operation, iv, sizeof(iv));
|
||||
if (status != PSA_SUCCESS) {
|
||||
TEST_FAIL_MESSAGE("Failed to set IV for AES encryption");
|
||||
}
|
||||
|
||||
ccomp_timer_start();
|
||||
size_t output_length = 0;
|
||||
for (int c = 0; c < CALLS; c++) {
|
||||
memset(buf, 0xAA, CALL_SZ);
|
||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, buf, buf);
|
||||
psa_cipher_update(&operation, buf, CALL_SZ, buf, CALL_SZ, &output_length);
|
||||
}
|
||||
psa_cipher_finish(&operation, buf + output_length, CALL_SZ - output_length, &output_length);
|
||||
elapsed_usec = ccomp_timer_stop();
|
||||
|
||||
/* Sanity check: make sure the last ciphertext block matches
|
||||
@@ -63,7 +86,8 @@ TEST_CASE("mbedtls AES performance", "[aes][timeout=60]")
|
||||
};
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16);
|
||||
|
||||
mbedtls_aes_free(&ctx);
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
free(buf);
|
||||
|
||||
// bytes/usec = MB/sec
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_heap_caps.h"
|
||||
@@ -15,6 +13,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if CONFIG_MBEDTLS_HARDWARE_AES || CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
|
||||
@@ -29,18 +28,20 @@ static const uint8_t sha256_thousand_bs[32] = {
|
||||
|
||||
static void tskRunSHA256Test(void *pvParameters)
|
||||
{
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status;
|
||||
size_t hash_length = 0;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false));
|
||||
status = psa_hash_setup(&operation, PSA_ALG_SHA_256);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
for (int j = 0; j < 10; j++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, (unsigned char *)one_hundred_bs, 100));
|
||||
status = psa_hash_update(&operation, (unsigned char *)one_hundred_bs, 100);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256));
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
status = psa_hash_finish(&operation, sha256, sizeof(sha256), &hash_length);
|
||||
operation = psa_hash_operation_init();
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation");
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
@@ -62,10 +63,20 @@ static void tskRunAES256Test(void *pvParameters)
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
};
|
||||
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
for (int i = 0; i <1000; i++)
|
||||
{
|
||||
const unsigned SZ = 1600;
|
||||
mbedtls_aes_context ctx;
|
||||
psa_cipher_operation_t ctx = PSA_CIPHER_OPERATION_INIT;
|
||||
uint8_t nonce[16];
|
||||
|
||||
const uint8_t expected_cipher_end[] = {
|
||||
@@ -86,24 +97,28 @@ static void tskRunAES256Test(void *pvParameters)
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
|
||||
mbedtls_aes_init(&ctx);
|
||||
mbedtls_aes_setkey_enc(&ctx, key_256, 256);
|
||||
psa_cipher_encrypt_setup(&ctx, key_id, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_cipher_set_iv(&ctx, nonce, sizeof(nonce));
|
||||
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
// Encrypt
|
||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, SZ, nonce, plaintext, ciphertext);
|
||||
size_t enc_len = 0;
|
||||
psa_cipher_update(&ctx, plaintext, SZ, ciphertext, SZ, &enc_len);
|
||||
psa_cipher_finish(&ctx, ciphertext + enc_len, SZ - enc_len, &enc_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32);
|
||||
|
||||
// Decrypt
|
||||
memcpy(nonce, iv, 16);
|
||||
mbedtls_aes_setkey_dec(&ctx, key_256, 256);
|
||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, SZ, nonce, ciphertext, decryptedtext);
|
||||
psa_cipher_decrypt_setup(&ctx, key_id, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_cipher_set_iv(&ctx, nonce, sizeof(nonce));
|
||||
psa_cipher_update(&ctx, ciphertext, SZ, decryptedtext, SZ, &enc_len);
|
||||
psa_cipher_finish(&ctx, decryptedtext + enc_len, SZ - enc_len, &enc_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
mbedtls_aes_free(&ctx);
|
||||
psa_cipher_abort(&ctx);
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <sdkconfig.h>
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "esp_types.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -22,8 +22,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "sha/sha_parallel_engine.h"
|
||||
#include "aes/esp_aes.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
static const char *TAG = "test";
|
||||
static volatile bool exit_flag = false;
|
||||
@@ -74,27 +73,33 @@ static void mbedtls_sha256_task(void *pvParameters)
|
||||
SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters;
|
||||
ESP_LOGI(TAG, "mbedtls_sha256_task is started");
|
||||
const char *input = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz~DEL0123456789Space!#$%&()*+,-.0123456789:;<=>?";
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char output[32];
|
||||
unsigned char output_origin[32];
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
psa_hash_operation_t sha256_op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = psa_hash_setup(&sha256_op, PSA_ALG_SHA_256);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
memset(output, 0, sizeof(output));
|
||||
mbedtls_sha256_starts(&sha256_ctx, false);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100);
|
||||
status = psa_hash_update(&sha256_op, (const uint8_t *)input, 100);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
mbedtls_sha256_finish(&sha256_ctx, output);
|
||||
size_t hash_length = 0;
|
||||
status = psa_hash_finish(&sha256_op, output, sizeof(output), &hash_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
memcpy(output_origin, output, sizeof(output));
|
||||
|
||||
while (exit_flag == false) {
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
psa_hash_operation_t sha256_operation = PSA_HASH_OPERATION_INIT;
|
||||
status = psa_hash_setup(&sha256_operation, PSA_ALG_SHA_256);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
memset(output, 0, sizeof(output));
|
||||
mbedtls_sha256_starts(&sha256_ctx, false);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100);
|
||||
status = psa_hash_update(&sha256_operation, (const uint8_t *)input, 100);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
mbedtls_sha256_finish(&sha256_ctx, output);
|
||||
status = psa_hash_finish(&sha256_operation, output, sizeof(output), &hash_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(output, output_origin, sizeof(output), "MBEDTLS SHA256 must match");
|
||||
}
|
||||
@@ -146,7 +151,6 @@ static void rsa_task(void *pvParameters)
|
||||
SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters;
|
||||
ESP_LOGI(TAG, "rsa_task is started");
|
||||
while (exit_flag == false) {
|
||||
mbedtls_rsa_self_test(0);
|
||||
}
|
||||
xSemaphoreGive(*sema);
|
||||
vTaskDelete(NULL);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/private/rsa.h"
|
||||
#include "esp_random.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@@ -38,9 +38,12 @@ TEST_CASE("ds sign test pkcs1_v15", "[ds_rsa]")
|
||||
mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data
|
||||
unsigned int hashlen = sizeof(hash);
|
||||
unsigned char signature[256] = {0};
|
||||
mbedtls_pk_context pk;
|
||||
mbedtls_pk_init(&pk);
|
||||
pk.MBEDTLS_PRIVATE(pk_ctx) = &rsa_ctx;
|
||||
|
||||
// esp_ds is not initialized, so we expect an error
|
||||
int err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
int err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(-1, err);
|
||||
|
||||
// Initialize the esp_ds context
|
||||
@@ -55,7 +58,7 @@ TEST_CASE("ds sign test pkcs1_v15", "[ds_rsa]")
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
// Now we can call esp_ds_rsa_sign again
|
||||
err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
TEST_ASSERT_NOT_NULL(signature);
|
||||
|
||||
@@ -89,9 +92,12 @@ TEST_CASE("ds sign test pkcs1_v21", "[ds_rsa]")
|
||||
mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data
|
||||
unsigned int hashlen = sizeof(hash);
|
||||
unsigned char signature[256] = {0};
|
||||
mbedtls_pk_context pk;
|
||||
mbedtls_pk_init(&pk);
|
||||
pk.MBEDTLS_PRIVATE(pk_ctx) = &rsa_ctx;
|
||||
|
||||
// esp_ds is not initialized, so we expect an error
|
||||
int err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
int err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(-1, err);
|
||||
|
||||
// Initialize the esp_ds context
|
||||
@@ -106,7 +112,7 @@ TEST_CASE("ds sign test pkcs1_v21", "[ds_rsa]")
|
||||
TEST_ASSERT_EQUAL(ESP_OK, err);
|
||||
|
||||
// Now we can call esp_ds_rsa_sign again
|
||||
err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
TEST_ASSERT_NOT_NULL(signature);
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
#include <esp_random.h>
|
||||
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/ecdh.h>
|
||||
#include <mbedtls/ecdsa.h>
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include <mbedtls/private/ecdh.h>
|
||||
#include <mbedtls/private/ecdsa.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include "test_utils.h"
|
||||
#include "ccomp_timer.h"
|
||||
@@ -54,24 +54,20 @@
|
||||
|
||||
TEST_CASE("mbedtls ECDH Generate Key", "[mbedtls]")
|
||||
{
|
||||
mbedtls_ecdh_context ctx;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
psa_key_attributes_t key_attributes;
|
||||
psa_key_id_t key_id;
|
||||
|
||||
mbedtls_ecdh_init(&ctx);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY));
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_bits(&key_attributes, 255);
|
||||
psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) );
|
||||
psa_status_t status = psa_generate_key(&key_attributes, &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ecp_group_load(ACCESS_ECDH(&ctx, grp), MBEDTLS_ECP_DP_CURVE25519) );
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ecdh_gen_public(ACCESS_ECDH(&ctx, grp), ACCESS_ECDH(&ctx, d), ACCESS_ECDH(&ctx, Q),
|
||||
mbedtls_ctr_drbg_random, &ctr_drbg ) );
|
||||
|
||||
mbedtls_ecdh_free(&ctx);
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls ECP self-tests", "[mbedtls]")
|
||||
@@ -82,29 +78,19 @@ TEST_CASE("mbedtls ECP self-tests", "[mbedtls]")
|
||||
TEST_CASE("mbedtls ECP mul w/ koblitz", "[mbedtls]")
|
||||
{
|
||||
/* Test case code via https://github.com/espressif/esp-idf/issues/1556 */
|
||||
mbedtls_entropy_context ctxEntropy;
|
||||
mbedtls_ctr_drbg_context ctxRandom;
|
||||
mbedtls_ecdsa_context ctxECDSA;
|
||||
const char* pers = "myecdsa";
|
||||
|
||||
mbedtls_entropy_init(&ctxEntropy);
|
||||
mbedtls_ctr_drbg_init(&ctxRandom);
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ctr_drbg_seed(&ctxRandom, mbedtls_entropy_func, &ctxEntropy,
|
||||
(const unsigned char*) pers, strlen(pers)) );
|
||||
|
||||
mbedtls_ecdsa_init(&ctxECDSA);
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK( mbedtls_ecdsa_genkey(&ctxECDSA, MBEDTLS_ECP_DP_SECP256K1,
|
||||
mbedtls_ctr_drbg_random, &ctxRandom) );
|
||||
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE) );
|
||||
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_mul(&ctxECDSA.MBEDTLS_PRIVATE(grp), &ctxECDSA.MBEDTLS_PRIVATE(Q),
|
||||
&ctxECDSA.MBEDTLS_PRIVATE(d), &ctxECDSA.MBEDTLS_PRIVATE(grp).G,
|
||||
mbedtls_ctr_drbg_random, &ctxRandom) );
|
||||
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE) );
|
||||
|
||||
mbedtls_ecdsa_free(&ctxECDSA);
|
||||
mbedtls_ctr_drbg_free(&ctxRandom);
|
||||
mbedtls_entropy_free(&ctxEntropy);
|
||||
}
|
||||
|
||||
#if CONFIG_MBEDTLS_HARDWARE_ECC
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* SPDX-FileContributor: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "esp_err.h"
|
||||
@@ -15,9 +15,6 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "entropy_poll.h"
|
||||
@@ -29,6 +26,8 @@
|
||||
#include "esp_crt_bundle.h"
|
||||
#include "esp_random.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "unity_test_utils.h"
|
||||
@@ -55,15 +54,21 @@ extern const uint8_t wrong_sig_crt_pem_end[] asm("_binary_wrong_sig_crt_esp32_
|
||||
extern const uint8_t correct_sig_crt_pem_start[] asm("_binary_correct_sig_crt_esp32_com_pem_start");
|
||||
extern const uint8_t correct_sig_crt_pem_end[] asm("_binary_correct_sig_crt_esp32_com_pem_end");
|
||||
|
||||
// ECDSA test certificates
|
||||
extern const uint8_t ecdsa_correct_sig_crt_pem_start[] asm("_binary_ecdsa_correct_sig_crt_pem_start");
|
||||
extern const uint8_t ecdsa_correct_sig_crt_pem_end[] asm("_binary_ecdsa_correct_sig_crt_pem_end");
|
||||
|
||||
extern const uint8_t ecdsa_wrong_sig_crt_pem_start[] asm("_binary_ecdsa_wrong_sig_crt_pem_start");
|
||||
extern const uint8_t ecdsa_wrong_sig_crt_pem_end[] asm("_binary_ecdsa_wrong_sig_crt_pem_end");
|
||||
|
||||
extern const uint8_t ecdsa_cert_bundle_start[] asm("_binary_ecdsa_cert_bundle_start");
|
||||
extern const uint8_t ecdsa_cert_bundle_end[] asm("_binary_ecdsa_cert_bundle_end");
|
||||
|
||||
#define SEM_TIMEOUT 10000
|
||||
typedef struct {
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_net_context listen_fd;
|
||||
mbedtls_net_context client_fd;
|
||||
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_x509_crt cert;
|
||||
mbedtls_pk_context pkey;
|
||||
@@ -84,12 +89,6 @@ static volatile bool exit_flag;
|
||||
|
||||
esp_err_t endpoint_teardown(mbedtls_endpoint_t *endpoint);
|
||||
|
||||
static int myrand(void *rng_state, unsigned char *output, size_t len)
|
||||
{
|
||||
size_t olen;
|
||||
return mbedtls_hardware_poll(rng_state, output, len, &olen);
|
||||
}
|
||||
|
||||
esp_err_t server_setup(mbedtls_endpoint_t *server)
|
||||
{
|
||||
int ret;
|
||||
@@ -102,8 +101,6 @@ esp_err_t server_setup(mbedtls_endpoint_t *server)
|
||||
mbedtls_ssl_init( &server->ssl );
|
||||
mbedtls_x509_crt_init( &server->cert );
|
||||
mbedtls_pk_init( &server->pkey );
|
||||
mbedtls_entropy_init( &server->entropy );
|
||||
mbedtls_ctr_drbg_init( &server->ctr_drbg );
|
||||
|
||||
ESP_LOGI(TAG, "Loading the server cert and key");
|
||||
ret = mbedtls_x509_crt_parse( &server->cert, server_cert_chain_pem_start,
|
||||
@@ -115,7 +112,7 @@ esp_err_t server_setup(mbedtls_endpoint_t *server)
|
||||
}
|
||||
|
||||
ret = mbedtls_pk_parse_key( &server->pkey, (const unsigned char *)server_pk_start,
|
||||
server_pk_end - server_pk_start, NULL, 0, myrand, NULL );
|
||||
server_pk_end - server_pk_start, NULL, 0);
|
||||
if ( ret != 0 ) {
|
||||
ESP_LOGE(TAG, "mbedtls_pk_parse_key returned %d", ret );
|
||||
return ESP_FAIL;
|
||||
@@ -128,13 +125,6 @@ esp_err_t server_setup(mbedtls_endpoint_t *server)
|
||||
}
|
||||
mbedtls_net_set_nonblock(&server->listen_fd);
|
||||
|
||||
ESP_LOGI(TAG, "Seeding the random number generator");
|
||||
if ( ( ret = mbedtls_ctr_drbg_seed( &server->ctr_drbg, mbedtls_entropy_func, &server->entropy,
|
||||
NULL, 0) ) != 0 ) {
|
||||
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned %d", ret );
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Setting up the SSL data");
|
||||
if ( ( ret = mbedtls_ssl_config_defaults( &server->conf,
|
||||
MBEDTLS_SSL_IS_SERVER,
|
||||
@@ -144,8 +134,6 @@ esp_err_t server_setup(mbedtls_endpoint_t *server)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng( &server->conf, mbedtls_ctr_drbg_random, &server->ctr_drbg );
|
||||
|
||||
if (( ret = mbedtls_ssl_conf_own_cert( &server->conf, &server->cert, &server->pkey ) ) != 0 ) {
|
||||
ESP_LOGE(TAG, "mbedtls_ssl_conf_own_cert returned %d", ret );
|
||||
return ESP_FAIL;
|
||||
@@ -209,9 +197,6 @@ esp_err_t endpoint_teardown(mbedtls_endpoint_t *endpoint)
|
||||
mbedtls_ssl_free( &endpoint->ssl );
|
||||
mbedtls_ssl_config_free( &endpoint->conf );
|
||||
|
||||
mbedtls_ctr_drbg_free( &endpoint->ctr_drbg );
|
||||
mbedtls_entropy_free( &endpoint->entropy );
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -223,19 +208,10 @@ esp_err_t client_setup(mbedtls_endpoint_t *client)
|
||||
mbedtls_esp_enable_debug_log( &client->conf, CONFIG_MBEDTLS_DEBUG_LEVEL );
|
||||
#endif
|
||||
mbedtls_net_init( &client->client_fd );
|
||||
mbedtls_net_init( &client->listen_fd );
|
||||
mbedtls_ssl_init( &client->ssl );
|
||||
mbedtls_x509_crt_init( &client->cert );
|
||||
mbedtls_pk_init( &client->pkey );
|
||||
mbedtls_entropy_init( &client->entropy );
|
||||
mbedtls_ctr_drbg_init( &client->ctr_drbg );
|
||||
|
||||
ESP_LOGI(TAG, "Seeding the random number generator");
|
||||
if ((ret = mbedtls_ctr_drbg_seed(&client->ctr_drbg, mbedtls_entropy_func, &client->entropy,
|
||||
NULL, 0)) != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned %d", ret);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Setting hostname for TLS session...");
|
||||
/* Hostname set here should match CN in server certificate */
|
||||
if ((ret = mbedtls_ssl_set_hostname(&client->ssl, SERVER_ADDRESS)) != 0) {
|
||||
@@ -251,7 +227,6 @@ esp_err_t client_setup(mbedtls_endpoint_t *client)
|
||||
ESP_LOGE(TAG, "mbedtls_ssl_config_defaults returned %d", ret);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
mbedtls_ssl_conf_rng(&client->conf, mbedtls_ctr_drbg_random, &client->ctr_drbg);
|
||||
|
||||
if ((ret = mbedtls_ssl_setup(&client->ssl, &client->conf)) != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%x", -ret);
|
||||
@@ -266,26 +241,26 @@ void client_task(void *pvParameters)
|
||||
SemaphoreHandle_t *client_signal_sem = (SemaphoreHandle_t *) pvParameters;
|
||||
int ret = ESP_FAIL;
|
||||
|
||||
mbedtls_endpoint_t client;
|
||||
mbedtls_endpoint_t *client = calloc(1, sizeof(mbedtls_endpoint_t));
|
||||
esp_crt_validate_res_t res = ESP_CRT_VALIDATE_UNKNOWN;
|
||||
|
||||
if (client_setup(&client) != ESP_OK) {
|
||||
if (client_setup(client) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "SSL client setup failed");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Test with default crt bundle that does not contain the ca crt */
|
||||
ESP_LOGI(TAG, "Connecting to %s:%s...", SERVER_ADDRESS, SERVER_PORT);
|
||||
if ((ret = mbedtls_net_connect(&client.client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
|
||||
if ((ret = mbedtls_net_connect(&client->client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_net_connect returned -%x", -ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Connected.");
|
||||
mbedtls_ssl_set_bio(&client.ssl, &client.client_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
mbedtls_ssl_set_bio(&client->ssl, &client->client_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "Performing the SSL/TLS handshake with bundle that is missing the server root certificate");
|
||||
while ( ( ret = mbedtls_ssl_handshake( &client.ssl ) ) != 0 ) {
|
||||
while ( ( ret = mbedtls_ssl_handshake( &client->ssl ) ) != 0 ) {
|
||||
if ( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) {
|
||||
printf( "mbedtls_ssl_handshake failed with -0x%x\n", -ret );
|
||||
break;
|
||||
@@ -293,7 +268,7 @@ void client_task(void *pvParameters)
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Verifying peer X.509 certificate for bundle ...");
|
||||
ret = mbedtls_ssl_get_verify_result(&client.ssl);
|
||||
ret = mbedtls_ssl_get_verify_result(&client->ssl);
|
||||
|
||||
res = (ret == 0) ? ESP_CRT_VALIDATE_OK : ESP_CRT_VALIDATE_FAIL;
|
||||
|
||||
@@ -305,25 +280,30 @@ void client_task(void *pvParameters)
|
||||
TEST_ASSERT_EQUAL(ESP_CRT_VALIDATE_FAIL, res);
|
||||
|
||||
// Reset session before new connection
|
||||
mbedtls_ssl_close_notify(&client.ssl);
|
||||
mbedtls_ssl_session_reset(&client.ssl);
|
||||
mbedtls_net_free( &client.client_fd);
|
||||
mbedtls_ssl_close_notify(&client->ssl);
|
||||
mbedtls_ssl_session_reset(&client->ssl);
|
||||
mbedtls_net_free( &client->client_fd);
|
||||
|
||||
/* Test with bundle that does contain the CA crt */
|
||||
esp_crt_bundle_attach(&client.conf);
|
||||
esp_crt_bundle_set(server_cert_bundle_start, server_cert_bundle_end - server_cert_bundle_start);
|
||||
ret = esp_crt_bundle_attach(&client->conf);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, ret);
|
||||
|
||||
ret = esp_crt_bundle_set(server_cert_bundle_start, server_cert_bundle_end - server_cert_bundle_start);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, ret);
|
||||
|
||||
ESP_LOGI(TAG, "Connecting to %s:%s...", SERVER_ADDRESS, SERVER_PORT);
|
||||
if ((ret = mbedtls_net_connect(&client.client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
|
||||
if ((ret = mbedtls_net_connect(&client->client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_net_connect returned -%x", -ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Connected.");
|
||||
mbedtls_ssl_set_bio(&client.ssl, &client.client_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
mbedtls_ssl_set_bio(&client->ssl, &client->client_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
|
||||
size_t available_before_handshake = uxTaskGetStackHighWaterMark(NULL);
|
||||
ESP_LOGI(TAG, "Available stack before handshake: %d", available_before_handshake);
|
||||
ESP_LOGI(TAG, "Performing the SSL/TLS handshake with bundle that is missing the server root certificate");
|
||||
while ( ( ret = mbedtls_ssl_handshake( &client.ssl ) ) != 0 ) {
|
||||
while ( ( ret = mbedtls_ssl_handshake( &client->ssl ) ) != 0 ) {
|
||||
if ( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) {
|
||||
printf( "mbedtls_ssl_handshake failed with -0x%x\n", -ret );
|
||||
break;
|
||||
@@ -331,7 +311,7 @@ void client_task(void *pvParameters)
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Verifying peer X.509 certificate for bundle ...");
|
||||
ret = mbedtls_ssl_get_verify_result(&client.ssl);
|
||||
ret = mbedtls_ssl_get_verify_result(&client->ssl);
|
||||
|
||||
res = (ret == 0) ? ESP_CRT_VALIDATE_OK : ESP_CRT_VALIDATE_FAIL;
|
||||
|
||||
@@ -343,17 +323,18 @@ void client_task(void *pvParameters)
|
||||
TEST_ASSERT_EQUAL(ESP_CRT_VALIDATE_OK, res);
|
||||
|
||||
// Reset session before new connection
|
||||
mbedtls_ssl_close_notify(&client.ssl);
|
||||
mbedtls_ssl_session_reset(&client.ssl);
|
||||
mbedtls_net_free( &client.client_fd);
|
||||
mbedtls_ssl_close_notify(&client->ssl);
|
||||
mbedtls_ssl_session_reset(&client->ssl);
|
||||
mbedtls_net_free( &client->client_fd);
|
||||
|
||||
|
||||
exit:
|
||||
mbedtls_ssl_close_notify(&client.ssl);
|
||||
mbedtls_ssl_session_reset(&client.ssl);
|
||||
esp_crt_bundle_detach(&client.conf);
|
||||
endpoint_teardown(&client);
|
||||
mbedtls_ssl_close_notify(&client->ssl);
|
||||
mbedtls_ssl_session_reset(&client->ssl);
|
||||
esp_crt_bundle_detach(&client->conf);
|
||||
endpoint_teardown(client);
|
||||
xSemaphoreGive(*client_signal_sem);
|
||||
free(client);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
@@ -441,6 +422,48 @@ TEST_CASE("custom certificate bundle - wrong signature", "[mbedtls]")
|
||||
esp_crt_bundle_detach(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("custom certificate bundle - ECDSA signature verification", "[mbedtls]")
|
||||
{
|
||||
/* Verify that ECDSA certificates with SHA-512 work correctly with PSA-based verification.
|
||||
* This tests both the ECDSA algorithm path and a different hash algorithm (SHA-512) than
|
||||
* the RSA tests which use SHA-256. */
|
||||
|
||||
mbedtls_x509_crt crt;
|
||||
uint32_t flags = 0;
|
||||
|
||||
esp_crt_bundle_attach(NULL);
|
||||
|
||||
// Set the ECDSA bundle
|
||||
esp_crt_bundle_set(ecdsa_cert_bundle_start, ecdsa_cert_bundle_end - ecdsa_cert_bundle_start);
|
||||
|
||||
// Test: ECDSA certificate with wrong signature should FAIL
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
printf("Testing ECDSA certificate with wrong signature\n");
|
||||
mbedtls_x509_crt_parse(&crt, ecdsa_wrong_sig_crt_pem_start,
|
||||
ecdsa_wrong_sig_crt_pem_end - ecdsa_wrong_sig_crt_pem_start);
|
||||
|
||||
// Verify with the ECDSA bundle - this should fail
|
||||
int verify_result = mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags,
|
||||
esp_crt_verify_callback, NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(0, verify_result);
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
|
||||
// Test: ECDSA certificate with correct signature should PASS
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
printf("Testing ECDSA certificate with correct signature\n");
|
||||
mbedtls_x509_crt_parse(&crt, ecdsa_correct_sig_crt_pem_start,
|
||||
ecdsa_correct_sig_crt_pem_end - ecdsa_correct_sig_crt_pem_start);
|
||||
|
||||
// Verify with the ECDSA bundle - this should succeed
|
||||
verify_result = mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags,
|
||||
esp_crt_verify_callback, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, verify_result);
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
|
||||
esp_crt_bundle_detach(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("custom certificate bundle init API - bound checking - NULL certificate bundle", "[mbedtls]")
|
||||
{
|
||||
esp_err_t esp_ret;
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sys/param.h"
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "esp_heap_caps.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/private/gcm.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "unity.h"
|
||||
|
||||
|
||||
@@ -14,12 +14,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "mbedtls/private/aes.h"
|
||||
#include "mbedtls/private/rsa.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
@@ -48,16 +45,3 @@ TEST_CASE("mbedtls RSA self-tests", "[bignum]")
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_rsa_self_test(1), "RSA self-tests should pass.");
|
||||
verify_apb_access_loop();
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
|
||||
{
|
||||
start_apb_access_loop();
|
||||
#if CONFIG_MBEDTLS_SHA1_C
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass.");
|
||||
#endif
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha256_self_test(1), "SHA256 self-tests should pass.");
|
||||
#if CONFIG_MBEDTLS_SHA512_C
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
#endif
|
||||
verify_apb_access_loop();
|
||||
}
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/ecdh.h>
|
||||
#include <mbedtls/ecdsa.h>
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include <mbedtls/private/ecdh.h>
|
||||
#include <mbedtls/private/ecdsa.h>
|
||||
#include <mbedtls/private/pk_private.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "hal/efuse_ll.h"
|
||||
#include "esp_efuse.h"
|
||||
@@ -194,6 +194,31 @@ void test_ecdsa_verify(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pub_y, plen));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1));
|
||||
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
if (id != MBEDTLS_ECP_DP_SECP192R1) {
|
||||
psa_key_type_t curve_family = PSA_ECC_FAMILY_SECP_R1;
|
||||
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve_family));
|
||||
if (id == MBEDTLS_ECP_DP_SECP256R1) {
|
||||
psa_set_key_bits(&key_attr, 256);
|
||||
}
|
||||
#if SOC_ECDSA_SUPPORT_CURVE_P384
|
||||
else if (id == MBEDTLS_ECP_DP_SECP384R1) {
|
||||
psa_set_key_bits(&key_attr, 384);
|
||||
}
|
||||
#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
|
||||
uint8_t psa_key[2 * plen + 1];
|
||||
psa_key[0] = 0x04; // Uncompressed point indicator
|
||||
memcpy(&psa_key[1], pub_x, plen);
|
||||
memcpy(&psa_key[1 + plen], pub_y, plen);
|
||||
|
||||
psa_status_t status = psa_import_key(&key_attr, psa_key, sizeof(psa_key), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
|
||||
if (id == MBEDTLS_ECP_DP_SECP192R1 || id == MBEDTLS_ECP_DP_SECP256R1) {
|
||||
hash_len = HASH_LEN;
|
||||
}
|
||||
@@ -218,6 +243,31 @@ void test_ecdsa_verify(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8
|
||||
}
|
||||
#endif
|
||||
|
||||
if (id != MBEDTLS_ECP_DP_SECP192R1) {
|
||||
uint8_t signature[2 * plen];
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, signature, plen));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, signature + plen, plen));
|
||||
|
||||
ccomp_timer_start();
|
||||
psa_status_t status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, hash_len,
|
||||
signature, sizeof(signature));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
elapsed_time = ccomp_timer_stop();
|
||||
|
||||
if (id == MBEDTLS_ECP_DP_SECP192R1) {
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(ECDSA_P192_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time));
|
||||
} else if (id == MBEDTLS_ECP_DP_SECP256R1) {
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(ECDSA_P256_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time));
|
||||
}
|
||||
#if SOC_ECDSA_SUPPORT_CURVE_P384
|
||||
else if (id == MBEDTLS_ECP_DP_SECP384R1) {
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(ECDSA_P384_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time));
|
||||
}
|
||||
#endif
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
}
|
||||
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
@@ -553,8 +603,8 @@ void test_ecdsa_export_pubkey(mbedtls_ecp_group_id id, const uint8_t *pub_x, con
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(pub_x, export_pub_x, len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(pub_y, export_pub_y, len);
|
||||
|
||||
mbedtls_ecdsa_free(keypair);
|
||||
mbedtls_pk_free(&key_ctx);
|
||||
/* Use esp_ecdsa_free_pk_context instead of manual cleanup to avoid memory leak */
|
||||
esp_ecdsa_free_pk_context(&key_ctx);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls ECDSA export public key on SECP192R1", "[mbedtls][efuse_key]")
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <sys/param.h>
|
||||
#include <esp_system.h>
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
@@ -1,607 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* mbedTLS SHA unit tests
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "test_apb_dport_access.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "test_utils.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
#if CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
static const unsigned char *one_hundred_as = (unsigned char *)
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
|
||||
static const unsigned char *one_hundred_bs = (unsigned char *)
|
||||
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
|
||||
static const uint8_t sha256_thousand_as[32] = {
|
||||
0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9, 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c,
|
||||
0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t sha256_thousand_bs[32] = {
|
||||
0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b
|
||||
};
|
||||
|
||||
static const uint8_t sha512_thousand_bs[64] = {
|
||||
0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d
|
||||
};
|
||||
|
||||
static const uint8_t sha384_thousand_bs[48] = {
|
||||
0x6d, 0xe5, 0xf5, 0x88, 0x57, 0x60, 0x83, 0xff, 0x7c, 0x94, 0x61, 0x5f, 0x8d, 0x96, 0xf2, 0x76, 0xd5, 0x3f, 0x77, 0x0c, 0x8e, 0xc1, 0xbf, 0xb6, 0x04, 0x27, 0xa4, 0xba, 0xea, 0x6c, 0x68, 0x44, 0xbd, 0xb0, 0x9c, 0xef, 0x6a, 0x09, 0x28, 0xe8, 0x1f, 0xfc, 0x95, 0x03, 0x69, 0x99, 0xab, 0x1a
|
||||
};
|
||||
|
||||
static const uint8_t sha1_thousand_as[20] = {
|
||||
0x29, 0x1e, 0x9a, 0x6c, 0x66, 0x99, 0x49, 0x49, 0xb5, 0x7b, 0xa5,
|
||||
0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba
|
||||
};
|
||||
|
||||
TEST_CASE("mbedtls SHA interleaving", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
mbedtls_sha512_context sha512_ctx;
|
||||
unsigned char sha1[20], sha256[32], sha512[64];
|
||||
|
||||
mbedtls_sha1_init(&sha1_ctx);
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
mbedtls_sha512_init(&sha512_ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts(&sha1_ctx));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&sha512_ctx, false));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_update(&sha1_ctx, one_hundred_as, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, one_hundred_as, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&sha512_ctx, one_hundred_bs, 100));
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish(&sha1_ctx, sha1));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&sha512_ctx, sha512));
|
||||
|
||||
mbedtls_sha1_free(&sha1_ctx);
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
mbedtls_sha512_free(&sha512_ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 calculation");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 calculation");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
|
||||
}
|
||||
|
||||
#define SHA_TASK_STACK_SIZE (10*1024)
|
||||
static SemaphoreHandle_t done_sem;
|
||||
|
||||
static void tskRunSHA1Test(void *pvParameters)
|
||||
{
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
unsigned char sha1[20];
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
mbedtls_sha1_init(&sha1_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts(&sha1_ctx));
|
||||
for (int j = 0; j < 10; j++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_update(&sha1_ctx, (unsigned char *)one_hundred_as, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish(&sha1_ctx, sha1));
|
||||
mbedtls_sha1_free(&sha1_ctx);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void tskRunSHA256Test(void *pvParameters)
|
||||
{
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false));
|
||||
for (int j = 0; j < 10; j++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, (unsigned char *)one_hundred_bs, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256));
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation");
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(4, 0);
|
||||
xTaskCreate(tskRunSHA1Test, "SHA1Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA1Test, "SHA1Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
void tskRunSHASelftests(void *param)
|
||||
{
|
||||
for (int i = 0; i < 5; i++) {
|
||||
#if CONFIG_MBEDTLS_SHA1_C
|
||||
if (mbedtls_sha1_self_test(1)) {
|
||||
printf("SHA1 self-tests failed.\n");
|
||||
while (1) {}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mbedtls_sha256_self_test(1)) {
|
||||
printf("SHA256 self-tests failed.\n");
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C
|
||||
if (mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
if (mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while (1) {}
|
||||
}
|
||||
#endif //SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(2, 0);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests1", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests2", SHA_TASK_STACK_SIZE, NULL, 3, NULL);
|
||||
|
||||
const int TIMEOUT_MS = 40000;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (!xSemaphoreTake(done_sem, TIMEOUT_MS / portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
unsigned char sha512[64];
|
||||
|
||||
mbedtls_sha512_init(&ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&ctx, false));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100));
|
||||
}
|
||||
|
||||
mbedtls_sha512_init(&clone);
|
||||
mbedtls_sha512_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&clone, one_hundred_bs, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&ctx, sha512));
|
||||
mbedtls_sha512_free(&ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 original calculation");
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&clone, sha512));
|
||||
mbedtls_sha512_free(&clone);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA384 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
|
||||
unsigned char sha384[48];
|
||||
|
||||
mbedtls_sha512_init(&ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&ctx, true));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100));
|
||||
}
|
||||
|
||||
mbedtls_sha512_init(&clone);
|
||||
mbedtls_sha512_clone(&clone, &ctx);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&clone, one_hundred_bs, 100));
|
||||
}
|
||||
/* intended warning suppression: is384 == true */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&ctx, sha384));
|
||||
#pragma GCC diagnostic pop
|
||||
mbedtls_sha512_free(&ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation");
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&clone, sha384));
|
||||
#pragma GCC diagnostic pop
|
||||
mbedtls_sha512_free(&clone);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_context clone;
|
||||
unsigned char sha256[64];
|
||||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&ctx, false));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&ctx, one_hundred_as, 100));
|
||||
}
|
||||
|
||||
mbedtls_sha256_init(&clone);
|
||||
mbedtls_sha256_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&ctx, one_hundred_as, 100));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&clone, one_hundred_as, 100));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&ctx, sha256));
|
||||
mbedtls_sha256_free(&ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 original calculation");
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&clone, sha256));
|
||||
mbedtls_sha256_free(&clone);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
mbedtls_sha256_context ctx;
|
||||
uint8_t result[32];
|
||||
int ret;
|
||||
bool done;
|
||||
} finalise_sha_param_t;
|
||||
|
||||
static void tskFinaliseSha(void *v_param)
|
||||
{
|
||||
finalise_sha_param_t *param = (finalise_sha_param_t *)v_param;
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(¶m->ctx, one_hundred_as, 100));
|
||||
}
|
||||
|
||||
param->ret = mbedtls_sha256_finish(¶m->ctx, param->result);
|
||||
mbedtls_sha256_free(¶m->ctx);
|
||||
|
||||
param->done = true;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls SHA session passed between tasks", "[mbedtls]")
|
||||
{
|
||||
finalise_sha_param_t param = { 0 };
|
||||
|
||||
mbedtls_sha256_init(¶m.ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(¶m.ctx, false));
|
||||
for (int i = 0; i < 5; i++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(¶m.ctx, one_hundred_as, 100));
|
||||
}
|
||||
|
||||
// pass the SHA context off to a different task
|
||||
//
|
||||
// note: at the moment this doesn't crash even if a mutex semaphore is used as the
|
||||
// engine lock, but it can crash...
|
||||
xTaskCreate(tskFinaliseSha, "SHAFinalise", SHA_TASK_STACK_SIZE, ¶m, 3, NULL);
|
||||
|
||||
while (!param.done) {
|
||||
vTaskDelay(1);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, param.ret);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, param.result, 32, "SHA256 result from other task");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Random input generated and hashed using python:
|
||||
|
||||
import hashlib
|
||||
import os, binascii
|
||||
|
||||
input = bytearray(os.urandom(150))
|
||||
arr = ''
|
||||
for idx, b in enumerate(input):
|
||||
if idx % 8 == 0:
|
||||
arr += '\n'
|
||||
arr += "{}, ".format(hex(b))
|
||||
digest = hashlib.sha256(input).hexdigest()
|
||||
|
||||
*/
|
||||
const uint8_t test_vector[] = {
|
||||
0xe4, 0x1a, 0x1a, 0x30, 0x71, 0xd3, 0x94, 0xb0,
|
||||
0xc3, 0x7e, 0x99, 0x9f, 0x1a, 0xde, 0x4a, 0x36,
|
||||
0xb1, 0x1, 0x81, 0x2b, 0x41, 0x91, 0x11, 0x7f,
|
||||
0xd8, 0xe1, 0xd5, 0xe5, 0x52, 0x6d, 0x92, 0xee,
|
||||
0x6c, 0xf7, 0x70, 0xea, 0x3a, 0xb, 0xc9, 0x97,
|
||||
0xc0, 0x12, 0x6f, 0x10, 0x5b, 0x90, 0xd8, 0x52,
|
||||
0x91, 0x69, 0xea, 0xc4, 0x1f, 0xc, 0xcf, 0xc6,
|
||||
0xf0, 0x43, 0xc6, 0xa3, 0x1f, 0x46, 0x3c, 0x3d,
|
||||
0x25, 0xe5, 0xa8, 0x27, 0x86, 0x85, 0x32, 0x3f,
|
||||
0x33, 0xd8, 0x40, 0xc4, 0x41, 0xf6, 0x4b, 0x12,
|
||||
0xd8, 0x5e, 0x4, 0x27, 0x42, 0x90, 0x73, 0x4,
|
||||
0x8, 0x42, 0xd1, 0x64, 0xd, 0x84, 0x3, 0x1,
|
||||
0x76, 0x88, 0xe4, 0x95, 0xdf, 0xe7, 0x62, 0xb4,
|
||||
0xb3, 0xb2, 0x7e, 0x6d, 0x78, 0xca, 0x79, 0x82,
|
||||
0xcc, 0xba, 0x22, 0xd2, 0x90, 0x2e, 0xe3, 0xa8,
|
||||
0x2a, 0x53, 0x3a, 0xb1, 0x9a, 0x7f, 0xb7, 0x8b,
|
||||
0xfa, 0x32, 0x47, 0xc1, 0x5c, 0x6, 0x4f, 0x7b,
|
||||
0xcd, 0xb3, 0xf4, 0xf1, 0xd0, 0xb5, 0xbf, 0xfb,
|
||||
0x7c, 0xc3, 0xa5, 0xb2, 0xc4, 0xd4,
|
||||
};
|
||||
|
||||
const uint8_t test_vector_digest[] = {
|
||||
0xff, 0x1c, 0x60, 0xcb, 0x21, 0xf0, 0x63, 0x68,
|
||||
0xb9, 0xfc, 0xfe, 0xad, 0x3e, 0xb0, 0x2e, 0xd1,
|
||||
0xf9, 0x08, 0x82, 0x82, 0x83, 0x06, 0xc1, 0x8a,
|
||||
0x98, 0x5d, 0x36, 0xc0, 0xb7, 0xeb, 0x35, 0xe0,
|
||||
};
|
||||
|
||||
|
||||
TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, test_vector, sizeof(test_vector)));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256));
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(test_vector_digest, sha256, 32, "SHA256 calculation");
|
||||
}
|
||||
|
||||
/* Function are not implemented in SW */
|
||||
#if CONFIG_MBEDTLS_HARDWARE_SHA && SOC_SHA_SUPPORT_SHA512_T
|
||||
|
||||
/*
|
||||
* FIPS-180-2 test vectors
|
||||
*/
|
||||
static unsigned char sha512T_test_buf[2][113] = {
|
||||
{ "abc" },
|
||||
{
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
}
|
||||
};
|
||||
|
||||
static const size_t sha512T_test_buflen[2] = {
|
||||
3, 112
|
||||
};
|
||||
|
||||
static const esp_sha_type sha512T_algo[4] = {
|
||||
SHA2_512224, SHA2_512256, SHA2_512T, SHA2_512T
|
||||
};
|
||||
|
||||
static const size_t sha512T_t_len[4] = { 224, 256, 224, 256 };
|
||||
|
||||
static const unsigned char sha512_test_sum[4][32] = {
|
||||
/* SHA512-224 */
|
||||
{
|
||||
0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54,
|
||||
0xda, 0xae, 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2,
|
||||
0x0e, 0x37, 0xed, 0x26, 0x5c, 0xee, 0xe9, 0xa4,
|
||||
0x3e, 0x89, 0x24, 0xaa
|
||||
},
|
||||
{
|
||||
0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23,
|
||||
0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33,
|
||||
0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72,
|
||||
0x68, 0x67, 0x4a, 0xf9
|
||||
},
|
||||
|
||||
/* SHA512-256 */
|
||||
{
|
||||
0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9,
|
||||
0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab,
|
||||
0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46,
|
||||
0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23
|
||||
},
|
||||
{
|
||||
0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8,
|
||||
0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe,
|
||||
0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14,
|
||||
0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a
|
||||
}
|
||||
|
||||
/* For SHA512_T testing we use t=224 & t=256
|
||||
* so the hash digest should be same as above
|
||||
*/
|
||||
};
|
||||
|
||||
/* This will run total of 8 test cases, 2 for each of the below MODE
|
||||
* SHA512/224, SHA512/256, SHA512/t with t=224 & SHA512/t with t=256
|
||||
*
|
||||
* Test is disabled for ESP32 as there is no hardware for SHA512/t
|
||||
*/
|
||||
TEST_CASE("mbedtls SHA512/t", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context sha512_ctx;
|
||||
unsigned char sha512[64], k;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
k = i * 2 + j;
|
||||
mbedtls_sha512_init(&sha512_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&sha512_ctx, false));
|
||||
esp_sha512_set_mode(&sha512_ctx, sha512T_algo[i]);
|
||||
if (i > 1) {
|
||||
k = (i - 2) * 2 + j;
|
||||
esp_sha512_set_t(&sha512_ctx, sha512T_t_len[i]);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&sha512_ctx, sha512T_test_buf[j], sha512T_test_buflen[j]));
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&sha512_ctx, sha512));
|
||||
mbedtls_sha512_free(&sha512_ctx);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_test_sum[k], sha512, sha512T_t_len[i] / 8, "SHA512t calculation");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
|
||||
#ifdef CONFIG_SPIRAM_USE_MALLOC
|
||||
#include "test_mbedtls_utils.h"
|
||||
TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]")
|
||||
{
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 16 * 1024;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
// allocate external memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
TEST_ASSERT(esp_ptr_external_ram(buf));
|
||||
memset(buf, 0x54, CALL_SZ);
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false));
|
||||
for (int c = 0; c < CALLS; c++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, buf, CALL_SZ));
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256));
|
||||
|
||||
free(buf);
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
|
||||
/* Check the result. Reference value can be calculated using:
|
||||
* dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\124' | sha256sum
|
||||
*/
|
||||
const char *expected_hash = "8d031167bd706ac337e07aa9129c34ae4ae792d0a79a2c70e7f012102e8adc3d";
|
||||
char hash_str[sizeof(sha256) * 2 + 1];
|
||||
utils_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256));
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str);
|
||||
|
||||
}
|
||||
|
||||
#if SOC_SHA_SUPPORT_DMA
|
||||
TEST_CASE("mbedtls SHA256 PSRAM DMA large buffer", "[hw_crypto]")
|
||||
{
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
const size_t SZ = 257984; // specific size to cover issue in https://github.com/espressif/esp-idf/issues/11915
|
||||
void *buffer = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
TEST_ASSERT_NOT_NULL(buffer);
|
||||
memset(buffer, 0x55, SZ);
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
int r = mbedtls_sha256_starts(&sha256_ctx, false);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
r = mbedtls_sha256_update(&sha256_ctx, buffer, SZ);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
r = mbedtls_sha256_finish(&sha256_ctx, sha256);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
free(buffer);
|
||||
|
||||
/* Check the result. Reference value can be calculated using:
|
||||
* dd if=/dev/zero bs=257984 count=1 | tr '\000' '\125' | sha256sum
|
||||
*/
|
||||
const char *expected_hash = "f2330c9f81ff1c8f0515247faa82be8b6f9685601de6f5dae79172766f136c33";
|
||||
|
||||
char hash_str[sizeof(sha256) * 2 + 1];
|
||||
utils_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256));
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str);
|
||||
}
|
||||
#endif // SOC_SHA_SUPPORT_DMA
|
||||
|
||||
#endif //CONFIG_SPIRAM_USE_MALLOC
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK && !CONFIG_IDF_TARGET_ESP32H2
|
||||
// Not enough rtc memory for test on H2
|
||||
|
||||
TEST_CASE("mbedtls SHA stack in RTC RAM", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateBinary();
|
||||
static StaticTask_t rtc_task;
|
||||
size_t STACK_SIZE = 3072;
|
||||
uint8_t *rtc_stack = heap_caps_calloc(STACK_SIZE, 1, MALLOC_CAP_RTCRAM);
|
||||
|
||||
TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack));
|
||||
|
||||
TEST_ASSERT_NOT_NULL(xTaskCreateStatic(tskRunSHA256Test, "tskRunSHA256Test_task", STACK_SIZE, NULL,
|
||||
3, rtc_stack, &rtc_task));
|
||||
TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS));
|
||||
|
||||
/* Give task time to cleanup before freeing stack */
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
free(rtc_stack);
|
||||
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
#endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK
|
||||
|
||||
#if CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM && CONFIG_SPIRAM_USE_MALLOC
|
||||
|
||||
TEST_CASE("mbedtls SHA stack in PSRAM", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateBinary();
|
||||
static StaticTask_t psram_task;
|
||||
size_t STACK_SIZE = 3072;
|
||||
uint8_t *psram_stack = heap_caps_calloc(STACK_SIZE, 1, MALLOC_CAP_SPIRAM);
|
||||
|
||||
TEST_ASSERT(esp_ptr_external_ram(psram_stack));
|
||||
|
||||
TEST_ASSERT_NOT_NULL(xTaskCreateStatic(tskRunSHA256Test, "tskRunSHA256Test_task", STACK_SIZE, NULL,
|
||||
3, psram_stack, &psram_task));
|
||||
TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS));
|
||||
|
||||
/* Give task time to cleanup before freeing stack */
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
free(psram_stack);
|
||||
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
#endif //CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM && CONFIG_SPIRAM_USE_MALLOC
|
||||
#endif // CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
@@ -0,0 +1,869 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
static const uint8_t key_256[] = {
|
||||
0x00, 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,
|
||||
};
|
||||
|
||||
TEST_CASE("PSA AES-CTR multipart", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 16;
|
||||
const size_t part_size = 8;
|
||||
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
uint8_t iv[iv_SZ];
|
||||
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_CTR;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Encrypt */
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
memset(iv, 0x3B, iv_SZ); // Initialize IV with known value
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
/* Decrypt */
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-ECB multipart", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 112;
|
||||
const size_t iv_SZ = 16;
|
||||
const size_t part_size = 16;
|
||||
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
uint8_t iv[iv_SZ];
|
||||
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Encrypt */
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
memset(iv, 0x3B, iv_SZ); // Initialize IV with known value
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg));
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
/* Decrypt */
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-CBC multipart", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 112; // Multiple of block size (16)
|
||||
const size_t iv_SZ = 16;
|
||||
const size_t part_size = 16; // Process one block at a time
|
||||
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
uint8_t iv[iv_SZ];
|
||||
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Encrypt */
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
memset(iv, 0x3B, iv_SZ); // Initialize IV with known value
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
/* Decrypt */
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-CBC-PKCS7 multipart", "[psa-aes]")
|
||||
{
|
||||
// Test both aligned and unaligned sizes
|
||||
const size_t SZ1 = 112; // Multiple of block size (16)
|
||||
const size_t SZ2 = 123; // Not a multiple of block size
|
||||
const size_t iv_SZ = 16;
|
||||
const size_t part_size = 16;
|
||||
|
||||
uint8_t *plaintext1 = malloc(SZ1);
|
||||
uint8_t *ciphertext1 = malloc(SZ1 + 16); // Extra block for padding
|
||||
uint8_t *decryptedtext1 = malloc(SZ1 + 16); // Extra space for intermediate buffering
|
||||
|
||||
uint8_t *plaintext2 = malloc(SZ2);
|
||||
uint8_t *ciphertext2 = malloc(SZ2 + 16); // Extra block for padding
|
||||
uint8_t *decryptedtext2 = malloc(SZ2 + 16); // Extra space for intermediate buffering
|
||||
|
||||
uint8_t iv[iv_SZ];
|
||||
|
||||
// Initialize test data
|
||||
memset(plaintext1, 0x3A, SZ1);
|
||||
memset(plaintext2, 0x3B, SZ2);
|
||||
memset(ciphertext1, 0x0, SZ1 + 16);
|
||||
memset(ciphertext2, 0x0, SZ2 + 16);
|
||||
memset(decryptedtext1, 0x0, SZ1 + 16);
|
||||
memset(decryptedtext2, 0x0, SZ2 + 16);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Test 1: Block-aligned input */
|
||||
{
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
memset(iv, 0x3C, iv_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
|
||||
// Process all blocks except the last one
|
||||
for (size_t offset = 0; offset < SZ1 - part_size; offset += part_size) {
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext1 + offset, part_size,
|
||||
ciphertext1 + total_out_len, SZ1 + 16 - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
// Process the last block separately
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext1 + SZ1 - part_size, part_size,
|
||||
ciphertext1 + total_out_len, SZ1 + 16 - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext1 + total_out_len,
|
||||
SZ1 + 16 - total_out_len, &out_len)); // Space for padding block
|
||||
total_out_len += out_len;
|
||||
|
||||
// The output size should be the input size rounded up to the next multiple of 16
|
||||
TEST_ASSERT_EQUAL_size_t((SZ1 + 16), total_out_len); // Should include padding block
|
||||
/* Decrypt */
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t dec_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < total_out_len; offset += part_size) {
|
||||
size_t this_part = total_out_len - offset < part_size ? total_out_len - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext1 + offset, this_part,
|
||||
decryptedtext1 + dec_len, SZ1 + 16 - dec_len, &out_len));
|
||||
dec_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext1 + dec_len,
|
||||
SZ1 + 16 - dec_len, &out_len));
|
||||
dec_len += out_len;
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(SZ1, dec_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext1, decryptedtext1, SZ1);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
}
|
||||
|
||||
/* Test 2: Non-block-aligned input */
|
||||
{
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
memset(iv, 0x3D, iv_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ2; offset += part_size) {
|
||||
size_t this_part = SZ2 - offset < part_size ? SZ2 - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext2 + offset, this_part,
|
||||
ciphertext2 + total_out_len, SZ2 + 16 - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext2 + total_out_len,
|
||||
SZ2 + 16 - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
|
||||
/* Decrypt */
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t dec_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < total_out_len; offset += part_size) {
|
||||
size_t this_part = total_out_len - offset < part_size ? total_out_len - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext2 + offset, this_part,
|
||||
decryptedtext2 + dec_len, SZ2 + 16 - dec_len, &out_len));
|
||||
dec_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext2 + dec_len,
|
||||
SZ2 + 16 - dec_len, &out_len));
|
||||
dec_len += out_len;
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(SZ2, dec_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext2, decryptedtext2, SZ2);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
free(plaintext1);
|
||||
free(ciphertext1);
|
||||
free(decryptedtext1);
|
||||
free(plaintext2);
|
||||
free(ciphertext2);
|
||||
free(decryptedtext2);
|
||||
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-CFB multipart", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 16;
|
||||
const size_t part_size = 8;
|
||||
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
uint8_t iv[iv_SZ];
|
||||
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_CFB;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Encrypt */
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
memset(iv, 0x3B, iv_SZ); // Initialize IV with known value
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
/* Decrypt */
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-OFB multipart", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 16;
|
||||
const size_t part_size = 8;
|
||||
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
uint8_t iv[iv_SZ];
|
||||
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_OFB;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Encrypt */
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
memset(iv, 0x3B, iv_SZ); // Initialize IV with known value
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
/* Decrypt */
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len,
|
||||
SZ - total_out_len, &out_len));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-CTR streaming chunk invariance", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 16;
|
||||
|
||||
// Vectors match legacy mbedtls CTR stream test
|
||||
const uint8_t expected_cipher[] = {
|
||||
0xc5, 0x78, 0xa7, 0xb4, 0xf3, 0xb9, 0xcb, 0x8b,
|
||||
0x09, 0xe0, 0xd6, 0x89, 0x14, 0x6a, 0x19, 0x09,
|
||||
0xde, 0xaf, 0x37, 0x19, 0x32, 0x4d, 0xca, 0xf6,
|
||||
0xff, 0x6e, 0xd2, 0x5d, 0x87, 0x51, 0xaa, 0x8c,
|
||||
0x1c, 0xe3, 0x3b, 0xbb, 0x18, 0xf5, 0xa0, 0x1b,
|
||||
0xdc, 0x29, 0x52, 0x63, 0xf6, 0x5d, 0x49, 0x85,
|
||||
0x29, 0xf1, 0xf0, 0x69, 0x8f, 0xa6, 0x9f, 0x38,
|
||||
0x5c, 0xdd, 0x26, 0xf8, 0x9d, 0x40, 0xa1, 0xff,
|
||||
0x52, 0x46, 0xe1, 0x72, 0x70, 0x39, 0x73, 0xff,
|
||||
0xd0, 0x5e, 0xe5, 0x3f, 0xc5, 0xed, 0x5c, 0x18,
|
||||
0xa7, 0x84, 0xd8, 0xdf, 0x9d, 0xb5, 0x06, 0xb1,
|
||||
0xa7, 0xcf, 0x2e, 0x7a, 0x51, 0xfc, 0x44, 0xc5,
|
||||
0xb9, 0x5f, 0x22, 0x47,
|
||||
};
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[iv_SZ];
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
|
||||
memset(key, 0x44, sizeof(key));
|
||||
memset(iv, 0xEE, iv_SZ);
|
||||
memset(plaintext, 0xAA, SZ);
|
||||
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CTR);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key, sizeof(key), &key_id));
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
for (size_t chunk = 1; chunk < SZ; chunk++) {
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len = 0, total_out = 0;
|
||||
|
||||
memset(iv, 0xEE, iv_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, PSA_ALG_CTR));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += chunk) {
|
||||
size_t this_part = SZ - offset < chunk ? SZ - offset : chunk;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out,
|
||||
SZ - total_out, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out = 0;
|
||||
memset(iv, 0xEE, iv_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, PSA_ALG_CTR));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += chunk) {
|
||||
size_t this_part = SZ - offset < chunk ? SZ - offset : chunk;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out,
|
||||
SZ - total_out, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
psa_cipher_abort(&dec_op);
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-OFB streaming chunk invariance", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 16;
|
||||
|
||||
// Vectors match legacy mbedtls OFB stream test
|
||||
const uint8_t expected_cipher[] = {
|
||||
0xc5, 0x78, 0xa7, 0xb4, 0xf3, 0xb9, 0xcb, 0x8b,
|
||||
0x09, 0xe0, 0xd6, 0x89, 0x14, 0x6a, 0x19, 0x09,
|
||||
0x0a, 0x33, 0x8b, 0xab, 0x82, 0xcb, 0x20, 0x8f,
|
||||
0x74, 0x2a, 0x6c, 0xb3, 0xc6, 0xe8, 0x18, 0x89,
|
||||
0x09, 0xb6, 0xaf, 0x20, 0xcd, 0xea, 0x74, 0x14,
|
||||
0x48, 0x61, 0xe8, 0x4d, 0x50, 0x12, 0x9f, 0x5e,
|
||||
0xb8, 0x10, 0x53, 0x3b, 0x74, 0xd9, 0xd0, 0x95,
|
||||
0x13, 0xdc, 0x14, 0xcf, 0x0c, 0xa1, 0x90, 0xfd,
|
||||
0xa2, 0x58, 0x12, 0xb2, 0x00, 0x2c, 0x5b, 0x7a,
|
||||
0x2a, 0x76, 0x80, 0x20, 0x82, 0x39, 0xa2, 0x21,
|
||||
0xf8, 0x7a, 0xec, 0xae, 0x82, 0x6a, 0x5c, 0xd3,
|
||||
0x04, 0xd9, 0xbd, 0xe4, 0x53, 0xc9, 0xdf, 0x67,
|
||||
0xaa, 0x5c, 0xaf, 0xa6,
|
||||
};
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[iv_SZ];
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
|
||||
memset(key, 0x44, sizeof(key));
|
||||
memset(iv, 0xEE, iv_SZ);
|
||||
memset(plaintext, 0xAA, SZ);
|
||||
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_OFB);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key, sizeof(key), &key_id));
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
for (size_t chunk = 1; chunk < SZ; chunk++) {
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len = 0, total_out = 0;
|
||||
|
||||
memset(iv, 0xEE, iv_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, PSA_ALG_OFB));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += chunk) {
|
||||
size_t this_part = SZ - offset < chunk ? SZ - offset : chunk;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out,
|
||||
SZ - total_out, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out = 0;
|
||||
memset(iv, 0xEE, iv_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, PSA_ALG_OFB));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
for (size_t offset = 0; offset < SZ; offset += chunk) {
|
||||
size_t this_part = SZ - offset < chunk ? SZ - offset : chunk;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out += out_len;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out,
|
||||
SZ - total_out, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
psa_cipher_abort(&dec_op);
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-CFB-128", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 1000;
|
||||
const size_t iv_SZ = 16;
|
||||
const uint8_t expected_cipher_end[] = {
|
||||
0xf3, 0x64, 0x20, 0xa1, 0x70, 0x2a, 0xd9, 0x3f,
|
||||
0xb7, 0x48, 0x8c, 0x2c, 0x1f, 0x65, 0x53, 0xc2,
|
||||
0xac, 0xfd, 0x82, 0xe5, 0x31, 0x24, 0x1f, 0x30,
|
||||
0xaf, 0xcc, 0x8d, 0xb3, 0xf3, 0x63, 0xe1, 0xa0,
|
||||
};
|
||||
|
||||
const uint8_t iv_seed[] = {
|
||||
0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
|
||||
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
|
||||
};
|
||||
uint8_t iv[iv_SZ];
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
|
||||
memcpy(iv, iv_seed, iv_SZ);
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CFB);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT;
|
||||
size_t out_len = 0, total_out = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, PSA_ALG_CFB));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ));
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext, SZ, ciphertext, SZ, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out, SZ - total_out, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - sizeof(expected_cipher_end), sizeof(expected_cipher_end));
|
||||
|
||||
psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT;
|
||||
total_out = 0;
|
||||
memcpy(iv, iv_seed, iv_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, PSA_ALG_CFB));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ));
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext, SZ, decryptedtext, SZ, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out, SZ - total_out, &out_len));
|
||||
total_out += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
psa_cipher_abort(&enc_op);
|
||||
psa_cipher_abort(&dec_op);
|
||||
psa_destroy_key(key_id);
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("PSA AES-CBC one-shot", "[psa-aes]")
|
||||
{
|
||||
const size_t SZ = 1600;
|
||||
const size_t iv_SZ = 16;
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *plaintext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *ciphertext = heap_caps_malloc(SZ + iv_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
uint8_t *decryptedtext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(psa_import_key(&attributes, key_256, sizeof(key_256), &key_id), PSA_SUCCESS);
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
size_t ciphertext_len = 0;
|
||||
/* Encrypt the plaintext */
|
||||
TEST_ASSERT_EQUAL(psa_cipher_encrypt(key_id, alg, plaintext, SZ, ciphertext, SZ + iv_SZ, &ciphertext_len), PSA_SUCCESS);
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(ciphertext_len, SZ + iv_SZ);
|
||||
|
||||
size_t decryptedtext_len = 0;
|
||||
/* Decrypt the ciphertext */
|
||||
TEST_ASSERT_EQUAL(psa_cipher_decrypt(key_id, alg, ciphertext, SZ + iv_SZ, decryptedtext, SZ, &decryptedtext_len), PSA_SUCCESS);
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(decryptedtext_len, SZ);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
static const uint8_t key_256[] = {
|
||||
0x00, 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,
|
||||
};
|
||||
|
||||
TEST_CASE("PSA AES-GCM multipart", "[psa-aes-gcm]")
|
||||
{
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV
|
||||
const size_t tag_SZ = 16; // GCM tag size
|
||||
const size_t aad_SZ = 16; // Size of Additional Authenticated Data
|
||||
const size_t part_size = 8;
|
||||
|
||||
size_t tag_length = 0;
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
uint8_t iv[iv_SZ];
|
||||
uint8_t tag[tag_SZ];
|
||||
uint8_t aad[aad_SZ];
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
|
||||
// Initialize test data
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
memset(iv, 0x3B, iv_SZ);
|
||||
memset(aad, 0x3C, aad_SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_GCM;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Encrypt */
|
||||
psa_aead_operation_t enc_op = PSA_AEAD_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&enc_op, aad_SZ, SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&enc_op, iv, iv_SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&enc_op, aad, aad_SZ));
|
||||
|
||||
// Process the plaintext in parts
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
// Finish encryption and get the tag
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_finish(&enc_op,
|
||||
ciphertext + total_out_len,
|
||||
SZ - total_out_len,
|
||||
&out_len,
|
||||
tag,
|
||||
tag_SZ,
|
||||
&tag_length));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
/* Decrypt */
|
||||
psa_aead_operation_t dec_op = PSA_AEAD_OPERATION_INIT;
|
||||
total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&dec_op, aad_SZ, SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&dec_op, iv, iv_SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&dec_op, aad, aad_SZ));
|
||||
|
||||
// Process the ciphertext in parts
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
// Verify the tag and finish decryption
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_verify(&dec_op,
|
||||
decryptedtext + total_out_len,
|
||||
SZ - total_out_len,
|
||||
&out_len,
|
||||
tag,
|
||||
tag_SZ));
|
||||
total_out_len += out_len;
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, total_out_len);
|
||||
|
||||
// Verify the decrypted data matches the original plaintext
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
/* Cleanup */
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
psa_aead_abort(&enc_op);
|
||||
psa_aead_abort(&dec_op);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
|
||||
TEST_CASE("PSA AES-GCM one-shot", "[psa-aes-gcm]")
|
||||
{
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV
|
||||
const size_t tag_SZ = 16; // GCM tag size
|
||||
const size_t aad_SZ = 16; // Size of Additional Authenticated Data
|
||||
|
||||
// Allocate memory with proper alignment
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ + tag_SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
uint8_t *iv = malloc(iv_SZ);
|
||||
uint8_t *aad = malloc(aad_SZ);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
TEST_ASSERT_NOT_NULL(iv);
|
||||
TEST_ASSERT_NOT_NULL(aad);
|
||||
|
||||
// Initialize test data
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(ciphertext, 0, SZ + tag_SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
memset(iv, 0x3B, iv_SZ);
|
||||
memset(aad, 0x3C, aad_SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_GCM;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
size_t output_length;
|
||||
|
||||
/* One-shot encrypt */
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt(key_id, alg,
|
||||
iv, iv_SZ,
|
||||
aad, aad_SZ,
|
||||
plaintext, SZ,
|
||||
ciphertext, SZ + tag_SZ,
|
||||
&output_length));
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(SZ + tag_SZ, output_length);
|
||||
|
||||
/* One-shot decrypt */
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt(key_id, alg,
|
||||
iv, iv_SZ,
|
||||
aad, aad_SZ,
|
||||
ciphertext, SZ + tag_SZ,
|
||||
decryptedtext, SZ,
|
||||
&output_length));
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, output_length);
|
||||
|
||||
// Verify the decrypted data matches the original plaintext
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
/* Cleanup */
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
free(iv);
|
||||
free(aad);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/* PSA CMAC test
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "psa/crypto.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_utils.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
#if CONFIG_MBEDTLS_CMAC_C
|
||||
static const uint8_t key_128[] = {
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
};
|
||||
|
||||
static const uint8_t key_256[] = {
|
||||
0x00, 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,
|
||||
};
|
||||
|
||||
static const uint8_t test_data[] = {
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51
|
||||
};
|
||||
|
||||
// Expected CMAC values from the mbedtls implementation
|
||||
static const uint8_t expected_cmac_128[] = {
|
||||
0x93, 0xae, 0x18, 0x36, 0xdf, 0xbd, 0x91, 0x06,
|
||||
0xa5, 0xd1, 0x84, 0x5c, 0xe5, 0x61, 0x02, 0xe2,
|
||||
};
|
||||
|
||||
static const uint8_t expected_cmac_256[] = {
|
||||
0x35, 0x17, 0x99, 0xb0, 0xfd, 0xb1, 0x5b, 0x47,
|
||||
0x98, 0xe3, 0x47, 0xef, 0xa3, 0xb4, 0xe1, 0x89,
|
||||
};
|
||||
|
||||
static const uint8_t expected_cmac_zero_length[] = {
|
||||
0xd8, 0xa8, 0x58, 0x43, 0x62, 0xe9, 0x93, 0xf8,
|
||||
0xd5, 0x29, 0x24, 0xf6, 0x39, 0x07, 0xc4, 0x88,
|
||||
};
|
||||
|
||||
TEST_CASE("PSA CMAC AES-128 test", "[psa_cmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CMAC);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
// Import the key
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Allocate internal memory for CMAC output
|
||||
uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(cmac);
|
||||
|
||||
size_t cmac_length = 0;
|
||||
|
||||
// Calculate CMAC
|
||||
status = psa_mac_compute(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
&cmac_length);
|
||||
ESP_LOGI("PSA CMAC AES-128", "Status: %ld", status);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(16, cmac_length);
|
||||
ESP_LOG_BUFFER_HEXDUMP("CMAC AES-128", cmac, cmac_length, ESP_LOG_INFO);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac, 16);
|
||||
|
||||
// Verify CMAC
|
||||
status = psa_mac_verify(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
expected_cmac_128, sizeof(expected_cmac_128));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Cleanup
|
||||
psa_destroy_key(key_id);
|
||||
free(cmac);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
TEST_CASE("PSA CMAC AES-256 test", "[psa_cmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CMAC);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
|
||||
// Import the key
|
||||
status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Allocate internal memory for CMAC output
|
||||
uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 256, PSA_ALG_CMAC),
|
||||
MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(cmac);
|
||||
|
||||
size_t cmac_length = 0;
|
||||
|
||||
// Calculate CMAC
|
||||
status = psa_mac_compute(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 256, PSA_ALG_CMAC),
|
||||
&cmac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(16, cmac_length);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_256, cmac, 16);
|
||||
|
||||
// Verify CMAC
|
||||
status = psa_mac_verify(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
expected_cmac_256, sizeof(expected_cmac_256));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Cleanup
|
||||
psa_destroy_key(key_id);
|
||||
free(cmac);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
TEST_CASE("PSA CMAC AES-128 multipart test", "[psa_cmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CMAC);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
// Import the key
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Allocate internal memory for CMAC output
|
||||
uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(cmac);
|
||||
|
||||
size_t cmac_length = 0;
|
||||
|
||||
// Test multipart operation with different chunk sizes
|
||||
for (size_t chunk_size = 1; chunk_size < sizeof(test_data); chunk_size++) {
|
||||
// Setup operation
|
||||
status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
// Process data in chunks
|
||||
for (size_t offset = 0; offset < sizeof(test_data); offset += chunk_size) {
|
||||
size_t current_chunk_size = (offset + chunk_size > sizeof(test_data)) ?
|
||||
(sizeof(test_data) - offset) : chunk_size;
|
||||
|
||||
status = psa_mac_update(&operation, test_data + offset, current_chunk_size);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
|
||||
// Finish operation
|
||||
status = psa_mac_sign_finish(&operation, cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
&cmac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(16, cmac_length);
|
||||
// Verify result
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac, 16);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
psa_destroy_key(key_id);
|
||||
free(cmac);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
TEST_CASE("PSA CMAC AES-128 multipart verify test", "[psa_cmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CMAC);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
// Import the key
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Allocate internal memory for CMAC output
|
||||
uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(cmac);
|
||||
|
||||
size_t cmac_length = 0;
|
||||
|
||||
status = psa_mac_compute(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
&cmac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(16, cmac_length);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac, 16);
|
||||
|
||||
// Verify CMAC multipart
|
||||
psa_mac_operation_t verify_operation = PSA_MAC_OPERATION_INIT;
|
||||
status = psa_mac_verify_setup(&verify_operation, key_id, PSA_ALG_CMAC);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_update(&verify_operation, test_data, sizeof(test_data));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_verify_finish(&verify_operation, cmac, cmac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Modify one byte of cmac and check for failure
|
||||
cmac[0] = cmac[0] + 1;
|
||||
|
||||
status = psa_mac_verify_setup(&verify_operation, key_id, PSA_ALG_CMAC);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_update(&verify_operation, test_data, sizeof(test_data));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_verify_finish(&verify_operation, cmac, cmac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
|
||||
|
||||
// Cleanup
|
||||
psa_destroy_key(key_id);
|
||||
free(cmac);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
TEST_CASE("PSA CMAC zero-length test", "[psa_cmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CMAC);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
// Import the key
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Allocate internal memory for CMAC output
|
||||
uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(cmac);
|
||||
|
||||
size_t cmac_length = 0;
|
||||
|
||||
// Calculate CMAC on zero-length data
|
||||
status = psa_mac_compute(key_id, PSA_ALG_CMAC,
|
||||
NULL, 0,
|
||||
cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC),
|
||||
&cmac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(16, cmac_length);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_zero_length, cmac, 16);
|
||||
|
||||
// Verify CMAC
|
||||
status = psa_mac_verify(key_id, PSA_ALG_CMAC,
|
||||
NULL, 0,
|
||||
expected_cmac_zero_length, sizeof(expected_cmac_zero_length));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Cleanup
|
||||
psa_destroy_key(key_id);
|
||||
free(cmac);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
TEST_CASE("PSA CMAC memory alignment test", "[psa_cmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CMAC);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
// Import the key
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Allocate memory with different capabilities
|
||||
uint8_t *cmac_internal = heap_caps_malloc(16, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
uint8_t *cmac_dma = heap_caps_malloc(16, MALLOC_CAP_DMA|MALLOC_CAP_8BIT);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(cmac_internal);
|
||||
TEST_ASSERT_NOT_NULL(cmac_dma);
|
||||
|
||||
size_t cmac_length_internal = 0;
|
||||
size_t cmac_length_dma = 0;
|
||||
|
||||
// Calculate CMAC with internal memory
|
||||
status = psa_mac_compute(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
cmac_internal, 16,
|
||||
&cmac_length_internal);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(16, cmac_length_internal);
|
||||
|
||||
// Calculate CMAC with DMA-capable memory
|
||||
status = psa_mac_compute(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
cmac_dma, 16,
|
||||
&cmac_length_dma);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
TEST_ASSERT_EQUAL(16, cmac_length_dma);
|
||||
|
||||
// Results should be identical
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac_internal, 16);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac_dma, 16);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(cmac_internal, cmac_dma, 16);
|
||||
|
||||
// Cleanup
|
||||
psa_destroy_key(key_id);
|
||||
free(cmac_internal);
|
||||
free(cmac_dma);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
TEST_CASE("PSA CMAC verify failure test", "[psa_cmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CMAC);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
// Import the key
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Create an invalid CMAC by modifying one byte
|
||||
uint8_t invalid_cmac[16];
|
||||
memcpy(invalid_cmac, expected_cmac_128, 16);
|
||||
invalid_cmac[0] ^= 0x01; // Flip one bit
|
||||
|
||||
// Verify should fail with the modified CMAC
|
||||
status = psa_mac_verify(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
invalid_cmac, sizeof(invalid_cmac));
|
||||
TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
|
||||
|
||||
// Verify should succeed with the correct CMAC
|
||||
status = psa_mac_verify(key_id, PSA_ALG_CMAC,
|
||||
test_data, sizeof(test_data),
|
||||
expected_cmac_128, sizeof(expected_cmac_128));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Cleanup
|
||||
psa_destroy_key(key_id);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
#endif /* CONFIG_MBEDTLS_CMAC_C */
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "unity.h"
|
||||
|
||||
static const uint8_t key_256[] = {
|
||||
0x00, 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,
|
||||
};
|
||||
|
||||
TEST_CASE("PSA ARIA-GCM multipart", "[psa-gcm]")
|
||||
{
|
||||
// TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_crypto_init());
|
||||
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV
|
||||
const size_t tag_SZ = 16; // GCM tag size
|
||||
const size_t aad_SZ = 16; // Size of Additional Authenticated Data
|
||||
const size_t part_size = 8;
|
||||
|
||||
// Allocate memory with proper alignment
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ + tag_SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
uint8_t *iv = malloc(iv_SZ);
|
||||
uint8_t *aad = malloc(aad_SZ);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
TEST_ASSERT_NOT_NULL(iv);
|
||||
TEST_ASSERT_NOT_NULL(aad);
|
||||
|
||||
// Initialize test data
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(ciphertext, 0, SZ + tag_SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
memset(iv, 0x3B, iv_SZ);
|
||||
memset(aad, 0x3C, aad_SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_GCM;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ARIA);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Encrypt */
|
||||
psa_aead_operation_t enc_op = PSA_AEAD_OPERATION_INIT;
|
||||
size_t out_len, total_out_len = 0;
|
||||
size_t tag_length = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt_setup(&enc_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&enc_op, aad_SZ, SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&enc_op, iv, iv_SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&enc_op, aad, aad_SZ));
|
||||
|
||||
// Process the plaintext in parts
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&enc_op, plaintext + offset, this_part,
|
||||
ciphertext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
// Finish encryption and get the tag
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_finish(&enc_op,
|
||||
ciphertext + total_out_len,
|
||||
SZ + tag_SZ - total_out_len,
|
||||
&out_len,
|
||||
ciphertext + SZ,
|
||||
tag_SZ,
|
||||
&tag_length));
|
||||
total_out_len += out_len;
|
||||
|
||||
/* Decrypt */
|
||||
psa_aead_operation_t dec_op = PSA_AEAD_OPERATION_INIT;
|
||||
total_out_len = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt_setup(&dec_op, key_id, alg));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&dec_op, aad_SZ, SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&dec_op, iv, iv_SZ));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&dec_op, aad, aad_SZ));
|
||||
|
||||
// Process the ciphertext in parts
|
||||
for (size_t offset = 0; offset < SZ; offset += part_size) {
|
||||
size_t this_part = SZ - offset < part_size ? SZ - offset : part_size;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&dec_op, ciphertext + offset, this_part,
|
||||
decryptedtext + offset, this_part, &out_len));
|
||||
total_out_len += out_len;
|
||||
}
|
||||
|
||||
// Verify the tag and finish decryption
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_verify(&dec_op,
|
||||
decryptedtext + total_out_len,
|
||||
SZ - total_out_len,
|
||||
&out_len,
|
||||
ciphertext + SZ,
|
||||
tag_SZ));
|
||||
total_out_len += out_len;
|
||||
|
||||
// Verify the decrypted data matches the original plaintext
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
/* Cleanup */
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
free(iv);
|
||||
free(aad);
|
||||
|
||||
psa_aead_abort(&enc_op);
|
||||
psa_aead_abort(&dec_op);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
|
||||
TEST_CASE("PSA ARIA-GCM one-shot", "[psa-gcm]")
|
||||
{
|
||||
// TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_crypto_init());
|
||||
|
||||
const size_t SZ = 100;
|
||||
const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV
|
||||
const size_t tag_SZ = 16; // GCM tag size
|
||||
const size_t aad_SZ = 16; // Size of Additional Authenticated Data
|
||||
|
||||
// Allocate memory with proper alignment
|
||||
uint8_t *plaintext = malloc(SZ);
|
||||
uint8_t *ciphertext = malloc(SZ + tag_SZ);
|
||||
uint8_t *decryptedtext = malloc(SZ);
|
||||
uint8_t *iv = malloc(iv_SZ);
|
||||
uint8_t *aad = malloc(aad_SZ);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(plaintext);
|
||||
TEST_ASSERT_NOT_NULL(ciphertext);
|
||||
TEST_ASSERT_NOT_NULL(decryptedtext);
|
||||
TEST_ASSERT_NOT_NULL(iv);
|
||||
TEST_ASSERT_NOT_NULL(aad);
|
||||
|
||||
// Initialize test data
|
||||
memset(plaintext, 0x3A, SZ);
|
||||
memset(ciphertext, 0, SZ + tag_SZ);
|
||||
memset(decryptedtext, 0x0, SZ);
|
||||
memset(iv, 0x3B, iv_SZ);
|
||||
memset(aad, 0x3C, aad_SZ);
|
||||
|
||||
/* Import a key */
|
||||
psa_key_id_t key_id;
|
||||
psa_algorithm_t alg = PSA_ALG_GCM;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ARIA);
|
||||
psa_set_key_bits(&attributes, sizeof(key_256) * 8);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id));
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
size_t output_length;
|
||||
|
||||
/* One-shot encrypt */
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt(key_id, alg,
|
||||
iv, iv_SZ,
|
||||
aad, aad_SZ,
|
||||
plaintext, SZ,
|
||||
ciphertext, SZ + tag_SZ,
|
||||
&output_length));
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(SZ + tag_SZ, output_length);
|
||||
|
||||
/* One-shot decrypt */
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt(key_id, alg,
|
||||
iv, iv_SZ,
|
||||
aad, aad_SZ,
|
||||
ciphertext, SZ + tag_SZ,
|
||||
decryptedtext, SZ,
|
||||
&output_length));
|
||||
|
||||
TEST_ASSERT_EQUAL_size_t(SZ, output_length);
|
||||
|
||||
// Verify the decrypted data matches the original plaintext
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ);
|
||||
|
||||
/* Cleanup */
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
free(iv);
|
||||
free(aad);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_id);
|
||||
// mbedtls_psa_crypto_free();
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/* PSA HMAC test
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "unity.h"
|
||||
static const uint8_t key_128[] = {
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
};
|
||||
|
||||
static const uint8_t test_data[] = {
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51
|
||||
};
|
||||
|
||||
static const uint8_t expected_hmac_128[] = {
|
||||
0x00, 0x7a, 0x5a, 0xd6, 0x54, 0x96, 0x5b, 0xcd,
|
||||
0x30, 0xc1, 0x60, 0x62, 0xec, 0xac, 0x75, 0xfb,
|
||||
0x87, 0x71, 0x0e, 0x13
|
||||
};
|
||||
|
||||
TEST_CASE("PSA HMAC SHA-1 test", "[psa_hmac]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
// Initialize PSA Crypto
|
||||
status = PSA_SUCCESS;
|
||||
// TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// Set up key attributes
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_1));
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
|
||||
uint8_t *hmac = malloc(PSA_HASH_LENGTH(PSA_ALG_SHA_1));
|
||||
TEST_ASSERT_NOT_NULL(hmac);
|
||||
|
||||
status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
size_t mac_length = 0;
|
||||
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1),
|
||||
test_data, sizeof(test_data),
|
||||
hmac, PSA_HASH_LENGTH(PSA_ALG_SHA_1), &mac_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
status = psa_mac_verify(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1),
|
||||
test_data, sizeof(test_data),
|
||||
expected_hmac_128, sizeof(expected_hmac_128));
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
free(hmac);
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/pem.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "unity.h"
|
||||
#include "ccomp_timer.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
typedef enum {
|
||||
PSA_RSA_KEY_SIZE_2048,
|
||||
PSA_RSA_KEY_SIZE_3072,
|
||||
PSA_RSA_KEY_SIZE_4096,
|
||||
} psa_rsa_key_size_t;
|
||||
|
||||
static const char privkey_4096_buf[] = "-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIIJKAIBAAKCAgEA1blr9wfIzTylroJHxcoq+YFA765gF5vj9b6tfaPG0XQExSkjndHv5sra4ar7T+k2sBB4OcKKeGHkNk6wk8tGmOS79r2L74XZs1eB0UruG+huV7Sd+YiWzwN8y9jGImA9hIkf1qxIvkco5WTmT7cVwUnCQ7qiiVadD/LgyeGD04yKZpzv9UJzfjXz5ITTn/ejcn7423M9qz41nhRWwK4zw1jv7IB57d1dWOCbN3RO4dvfVndCz8DOmLzJrZAkLsz39vppbIwbMqTXKFxWqzZY2xrYmnMx9p3v4hLeju7ls3fsekESonoP0C76u50wJfZWO2XcIUo4pue/jHi2o9KouhLXW/vyasplXvE6FFrBjSpsm1Nar4KQMUolEkUbO9baGcQvH9G5WOH0kwPt7AOSqM2EUPvBd7Jv0tbMI/BRZVVltC/t6WhannCM/I6nZrlNe5tie/qYlFu474jp5/tpa8RykkDxwl9whejIqd4iQbvDiP/GXgBYtDJ9VU/S2KqHJhQFLDi+F3+ewOcF391fgt1e1J2vNYLKZOfxTOl/1vJbU/2IjRWTRQ7cXnmpR/GNCRfgH2as6Z/0oknBSVephguDnO5QlveP4Cx2EOVY/A/KgDpu8PumSrlIk+YQgLxdKsXaVI6eDY4rY7q2uCJH3yIAfZJXEeD+ResUuSZltvECAwEAAQKCAgBwR89+oipOGHR6b5tBP+q/1bXFtXhqLs3eBuSiQu5qj2cKJYi+mtJMD3paYDdTThQa/ywKPDf+8n6wQTrnCj32iQRupjnkBg/O9kQPLixVoRCHJy5vL+D6tLxVY3cEDEeFX3zIjQ5SWJQVn6KXcnoNZ7CVYHGPcV9mR5TsuntFImp7aituUBDY14NgJKABRFosBqS6tZpKYo5MlCbXZy1ujUTOnNhxrIAj9yvUQFhIs/hrNpB1ELf46gWSF03LAIesyvWjvx9yxcL7QzeNDyozQbFVwvsWsvaZcIxXzw4B8RjdSV5+2V2BY4z6D6SB7R50ahjxrEqC9PFe3PQmsL9OvFjV9idYwFOhxiWXGjIm3wwFFLOj3e0TShscj2Iw+Ghd3wApvSdBZxzdjap1NHC+Q6yYU+BnivxUHcopVPPM3rsLndyRC6zfrQw/OkOlAP3bNL1hRedPRmRDOz0V1ihEpgC1VfXx6XOu4eg8xWiJgWX+BGvT5GWjfQg2hB1Jm344r3l0eLhr25dO80GIac2QGT2+WmYkXcsQ3AiqAn2VF8UB5mU+Iyh96jmSFVVltGZgfp98yFYN63/7wB++lhVQmJZwbglutng1qjQBFslIULddIHiYvF+AVvkrO3Hc2zg8rT91tbE13k06A1zlNGcQuQKLax8e+2/BNjsZU2E4uQKCAQEA7L4obKWYRHgG6j1VEDRrQU8Vkm4L11B+ZD/rsEh3q7LbzViOPv+1dZ40jX2qYScWyaefI46bukJlk/mlNv4Dh3EnSFvHPCInDM3oImCYImwUx0hkbSRyRNwlwRwx81LJzIR84cCqpNWrXXcplomUSM62ea1E1vtNSZs9Bg2OLoWvFOTPgk/xDi6ezdb6JFiId6cARup/bmZ363mg8jCq0wpTLVdUGrezfMj4GpB1uQET5xqXleumQu/04cHPOfXwpV0ikIOId/ldY/PetiRd86B32aB2Xd4fHUpxHMY+63MFmL6SsqMQJMPubv+eIrOId4HhT+nXNFBZXolT5XG5NwKCAQEA5xvvccHNyCTL0AebxD6EihWnp0/Dd0DwXWxZw0Yhhc9xa/W/QtygB6kPb35oKGvCKdm4dWCIGln03dU5D6CMNkJlbkxpo8gybz34SJ/6OvU836rBLHZXE3Xiqbe5XkdMdarA7kTEhEUqekDXPxhws9dWh0YjtAnBPpm1GQppiykI2edkiIhRgju5ghe+/UjAjxrEgCKZeAODh46hwZHERRKQN2MFUOFcOVDq+2wTJem9r3h1uBQAiZn8PDyx0rlRkwH2dZSSauVW+I713N0JGucOV7FeMO0ebioqqckh0i91ZJNH//Io8Sp8WuBsU/vcP9jT+5BDkCbc71BRO/AFFwKCAQBj4a6oeA0QBhvUw9+ZoKQHv9f4GZnBU+KfZSCJFWn39NQrhMsu5S+n2gGOGJDDwHwqxB+uHsKxCMZWciM0WmMex6ytKJucUURscIsZxespyrPRiEdmjNPxHXiISt8AK9OcB+GwVVsphERygI35Rz5aoWv3VhUPJqNrBKXwYdO06Q3/ILIz5oprU1wIuER9BSU+ZiUFxnXRHEZIAN7Yj5Piyh5hqNCBHTQK17dlbcFdNokxHdUKmYth/l8wyFYnvA21lt+4XOY8x+aQ/xjde+ZvnSozlTGbVNWHxBqI61MsfzDDStQVrhpniIqWJh6PwXM4CIII9z2mgqfR7NqKmTptAoIBAQDTYQOigmZbFvyrayoXVi8XtTLAnv3jByxR5pY7OtvSbagJ3J1w5CYim4iYq39M6TKP4KkMApy5rWl/tFQabPeRcS0gsxc0TBmFEaMTme7fGgrxcFZ6+koubHZCUN5k0sWmIeWQiKlNaY2uf7vf49TBSMXFuGtTclCjlybCnnlmZMPJuhCDqFsUyNelm15+f5pPyWXM5NiFooEc7WIZj996Zb4uSo1EKruVWONzzqe814s9AOp60SCkuoiv97uVRxbLZNItPRSmXNktQmSx/CEl0AuYPYwvJ9HbZQncfTBH9ExlDyidernjyr4uyHGMZyJN614ICy0gncsZv9ZtAd1FAoIBAA4toGPU/VcKFmK92zgO05jsg5vJzw5xeoxRWKrLg7iby6Su6BuNgaVwfYWeZuOhnXakid7FvFXKH6x44o9gyFm5bKqFhaXDzAnxzqcLeM5V+gititOsstpZCbVOoKQOhgTHyxpFNVX3E/nB8EunydWyhQMxKme//NsRroFm1vWljQKyL3zER82AzyseEpEYZoB/6g0n5uF2lR7KllxeBlINsceQ8g3JkmJTdS1hoXcyUSsZ+EgrRbCykNB5aVC5G3/W1OSZsFHbbMrYHCMnaYKwMqLmOkb11o6nOrJJ4pgHj8CVcp2TNjfy3y0Ru6RZ42b0Q+3LktJBGu9r5d04FgI=\n"
|
||||
"-----END RSA PRIVATE KEY-----";
|
||||
|
||||
static const char privkey_2048_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n"
|
||||
"MIIEowIBAAKCAQEA8N8hdkemvj6Tpk975/OWhv9BrTsCBCu+ZYfDb5VI7U2meKBg\r\n"
|
||||
"3dAkyyhRlY3fNwSRzBUMCzsHjpgnsB40wxOgiwlB9n6PMhq0qUVKAdCpKwFztsKd\r\n"
|
||||
"JJAsCUC+Zlwxn4RpH6ZnMl3a/njRYjuDyI32kucMP/lBRo7ks1798Gy/j+x1h5xA\r\n"
|
||||
"vZSlFoEXKjCC6S1DWhALePuZnk4m/jGP6g+YfyJXSTqsenKa/DcWndfn/JoElZ0J\r\n"
|
||||
"nhud8lBXwVe6mMheE1yqfL+VTU1nwg/TPNZrZsFz2sXig/RQCKt6LuSuzhRpsLp+\r\n"
|
||||
"BdwqEs9xrwlhZnp7j4kQBomISd6kAxQfYVROHQIDAQABAoIBAHgtO4rB8QWWPyCJ\r\n"
|
||||
"I670r7OnA2OkvzrJgHMzq2SuvPX4+gfRLMM+qDzcXugZIrdWhk+maJ3p07lnXNXY\r\n"
|
||||
"HEcAMedstQaA2n0LKfwSX/xL2TtlvBABRVoKvI3ZSaXUdcW60KBD69ULUsoICZ/T\r\n"
|
||||
"Rcr4WX+t20TH3bOQc7ayvEwKVgE95xIUpTH9asw8uOPvKxW2j5OLQgZuWrWyUDg0\r\n"
|
||||
"MFh92PhWtw3i5zq6OpTTsFJeceKYV/VstIYjZ+FslmhjQxJbr+2DJRbpHXKceqy6\r\n"
|
||||
"9yWlSV0EM7neFCHlDa2WPhK8we+6IvMiNVQKj46fHGYNBaW/ZSX7TiG5J0Uqj2e9\r\n"
|
||||
"0MUGJ8ECgYEA+frJabhfzW5+JfGjTObeznJZE6fAOjFzaBIwFu8Kz2mIjYpQlwVK\r\n"
|
||||
"EepMkv2KkrJuqS4GnI+Nkq7G0BAUyUj9tTJ3HQzvtJrxsnxVi99Yofx1s1P4YAnu\r\n"
|
||||
"c8t3ElJoQ4BRoQIs/hIvyYn22IxllBHiGESrnPQ38D82xyXQgd6S8JkCgYEA9qww\r\n"
|
||||
"j7jx6Xpy/D1Dq8Dvalm7pz3J+yHnti4w2cqZ67grUoyGnNPtciNDdfi4JzLiKkUu\r\n"
|
||||
"SDS3DacvFpFyND0m8sbpMjnR8Rvhj+bfH8KcOAowD+YR/+6vSb/P/aBt6gYXcaBn\r\n"
|
||||
"cjepx+sE81mnC7UrHb4TjG4hO5t3ZTc6X28gyCUCgYAMZn9lSisecrO5SCJUp0M4\r\n"
|
||||
"NH3stq6XdGqIKBbQnG0J2u9WLh1PUIjbGKdRx1f/bPCGXe0gCRL5yse7/IA7d+51\r\n"
|
||||
"9ZnpDAI8EE+bDgXkWWD5MB/alHjGstdsURSICSR47L2f4g6/T8GlGr3vAg/r53My\r\n"
|
||||
"xv1IXOkFdu1NtbeBKbxaSQKBgENDmw5mAVmIcXiFAEICn4ahp4EoYT6g9T2BhQKu\r\n"
|
||||
"s6BKnU2qUj7Lr5ETOp8dzqGpx3B9Yux/q3cGotmFmd3S2x8SzJ5MlAoqbyy9aRSR\r\n"
|
||||
"DeZeKNL9CuV+YcA7lOz1ZWOOe7AZbHwB38NLPBNb3CheI769iTkfAuLtNvabw8go\r\n"
|
||||
"VokdAoGBALyvBhW+Squ5tx8NOEgAisakhAVOnT6jcoeKy6FyjcvKaWagmCOCC7Gz\r\n"
|
||||
"QB9Yf1tJ+3di+aLtWWdmU494iKJHBtPMhfrYltCpxHHQGlUc/GLPY3Z5bBYYYWpb\r\n"
|
||||
"Wzw4ZvDraKlAs7a9CRwS5cpktk5ptK4rc5noSXkvV+yOT75zXat2\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
static const char privkey_3072_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n"
|
||||
"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\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
// Keep the old version for reference (has issues with PSA-based PK)
|
||||
static int pem_to_der_rsa_key(const char *pem_key, size_t pem_key_len,
|
||||
uint8_t *der_buf, size_t der_buf_size,
|
||||
uint8_t **der_data_ptr, size_t *der_len)
|
||||
{
|
||||
// Use direct PEM parsing instead of PK layer for PSA compatibility
|
||||
// return pem_to_der_rsa_key_direct(pem_key, pem_key_len, der_buf, der_buf_size,
|
||||
// der_data_ptr, der_len);
|
||||
|
||||
mbedtls_pk_context pk;
|
||||
int ret;
|
||||
|
||||
mbedtls_pk_init(&pk);
|
||||
|
||||
// Parse PEM key
|
||||
ret = mbedtls_pk_parse_key(&pk,
|
||||
(const uint8_t *)pem_key,
|
||||
pem_key_len,
|
||||
NULL, 0); // No password
|
||||
if (ret != 0) {
|
||||
char error_buf[100];
|
||||
mbedtls_strerror(ret, error_buf, sizeof(error_buf));
|
||||
printf("mbedtls_pk_parse_key failed: -0x%04x - %s\n", -ret, error_buf);
|
||||
mbedtls_pk_free(&pk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Write key to DER format
|
||||
// NOTE: mbedtls_pk_write_key_der writes to the END of the buffer!
|
||||
// Returns the length on success, or negative error code
|
||||
printf("Attempting to write DER key (buffer size: %zu)...\n", der_buf_size);
|
||||
ret = mbedtls_pk_write_key_der(&pk, der_buf, der_buf_size);
|
||||
if (ret < 0) {
|
||||
char error_buf[100];
|
||||
mbedtls_strerror(ret, error_buf, sizeof(error_buf));
|
||||
printf("mbedtls_pk_write_key_der failed: -0x%04x - %s\n", -ret, error_buf);
|
||||
mbedtls_pk_free(&pk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
printf("DER key written successfully, length: %d\n", ret);
|
||||
|
||||
// ret contains the length of DER data
|
||||
*der_len = ret;
|
||||
|
||||
// Calculate the start position of DER data (at end of buffer)
|
||||
*der_data_ptr = der_buf + der_buf_size - ret;
|
||||
|
||||
mbedtls_pk_free(&pk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static psa_key_id_t import_rsa_key(psa_rsa_key_size_t key_size)
|
||||
{
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
int ret;
|
||||
|
||||
// Convert PEM to DER format
|
||||
uint8_t *der_buf = calloc(1, 10000); // Buffer for DER-encoded key (data written at end)
|
||||
uint8_t *der_key = NULL; // Pointer to actual DER data location
|
||||
size_t der_key_len = 0;
|
||||
|
||||
char *key_buf = NULL;
|
||||
|
||||
if (key_size == PSA_RSA_KEY_SIZE_2048) {
|
||||
key_buf = (char *)privkey_2048_buf;
|
||||
} else if (key_size == PSA_RSA_KEY_SIZE_3072) {
|
||||
key_buf = (char *)privkey_3072_buf;
|
||||
} else if (key_size == PSA_RSA_KEY_SIZE_4096) {
|
||||
key_buf = (char *)privkey_4096_buf;
|
||||
} else {
|
||||
printf("Unsupported key size for import_rsa_key\n");
|
||||
free(der_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = pem_to_der_rsa_key(key_buf,
|
||||
strlen(key_buf) + 1, // Include null terminator
|
||||
der_buf,
|
||||
10000,
|
||||
&der_key, // Returns pointer to DER data
|
||||
&der_key_len);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
// Configure key attributes for RSA encryption/decryption
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
|
||||
psa_set_key_usage_flags(&attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
|
||||
size_t key_bits = 0;
|
||||
if (key_size == PSA_RSA_KEY_SIZE_2048) {
|
||||
key_bits = 2048;
|
||||
} else if (key_size == PSA_RSA_KEY_SIZE_3072) {
|
||||
key_bits = 3072;
|
||||
} else if (key_size == PSA_RSA_KEY_SIZE_4096) {
|
||||
key_bits = 4096;
|
||||
}
|
||||
psa_set_key_bits(&attributes, key_bits);
|
||||
|
||||
status = psa_import_key(&attributes,
|
||||
der_key, // Pointer to DER data (at end of buffer)
|
||||
der_key_len,
|
||||
&key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("PSA import failed with error: %ld (0x%x)\n", status, (unsigned int)status);
|
||||
printf("Expected error codes:\n");
|
||||
printf(" PSA_ERROR_INVALID_ARGUMENT = %ld\n", PSA_ERROR_INVALID_ARGUMENT);
|
||||
printf(" PSA_ERROR_NOT_SUPPORTED = %ld\n", PSA_ERROR_NOT_SUPPORTED);
|
||||
printf(" PSA_ERROR_INSUFFICIENT_MEMORY = %ld\n", PSA_ERROR_INSUFFICIENT_MEMORY);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
free(der_buf);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
return key_id;
|
||||
}
|
||||
|
||||
TEST_CASE("test performance RSA key operations", "[bignum]")
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_rsa_key_size_t keysize = PSA_RSA_KEY_SIZE_2048;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// Use der_key (not der_buf) as it points to the actual DER data at end of buffer
|
||||
psa_key_id_t key_id = import_rsa_key(keysize);
|
||||
printf("RSA key imported successfully (key_id: %u)\n", (unsigned int)key_id);
|
||||
|
||||
size_t ciphertext_size = 0;
|
||||
if (keysize == PSA_RSA_KEY_SIZE_2048) {
|
||||
ciphertext_size = 256; // 2048 bits / 8
|
||||
} else if (keysize == PSA_RSA_KEY_SIZE_3072) {
|
||||
ciphertext_size = 384; // 3072 bits / 8
|
||||
} else if (keysize == PSA_RSA_KEY_SIZE_4096) {
|
||||
ciphertext_size = 512; // 4096 bits / 8
|
||||
} else {
|
||||
printf("Unsupported key size for ciphertext size calculation\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t plaintext[] = "Test message for RSA encryption";
|
||||
size_t plaintext_len = sizeof(plaintext);
|
||||
uint8_t ciphertext[ciphertext_size]; // RSA 2048-bit key produces 256-byte ciphertext
|
||||
size_t ciphertext_len = sizeof(ciphertext);
|
||||
uint8_t decrypted[ciphertext_size];
|
||||
size_t decrypted_len = sizeof(decrypted);
|
||||
size_t encrypt_len = 0;
|
||||
|
||||
#ifdef SOC_CCOMP_TIMER_SUPPORTED
|
||||
int public_perf, private_perf;
|
||||
ccomp_timer_start();
|
||||
#endif
|
||||
// Encrypt the plaintext
|
||||
status = psa_asymmetric_encrypt(key_id,
|
||||
PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
plaintext,
|
||||
plaintext_len,
|
||||
NULL,
|
||||
0,
|
||||
ciphertext,
|
||||
ciphertext_len,
|
||||
&encrypt_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
#ifdef SOC_CCOMP_TIMER_SUPPORTED
|
||||
public_perf = ccomp_timer_stop();
|
||||
#endif // SOC_CCOMP_TIMER_SUPPORTED
|
||||
|
||||
size_t decrypt_len = 0;
|
||||
#ifdef SOC_CCOMP_TIMER_SUPPORTED
|
||||
ccomp_timer_start();
|
||||
#endif
|
||||
// Decrypt the ciphertext
|
||||
status = psa_asymmetric_decrypt(key_id,
|
||||
PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
ciphertext,
|
||||
encrypt_len,
|
||||
NULL,
|
||||
0,
|
||||
decrypted,
|
||||
decrypted_len,
|
||||
&decrypt_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
#ifdef SOC_CCOMP_TIMER_SUPPORTED
|
||||
private_perf = ccomp_timer_stop();
|
||||
#endif // SOC_CCOMP_TIMER_SUPPORTED
|
||||
|
||||
// Verify decrypted data matches original plaintext
|
||||
TEST_ASSERT_EQUAL(plaintext_len, decrypt_len);
|
||||
|
||||
#ifdef SOC_CCOMP_TIMER_SUPPORTED
|
||||
printf("RSA Key Size: %d bits\n", (keysize == PSA_RSA_KEY_SIZE_2048) ? 2048 :
|
||||
(keysize == PSA_RSA_KEY_SIZE_3072) ? 3072 : 4096);
|
||||
printf("Encryption took %d us, Decryption took %d us\n", public_perf, private_perf);
|
||||
|
||||
if (keysize == PSA_RSA_KEY_SIZE_2048) {
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PUBLIC_OP, "%d us", public_perf);
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PRIVATE_OP, "%d us", private_perf);
|
||||
} else if (keysize == 4096) {
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PUBLIC_OP, "%d us", public_perf);
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PRIVATE_OP, "%d us", private_perf);
|
||||
}
|
||||
#endif // SOC_CCOMP_TIMER_SUPPORTED
|
||||
psa_destroy_key(key_id);
|
||||
keysize++;
|
||||
}
|
||||
}
|
||||
@@ -1,611 +0,0 @@
|
||||
/* mbedTLS RSA functionality tests
|
||||
*
|
||||
* Focus on testing functionality where we use ESP32 hardware
|
||||
* accelerated crypto features
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_system.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include "entropy_poll.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "memory_checks.h"
|
||||
#include "ccomp_timer.h"
|
||||
|
||||
#define PRINT_DEBUG_INFO
|
||||
|
||||
/* Taken from openssl s_client -connect api.gigafive.com:443 -showcerts
|
||||
*/
|
||||
static const char *rsa4096_cert = "-----BEGIN CERTIFICATE-----\n"\
|
||||
"MIIExzCCA6+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBkjELMAkGA1UEBhMCVVMx\n"\
|
||||
"CzAJBgNVBAgMAkNBMRQwEgYDVQQHDAtTYW50YSBDbGFyYTElMCMGA1UECgwcR2ln\n"\
|
||||
"YWZpdmUgVGVjaG5vbG9neSBQYXJ0bmVyczEZMBcGA1UEAwwQR2lnYWZpdmUgUm9v\n"\
|
||||
"dCBDQTEeMBwGCSqGSIb3DQEJARYPY2FAZ2lnYWZpdmUuY29tMB4XDTE2MDgyNzE2\n"\
|
||||
"NDYyM1oXDTI2MDgyNTE2NDYyM1owgZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD\n"\
|
||||
"QTEUMBIGA1UEBwwLU2FudGEgQ2xhcmExKTAnBgNVBAoMIEdpZ2FmaXZlIFRlY2hu\n"\
|
||||
"b2xvZ3kgUGFydG5lcnMgTExDMRkwFwYDVQQDDBBhcGkuZ2lnYWZpdmUuY29tMR8w\n"\
|
||||
"HQYJKoZIhvcNAQkBFhBjcmxAZ2lnYWZpdmUuY29tMIICIjANBgkqhkiG9w0BAQEF\n"\
|
||||
"AAOCAg8AMIICCgKCAgEAof82VrEpXMpsI/ddW6RLeTeSYtxiXZZkRbDKN6otYgEk\n"\
|
||||
"vA8yRbzei2cO2A/8+Erhe9beYLAMXWF+bjoUAFwnuIcbmufgHprOYzX/7CYXCsrH\n"\
|
||||
"LrJfVF6kvjCXy2W3xSvgh8ZgHNWnBGzl13tq19Fz8x0AhK5GQ9608oJCbnQjpVSI\n"\
|
||||
"lZDl3JVOifCeXf2c7nMhVOC/reTeto0Gbchs8Ox50WyojmfYbVjOQcA7f8p1eI+D\n"\
|
||||
"XUJK01cUGVu6/KarVArGHh5LsiyXOadbyeyOXPmjyrgarG3IIBeQSNECfJZPc/OW\n"\
|
||||
"lFszjU4YLDckI4x+tReiuFQbQPN5sDplcEldmZZm/8XD36ddvAaDds+SYlPXxDK7\n"\
|
||||
"7L8RBVUG2Ylc9YZf7RE6IMDmdQmsCZDX0VxySYEmzv5lnAx4mzzaXcgS+kHMOLyK\n"\
|
||||
"n9UxmpzwQoqqC9tMZqwRaeKW1njR1dSwQLqirBPfGCWKkpkpm7C3HEfeeLrasral\n"\
|
||||
"aPf6LAwN3A4ZKHa5Jmne7W+1eYS1aTXOAOLIPcXRAh1B80H+SusIdM9d6vk2YTIg\n"\
|
||||
"khwGQV3sgM6nIO5+T/8z141UEjWbtP7pb/u0+G9Cg7TwvRoO2UukxdvOwNto1G2e\n"\
|
||||
"J3rKB/JSYsYWnPHvvh9XR+55PZ4iCf9Rqw/IP82uyGipR9gxlHqN8WhMTj9tNEkC\n"\
|
||||
"AwEAAaMhMB8wHQYDVR0OBBYEFISCemcSriz1HFhRXluw9H+Bv9lEMA0GCSqGSIb3\n"\
|
||||
"DQEBCwUAA4IBAQCMetK0xe6Y/uZpb1ARh+hHYcHI3xI+IG4opWJeoB1gDh/xpNAW\n"\
|
||||
"j6t5MGbLoqNMBXbqL26hnKVspyvCxw7ebI5ZJgjtbrD1t+0D8yrgIZzr7AWGA9Hj\n"\
|
||||
"WIHqDHGDxwkmfjVVPmuO3l5RtJmL6KV6kVL2bOvVI6gECpFLddmOTtg+iXDfSw3x\n"\
|
||||
"0+ueMYKr8QLF+TCxfzQTHvTHvOJtcZHecc1n7PYbRmI2p7tV6RoBpV69oM6NAVUV\n"\
|
||||
"i2QoSxm0pYzDzavOaxwhEPHT34Tpg6fwXy1QokFD9OtxRFtdpTjL3bMWpatZE+ba\n"\
|
||||
"cjvvf0utMW5fNjTTxu1nnpuxZM3ifTCqZJ+9\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char *rsa3072_cert = "-----BEGIN CERTIFICATE-----\n"\
|
||||
"MIIEszCCAxugAwIBAgIUNTBsyv59/rRarOVm3KBA29zqEtUwDQYJKoZIhvcNAQEL\n"\
|
||||
"BQAwaTELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFNoYW5naGFpMREwDwYDVQQHDAhT\n"\
|
||||
"aGFuZ2hhaTESMBAGA1UECgwJRXNwcmVzc2lmMQwwCgYDVQQLDANJREYxEjAQBgNV\n"\
|
||||
"BAMMCWVzcHJlc3NpZjAeFw0yMDA3MTQwODQ5NDdaFw0yMTA3MTQwODQ5NDdaMGkx\n"\
|
||||
"CzAJBgNVBAYTAkNOMREwDwYDVQQIDAhTaGFuZ2hhaTERMA8GA1UEBwwIU2hhbmdo\n"\
|
||||
"YWkxEjAQBgNVBAoMCUVzcHJlc3NpZjEMMAoGA1UECwwDSURGMRIwEAYDVQQDDAll\n"\
|
||||
"c3ByZXNzaWYwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDMj3ZwPd2y\n"\
|
||||
"+UxzmMUdZC5I5JQIzvUmHRNJWUe99Vht/rIEQuNSGg7xjyvuZoyeFo+Yg+QYUICa\n"\
|
||||
"Ipe4y2bZS12QsTxUmeoEhYORDSeQXFEo4aUmWuKIs6Y41dBOL7eDYDL3FRmIgmcn\n"\
|
||||
"qMonyCrSzXlcgHOVtMd8U8ifkX5u+nTigQLSIHVeAFz8CvC0tIiPm9YFurtMN15p\n"\
|
||||
"P1K/AH17ljtwVqacrI/asZgX+ECY5rauNJLigEYgfr7+xV6GofaXp6rUpGgWbVxM\n"\
|
||||
"hqKe/dbDuIzte3VK+zRDNDCeE5gPQjgoSDblOVmPemrq7KKjZ/PKmP47ct5a/0Ov\n"\
|
||||
"zWcdCgaXDRoPiwbpmz3Z6uh3JdvsDf214svLK+z4EDIRzpvggM0pfDvOADatiPkr\n"\
|
||||
"KmnFD1ZZx3R29/7IZ5OVvQL1hgWbm3cL4JADOc8PQKcqCzBE9JDdAVoa228ESaJ/\n"\
|
||||
"n4b63qaqfgBnoaFzCEruEcXj5nuXBxlk19WWtgY1tZtAgoA8hTWxxH0CAwEAAaNT\n"\
|
||||
"MFEwHQYDVR0OBBYEFPlwrvgkde/r+F8VRMMtpDUIxAtgMB8GA1UdIwQYMBaAFPlw\n"\
|
||||
"rvgkde/r+F8VRMMtpDUIxAtgMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\n"\
|
||||
"BQADggGBAH9nBaEP+FWyaZnmxCblKhs8eIEYXzjxbnRUPo5b3uL/PAv1XD1kEUwY\n"\
|
||||
"GWnJ7Z5HOSCdVMgo1opmKGLWuiVP6Vlt9QuA/tWh0bGScL4QfriPXuA7aXAcLbW/\n"\
|
||||
"BqHNJ9Z+H2Fq09XktkZE4Nfnv3iTMMqfNCchM3t3iWZRf2sRVYIdd5OjhM+CLLUK\n"\
|
||||
"kYNiseAgbcBX0/kqTdHlC6OS8Mcu9btJ/663DZy8tndf+PH+EB6fexQd9T31jWoj\n"\
|
||||
"OkEkJ4vDRZP+0LceK7kNcMOcLx8DnF9LwUyHQitW7NMFServoTfxy8A0yep7nIOH\n"\
|
||||
"M/ndECzirQ6WkR9jMG3cw0Jm5mZvA9IAvnLhUO45AyZGC8mShJ0AaXtqejqPg9ng\n"\
|
||||
"//5VIpzoqwVkrMYlMA7ZrccQiRsd2nlBHr+64PRwRCp7y5FOxIzhGzsJibXUpO/V\n"\
|
||||
"FNwuPz+VcnPvJE7r4gB1oRViiGYojMDQV3G+jbgvpTHKUKP6zzavSAKs+FlfEAmh\n"\
|
||||
"EtmuT/beDA==\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
/* Root cert from openssl s_client -connect google.com:443 -showcerts
|
||||
*/
|
||||
static const char *rsa2048_cert = "-----BEGIN CERTIFICATE-----\n"\
|
||||
"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\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
|
||||
/* Some random input bytes to public key encrypt */
|
||||
static const uint8_t pki_input[4096/8] = {
|
||||
0, 1, 4, 6, 7, 9, 33, 103, 49, 11, 56, 211, 67, 92 };
|
||||
|
||||
/* Result of an RSA4096 operation using cert's public key
|
||||
(raw PKI, no padding/etc) */
|
||||
static const uint8_t pki_rsa4096_output[] = {
|
||||
0x91, 0x87, 0xcd, 0x04, 0x80, 0x7c, 0x8b, 0x0b,
|
||||
0x0c, 0xc0, 0x38, 0x37, 0x7a, 0xe3, 0x2c, 0x94,
|
||||
0xea, 0xc4, 0xcb, 0x83, 0x2c, 0x77, 0x71, 0x14,
|
||||
0x11, 0x85, 0x16, 0x61, 0xd3, 0x64, 0x2a, 0x0f,
|
||||
0xf9, 0x6b, 0x45, 0x04, 0x66, 0x5d, 0x15, 0xf1,
|
||||
0xcf, 0x69, 0x77, 0x90, 0xb9, 0x41, 0x68, 0xa9,
|
||||
0xa6, 0xfd, 0x94, 0xdc, 0x6a, 0xce, 0xc7, 0xb6,
|
||||
0x41, 0xd9, 0x44, 0x3c, 0x02, 0xb6, 0xc7, 0x26,
|
||||
0xce, 0xec, 0x66, 0x21, 0xa8, 0xe8, 0xf4, 0xa9,
|
||||
0x33, 0x4a, 0x6c, 0x28, 0x0f, 0x50, 0x30, 0x32,
|
||||
0x28, 0x00, 0xbb, 0x2c, 0xc3, 0x44, 0x72, 0x31,
|
||||
0x93, 0xd4, 0xde, 0x29, 0x6b, 0xfa, 0x31, 0xfd,
|
||||
0x3a, 0x05, 0xc6, 0xb1, 0x28, 0x43, 0x57, 0x20,
|
||||
0xf7, 0xf8, 0x13, 0x0c, 0x4a, 0x80, 0x00, 0xab,
|
||||
0x1f, 0xe8, 0x88, 0xad, 0x56, 0xf2, 0xda, 0x5a,
|
||||
0x50, 0xe9, 0x02, 0x09, 0x21, 0x2a, 0xfc, 0x82,
|
||||
0x68, 0x34, 0xf9, 0x04, 0xa3, 0x25, 0xe1, 0x0f,
|
||||
0xa8, 0x77, 0x29, 0x94, 0xb6, 0x9d, 0x5a, 0x08,
|
||||
0x33, 0x8d, 0x27, 0x6a, 0xc0, 0x3b, 0xad, 0x91,
|
||||
0x8a, 0x83, 0xa9, 0x2e, 0x48, 0xcd, 0x67, 0xa3,
|
||||
0x3a, 0x35, 0x41, 0x85, 0xfa, 0x3f, 0x61, 0x1f,
|
||||
0x80, 0xeb, 0xcd, 0x5a, 0xc5, 0x14, 0x7b, 0xab,
|
||||
0x9c, 0x45, 0x11, 0xd2, 0x25, 0x9a, 0x16, 0xeb,
|
||||
0x9c, 0xfa, 0xbe, 0x73, 0x18, 0xbd, 0x25, 0x8e,
|
||||
0x99, 0x6d, 0xb3, 0xbc, 0xac, 0x2d, 0xa2, 0x53,
|
||||
0xe8, 0x7c, 0x38, 0x1b, 0x7a, 0x75, 0xff, 0x76,
|
||||
0x4f, 0x48, 0x5b, 0x39, 0x20, 0x5a, 0x7b, 0x82,
|
||||
0xd3, 0x33, 0x33, 0x2a, 0xab, 0x6a, 0x7a, 0x42,
|
||||
0x1d, 0x1f, 0xd1, 0x61, 0x58, 0xd7, 0x38, 0x52,
|
||||
0xdf, 0xb0, 0x61, 0x98, 0x63, 0xb7, 0xa1, 0x4e,
|
||||
0xdb, 0x9b, 0xcb, 0xb7, 0x85, 0xc4, 0x3e, 0x03,
|
||||
0xe5, 0x59, 0x50, 0x28, 0x5a, 0x4d, 0x7f, 0x53,
|
||||
0x2e, 0x99, 0x1d, 0x6d, 0x85, 0x27, 0x78, 0x34,
|
||||
0x5e, 0xae, 0xc9, 0x1b, 0x37, 0x96, 0xde, 0x40,
|
||||
0x87, 0x35, 0x3c, 0x1f, 0xe0, 0x8f, 0xfb, 0x3a,
|
||||
0x58, 0x0e, 0x60, 0xe9, 0x06, 0xbd, 0x83, 0x03,
|
||||
0x92, 0xde, 0x5e, 0x69, 0x28, 0xb1, 0x00, 0xeb,
|
||||
0x44, 0xca, 0x3c, 0x49, 0x03, 0x10, 0xa8, 0x84,
|
||||
0xa6, 0xbb, 0xd5, 0xda, 0x98, 0x8c, 0x6f, 0xa3,
|
||||
0x0f, 0x39, 0xf3, 0xa7, 0x7d, 0xd5, 0x3b, 0xe2,
|
||||
0x85, 0x12, 0xda, 0xa4, 0x4d, 0x80, 0x97, 0xcb,
|
||||
0x11, 0xe0, 0x89, 0x90, 0xff, 0x5b, 0x72, 0x19,
|
||||
0x59, 0xd1, 0x39, 0x23, 0x9f, 0xb0, 0x00, 0xe2,
|
||||
0x45, 0x72, 0xc6, 0x9a, 0xbc, 0xe1, 0xd1, 0x51,
|
||||
0x6b, 0x35, 0xd2, 0x49, 0xbf, 0xb6, 0xfe, 0xab,
|
||||
0x09, 0xf7, 0x9d, 0xa4, 0x6e, 0x69, 0xb6, 0xf9,
|
||||
0xde, 0xe3, 0x57, 0x0c, 0x1a, 0x96, 0xf1, 0xcc,
|
||||
0x1c, 0x92, 0xdb, 0x44, 0xf4, 0x45, 0xfa, 0x8f,
|
||||
0x87, 0xcf, 0xf4, 0xd2, 0xa1, 0xf8, 0x69, 0x18,
|
||||
0xcf, 0xdc, 0xa0, 0x1f, 0xb0, 0x26, 0xad, 0x81,
|
||||
0xab, 0xdf, 0x78, 0x18, 0xa2, 0x74, 0xba, 0x2f,
|
||||
0xec, 0x70, 0xa2, 0x1f, 0x56, 0xee, 0xff, 0xc9,
|
||||
0xfe, 0xb1, 0xe1, 0x9b, 0xea, 0x0e, 0x33, 0x14,
|
||||
0x5f, 0x6e, 0xca, 0xee, 0x02, 0x56, 0x5a, 0x67,
|
||||
0x42, 0x9a, 0xbf, 0x55, 0xc0, 0x0f, 0x8e, 0x01,
|
||||
0x67, 0x63, 0x6e, 0xd1, 0x57, 0xf7, 0xf1, 0xc6,
|
||||
0x92, 0x9e, 0xb5, 0x45, 0xe1, 0x50, 0x58, 0x94,
|
||||
0x20, 0x90, 0x6a, 0x29, 0x2d, 0x4b, 0xd1, 0xb5,
|
||||
0x68, 0x63, 0xb5, 0xe6, 0xd8, 0x6e, 0x84, 0x80,
|
||||
0xad, 0xe6, 0x03, 0x1e, 0x51, 0xc2, 0xa8, 0x6d,
|
||||
0x84, 0xec, 0x2d, 0x7c, 0x61, 0x02, 0xd1, 0xda,
|
||||
0xf5, 0x94, 0xfa, 0x2d, 0xa6, 0xed, 0x89, 0x6a,
|
||||
0x6a, 0xda, 0x07, 0x5d, 0x83, 0xfc, 0x43, 0x76,
|
||||
0x7c, 0xca, 0x8c, 0x00, 0xfc, 0xb9, 0x2c, 0x23,
|
||||
};
|
||||
|
||||
static const uint8_t pki_rsa3072_output[] = {
|
||||
0x86, 0xc0, 0xe4, 0xa5, 0x4b, 0x45, 0xe4, 0xd4, 0x0f, 0xb7, 0xe3, 0x10, 0x4f, 0xea, 0x88, 0x91,
|
||||
0x3d, 0xad, 0x43, 0x86, 0x90, 0xf0, 0xd8, 0xf0, 0x29, 0x21, 0xc7, 0x5c, 0x75, 0x49, 0x91, 0xce,
|
||||
0xf8, 0x34, 0x91, 0xbd, 0x89, 0x61, 0xcf, 0x47, 0x0e, 0x4d, 0x3f, 0x29, 0xd1, 0x02, 0xa7, 0xa8,
|
||||
0x8f, 0x6a, 0xda, 0x1a, 0xf2, 0xf1, 0x18, 0x92, 0x35, 0xf6, 0x0c, 0x07, 0x5a, 0x84, 0xfa, 0x65,
|
||||
0xd3, 0x02, 0xe0, 0x53, 0x17, 0x5d, 0xf7, 0x45, 0x26, 0xcc, 0xf9, 0x26, 0xf5, 0x6a, 0x66, 0xbb,
|
||||
0xef, 0x33, 0xcb, 0x03, 0x6e, 0x6a, 0x93, 0x6c, 0x2a, 0x27, 0xa7, 0xf7, 0x2c, 0xdc, 0x00, 0xdd,
|
||||
0x98, 0x52, 0xfb, 0xce, 0x31, 0xe2, 0x96, 0x20, 0x98, 0x0a, 0xf4, 0x19, 0x0f, 0xbf, 0x22, 0xed,
|
||||
0x37, 0xb2, 0x14, 0x10, 0x88, 0xa3, 0x6a, 0x43, 0x26, 0xb8, 0x54, 0xf1, 0xb8, 0xc6, 0x56, 0xb7,
|
||||
0x89, 0x34, 0xc0, 0xba, 0xae, 0x38, 0x35, 0x2c, 0x13, 0x57, 0x7a, 0xa4, 0x4b, 0xf2, 0x21, 0x82,
|
||||
0xf4, 0xea, 0x1a, 0x2c, 0xd8, 0x32, 0xe8, 0x5f, 0x37, 0x04, 0x52, 0x3d, 0xff, 0xc2, 0x85, 0x00,
|
||||
0xd2, 0x8d, 0x84, 0x36, 0x61, 0x61, 0x7b, 0xea, 0x7c, 0x3d, 0xeb, 0x51, 0xea, 0xf2, 0x67, 0xc9,
|
||||
0xb8, 0xa6, 0x98, 0x54, 0x3f, 0x5b, 0x8f, 0x1a, 0x8a, 0x93, 0x81, 0x05, 0xa3, 0x15, 0xf8, 0x54,
|
||||
0x8f, 0x75, 0xe2, 0x01, 0xc3, 0x47, 0xc3, 0x8f, 0xc7, 0x6d, 0x04, 0xbc, 0x05, 0x88, 0xd9, 0x62,
|
||||
0xcc, 0x14, 0xea, 0x30, 0x68, 0x73, 0xd5, 0xe5, 0x53, 0x7c, 0xb1, 0xa0, 0xe5, 0x6c, 0xd0, 0xa3,
|
||||
0x07, 0x2a, 0x5e, 0x2a, 0x0f, 0x89, 0x39, 0xea, 0xf9, 0xf5, 0xfb, 0x3b, 0xee, 0x66, 0xd9, 0xd4,
|
||||
0x04, 0x2d, 0x1b, 0xc9, 0xc2, 0x37, 0xc8, 0xa8, 0x71, 0xea, 0xa8, 0xf6, 0xe6, 0xc1, 0xdc, 0x5b,
|
||||
0x70, 0x68, 0x89, 0xa5, 0x69, 0xc0, 0x7f, 0x15, 0x8b, 0x6d, 0xc6, 0x88, 0x41, 0x8b, 0x25, 0x8f,
|
||||
0x2f, 0x5c, 0x81, 0x94, 0x1b, 0x8c, 0x52, 0x3f, 0xe5, 0x97, 0x6d, 0x4a, 0xc6, 0x42, 0x35, 0x0e,
|
||||
0x59, 0xce, 0x00, 0x3c, 0x2b, 0x0f, 0x5a, 0xc5, 0x1b, 0x01, 0xf3, 0x02, 0x70, 0xb1, 0x88, 0xda,
|
||||
0x7b, 0x5b, 0x4d, 0x3e, 0xd1, 0x15, 0x57, 0xc8, 0x39, 0x14, 0xff, 0x8d, 0x2b, 0x12, 0xf5, 0x5b,
|
||||
0xaf, 0x78, 0x2e, 0x0b, 0xcd, 0x27, 0x83, 0xdb, 0x4e, 0xe1, 0x5d, 0xa5, 0xbd, 0xfe, 0x2b, 0x6e,
|
||||
0x8b, 0x54, 0x7d, 0x14, 0x6f, 0x4d, 0xe1, 0x14, 0xc8, 0x30, 0x0e, 0x10, 0x23, 0x2a, 0xe1, 0xe5,
|
||||
0xee, 0xa3, 0x69, 0x8d, 0xe2, 0x9a, 0xed, 0x0c, 0x23, 0x16, 0x8e, 0x95, 0xae, 0x1a, 0xa2, 0x28,
|
||||
0x61, 0x25, 0xa2, 0x15, 0x74, 0xc4, 0xec, 0x6b, 0x73, 0xb2, 0x8c, 0xd2, 0x64, 0xfd, 0x2b, 0x92,
|
||||
};
|
||||
|
||||
static const uint8_t pki_rsa2048_output[] = {
|
||||
0x3c, 0xd6, 0xc2, 0xbf, 0x01, 0x4a, 0x00, 0x95,
|
||||
0x2c, 0x32, 0x11, 0xc0, 0xc9, 0x7e, 0x8f, 0x0a,
|
||||
0x15, 0xee, 0xfb, 0x34, 0x1d, 0xaa, 0xae, 0x15,
|
||||
0x11, 0x6d, 0x99, 0x2b, 0x09, 0xeb, 0x3f, 0x89,
|
||||
0x46, 0x98, 0x08, 0x2f, 0x10, 0x13, 0xa1, 0x17,
|
||||
0xc7, 0xec, 0x67, 0x3a, 0x34, 0x4f, 0x40, 0xcd,
|
||||
0xe2, 0xc0, 0xbe, 0x99, 0xc7, 0xe7, 0xff, 0xea,
|
||||
0xd0, 0x82, 0xd2, 0x62, 0x73, 0xde, 0x56, 0xe8,
|
||||
0xb6, 0xa7, 0xe7, 0xe1, 0x64, 0x90, 0x00, 0x56,
|
||||
0x1d, 0x2c, 0x1c, 0xc5, 0xec, 0x7f, 0xb1, 0x87,
|
||||
0x59, 0xb1, 0xd6, 0x44, 0x0f, 0x67, 0x35, 0xb4,
|
||||
0x91, 0x49, 0xed, 0x10, 0x4c, 0xef, 0xe5, 0xc8,
|
||||
0xea, 0x0d, 0xbd, 0xaf, 0xb9, 0xad, 0x12, 0x41,
|
||||
0xaa, 0xf4, 0x68, 0x54, 0x08, 0xec, 0x70, 0x8c,
|
||||
0xac, 0x6b, 0x57, 0xcf, 0x0a, 0x0c, 0x08, 0x34,
|
||||
0x28, 0x29, 0x27, 0xa4, 0x71, 0x80, 0x43, 0x59,
|
||||
0xd9, 0x35, 0x88, 0x28, 0x1d, 0xfa, 0x0b, 0x72,
|
||||
0xa0, 0xe1, 0x03, 0x65, 0x7a, 0xf8, 0x1c, 0x76,
|
||||
0x9a, 0xad, 0x21, 0x23, 0x11, 0x2f, 0x45, 0x40,
|
||||
0x72, 0x05, 0x69, 0x1b, 0x2a, 0x74, 0x9f, 0x95,
|
||||
0x44, 0x60, 0x05, 0x6a, 0x17, 0x80, 0x4a, 0xa0,
|
||||
0xed, 0x23, 0xa6, 0xef, 0x79, 0x5d, 0x83, 0xd8,
|
||||
0x8d, 0xd8, 0xe1, 0x4c, 0x5e, 0xf8, 0xfa, 0x11,
|
||||
0x57, 0xbe, 0xca, 0x22, 0x93, 0x5b, 0xe6, 0x8b,
|
||||
0xe1, 0x31, 0xde, 0x70, 0x80, 0x4a, 0xa2, 0xd3,
|
||||
0x91, 0xe8, 0xde, 0x88, 0xa2, 0x98, 0x73, 0x49,
|
||||
0x0d, 0x26, 0xe1, 0x42, 0xd7, 0xb9, 0x5e, 0xf6,
|
||||
0x05, 0x09, 0x27, 0xc6, 0x8c, 0xc2, 0xb1, 0x53,
|
||||
0x5f, 0x19, 0xaf, 0x2b, 0xfe, 0xac, 0x6a, 0x27,
|
||||
0xde, 0x89, 0xbc, 0x72, 0x3e, 0xd5, 0x9f, 0x36,
|
||||
0xc2, 0x91, 0x68, 0x30, 0xe7, 0x76, 0x96, 0x56,
|
||||
0x8f, 0x01, 0xc4, 0x5b, 0xb7, 0xb3, 0x90, 0x7f,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_MPI
|
||||
/* Pregenerated RSA 4096 size keys using openssl */
|
||||
static const char privkey_4096_buf[] = "-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIIJKAIBAAKCAgEA1blr9wfIzTylroJHxcoq+YFA765gF5vj9b6tfaPG0XQExSkjndHv5sra4ar7T+k2sBB4OcKKeGHkNk6wk8tGmOS79r2L74XZs1eB0UruG+huV7Sd+YiWzwN8y9jGImA9hIkf1qxIvkco5WTmT7cVwUnCQ7qiiVadD/LgyeGD04yKZpzv9UJzfjXz5ITTn/ejcn7423M9qz41nhRWwK4zw1jv7IB57d1dWOCbN3RO4dvfVndCz8DOmLzJrZAkLsz39vppbIwbMqTXKFxWqzZY2xrYmnMx9p3v4hLeju7ls3fsekESonoP0C76u50wJfZWO2XcIUo4pue/jHi2o9KouhLXW/vyasplXvE6FFrBjSpsm1Nar4KQMUolEkUbO9baGcQvH9G5WOH0kwPt7AOSqM2EUPvBd7Jv0tbMI/BRZVVltC/t6WhannCM/I6nZrlNe5tie/qYlFu474jp5/tpa8RykkDxwl9whejIqd4iQbvDiP/GXgBYtDJ9VU/S2KqHJhQFLDi+F3+ewOcF391fgt1e1J2vNYLKZOfxTOl/1vJbU/2IjRWTRQ7cXnmpR/GNCRfgH2as6Z/0oknBSVephguDnO5QlveP4Cx2EOVY/A/KgDpu8PumSrlIk+YQgLxdKsXaVI6eDY4rY7q2uCJH3yIAfZJXEeD+ResUuSZltvECAwEAAQKCAgBwR89+oipOGHR6b5tBP+q/1bXFtXhqLs3eBuSiQu5qj2cKJYi+mtJMD3paYDdTThQa/ywKPDf+8n6wQTrnCj32iQRupjnkBg/O9kQPLixVoRCHJy5vL+D6tLxVY3cEDEeFX3zIjQ5SWJQVn6KXcnoNZ7CVYHGPcV9mR5TsuntFImp7aituUBDY14NgJKABRFosBqS6tZpKYo5MlCbXZy1ujUTOnNhxrIAj9yvUQFhIs/hrNpB1ELf46gWSF03LAIesyvWjvx9yxcL7QzeNDyozQbFVwvsWsvaZcIxXzw4B8RjdSV5+2V2BY4z6D6SB7R50ahjxrEqC9PFe3PQmsL9OvFjV9idYwFOhxiWXGjIm3wwFFLOj3e0TShscj2Iw+Ghd3wApvSdBZxzdjap1NHC+Q6yYU+BnivxUHcopVPPM3rsLndyRC6zfrQw/OkOlAP3bNL1hRedPRmRDOz0V1ihEpgC1VfXx6XOu4eg8xWiJgWX+BGvT5GWjfQg2hB1Jm344r3l0eLhr25dO80GIac2QGT2+WmYkXcsQ3AiqAn2VF8UB5mU+Iyh96jmSFVVltGZgfp98yFYN63/7wB++lhVQmJZwbglutng1qjQBFslIULddIHiYvF+AVvkrO3Hc2zg8rT91tbE13k06A1zlNGcQuQKLax8e+2/BNjsZU2E4uQKCAQEA7L4obKWYRHgG6j1VEDRrQU8Vkm4L11B+ZD/rsEh3q7LbzViOPv+1dZ40jX2qYScWyaefI46bukJlk/mlNv4Dh3EnSFvHPCInDM3oImCYImwUx0hkbSRyRNwlwRwx81LJzIR84cCqpNWrXXcplomUSM62ea1E1vtNSZs9Bg2OLoWvFOTPgk/xDi6ezdb6JFiId6cARup/bmZ363mg8jCq0wpTLVdUGrezfMj4GpB1uQET5xqXleumQu/04cHPOfXwpV0ikIOId/ldY/PetiRd86B32aB2Xd4fHUpxHMY+63MFmL6SsqMQJMPubv+eIrOId4HhT+nXNFBZXolT5XG5NwKCAQEA5xvvccHNyCTL0AebxD6EihWnp0/Dd0DwXWxZw0Yhhc9xa/W/QtygB6kPb35oKGvCKdm4dWCIGln03dU5D6CMNkJlbkxpo8gybz34SJ/6OvU836rBLHZXE3Xiqbe5XkdMdarA7kTEhEUqekDXPxhws9dWh0YjtAnBPpm1GQppiykI2edkiIhRgju5ghe+/UjAjxrEgCKZeAODh46hwZHERRKQN2MFUOFcOVDq+2wTJem9r3h1uBQAiZn8PDyx0rlRkwH2dZSSauVW+I713N0JGucOV7FeMO0ebioqqckh0i91ZJNH//Io8Sp8WuBsU/vcP9jT+5BDkCbc71BRO/AFFwKCAQBj4a6oeA0QBhvUw9+ZoKQHv9f4GZnBU+KfZSCJFWn39NQrhMsu5S+n2gGOGJDDwHwqxB+uHsKxCMZWciM0WmMex6ytKJucUURscIsZxespyrPRiEdmjNPxHXiISt8AK9OcB+GwVVsphERygI35Rz5aoWv3VhUPJqNrBKXwYdO06Q3/ILIz5oprU1wIuER9BSU+ZiUFxnXRHEZIAN7Yj5Piyh5hqNCBHTQK17dlbcFdNokxHdUKmYth/l8wyFYnvA21lt+4XOY8x+aQ/xjde+ZvnSozlTGbVNWHxBqI61MsfzDDStQVrhpniIqWJh6PwXM4CIII9z2mgqfR7NqKmTptAoIBAQDTYQOigmZbFvyrayoXVi8XtTLAnv3jByxR5pY7OtvSbagJ3J1w5CYim4iYq39M6TKP4KkMApy5rWl/tFQabPeRcS0gsxc0TBmFEaMTme7fGgrxcFZ6+koubHZCUN5k0sWmIeWQiKlNaY2uf7vf49TBSMXFuGtTclCjlybCnnlmZMPJuhCDqFsUyNelm15+f5pPyWXM5NiFooEc7WIZj996Zb4uSo1EKruVWONzzqe814s9AOp60SCkuoiv97uVRxbLZNItPRSmXNktQmSx/CEl0AuYPYwvJ9HbZQncfTBH9ExlDyidernjyr4uyHGMZyJN614ICy0gncsZv9ZtAd1FAoIBAA4toGPU/VcKFmK92zgO05jsg5vJzw5xeoxRWKrLg7iby6Su6BuNgaVwfYWeZuOhnXakid7FvFXKH6x44o9gyFm5bKqFhaXDzAnxzqcLeM5V+gititOsstpZCbVOoKQOhgTHyxpFNVX3E/nB8EunydWyhQMxKme//NsRroFm1vWljQKyL3zER82AzyseEpEYZoB/6g0n5uF2lR7KllxeBlINsceQ8g3JkmJTdS1hoXcyUSsZ+EgrRbCykNB5aVC5G3/W1OSZsFHbbMrYHCMnaYKwMqLmOkb11o6nOrJJ4pgHj8CVcp2TNjfy3y0Ru6RZ42b0Q+3LktJBGu9r5d04FgI=\n"
|
||||
"-----END RSA PRIVATE KEY-----";
|
||||
|
||||
static const char privkey_2048_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n"
|
||||
"MIIEowIBAAKCAQEA8N8hdkemvj6Tpk975/OWhv9BrTsCBCu+ZYfDb5VI7U2meKBg\r\n"
|
||||
"3dAkyyhRlY3fNwSRzBUMCzsHjpgnsB40wxOgiwlB9n6PMhq0qUVKAdCpKwFztsKd\r\n"
|
||||
"JJAsCUC+Zlwxn4RpH6ZnMl3a/njRYjuDyI32kucMP/lBRo7ks1798Gy/j+x1h5xA\r\n"
|
||||
"vZSlFoEXKjCC6S1DWhALePuZnk4m/jGP6g+YfyJXSTqsenKa/DcWndfn/JoElZ0J\r\n"
|
||||
"nhud8lBXwVe6mMheE1yqfL+VTU1nwg/TPNZrZsFz2sXig/RQCKt6LuSuzhRpsLp+\r\n"
|
||||
"BdwqEs9xrwlhZnp7j4kQBomISd6kAxQfYVROHQIDAQABAoIBAHgtO4rB8QWWPyCJ\r\n"
|
||||
"I670r7OnA2OkvzrJgHMzq2SuvPX4+gfRLMM+qDzcXugZIrdWhk+maJ3p07lnXNXY\r\n"
|
||||
"HEcAMedstQaA2n0LKfwSX/xL2TtlvBABRVoKvI3ZSaXUdcW60KBD69ULUsoICZ/T\r\n"
|
||||
"Rcr4WX+t20TH3bOQc7ayvEwKVgE95xIUpTH9asw8uOPvKxW2j5OLQgZuWrWyUDg0\r\n"
|
||||
"MFh92PhWtw3i5zq6OpTTsFJeceKYV/VstIYjZ+FslmhjQxJbr+2DJRbpHXKceqy6\r\n"
|
||||
"9yWlSV0EM7neFCHlDa2WPhK8we+6IvMiNVQKj46fHGYNBaW/ZSX7TiG5J0Uqj2e9\r\n"
|
||||
"0MUGJ8ECgYEA+frJabhfzW5+JfGjTObeznJZE6fAOjFzaBIwFu8Kz2mIjYpQlwVK\r\n"
|
||||
"EepMkv2KkrJuqS4GnI+Nkq7G0BAUyUj9tTJ3HQzvtJrxsnxVi99Yofx1s1P4YAnu\r\n"
|
||||
"c8t3ElJoQ4BRoQIs/hIvyYn22IxllBHiGESrnPQ38D82xyXQgd6S8JkCgYEA9qww\r\n"
|
||||
"j7jx6Xpy/D1Dq8Dvalm7pz3J+yHnti4w2cqZ67grUoyGnNPtciNDdfi4JzLiKkUu\r\n"
|
||||
"SDS3DacvFpFyND0m8sbpMjnR8Rvhj+bfH8KcOAowD+YR/+6vSb/P/aBt6gYXcaBn\r\n"
|
||||
"cjepx+sE81mnC7UrHb4TjG4hO5t3ZTc6X28gyCUCgYAMZn9lSisecrO5SCJUp0M4\r\n"
|
||||
"NH3stq6XdGqIKBbQnG0J2u9WLh1PUIjbGKdRx1f/bPCGXe0gCRL5yse7/IA7d+51\r\n"
|
||||
"9ZnpDAI8EE+bDgXkWWD5MB/alHjGstdsURSICSR47L2f4g6/T8GlGr3vAg/r53My\r\n"
|
||||
"xv1IXOkFdu1NtbeBKbxaSQKBgENDmw5mAVmIcXiFAEICn4ahp4EoYT6g9T2BhQKu\r\n"
|
||||
"s6BKnU2qUj7Lr5ETOp8dzqGpx3B9Yux/q3cGotmFmd3S2x8SzJ5MlAoqbyy9aRSR\r\n"
|
||||
"DeZeKNL9CuV+YcA7lOz1ZWOOe7AZbHwB38NLPBNb3CheI769iTkfAuLtNvabw8go\r\n"
|
||||
"VokdAoGBALyvBhW+Squ5tx8NOEgAisakhAVOnT6jcoeKy6FyjcvKaWagmCOCC7Gz\r\n"
|
||||
"QB9Yf1tJ+3di+aLtWWdmU494iKJHBtPMhfrYltCpxHHQGlUc/GLPY3Z5bBYYYWpb\r\n"
|
||||
"Wzw4ZvDraKlAs7a9CRwS5cpktk5ptK4rc5noSXkvV+yOT75zXat2\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
static const char privkey_3072_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n"
|
||||
"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\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
#endif
|
||||
|
||||
_Static_assert(sizeof(pki_rsa2048_output) == 2048/8, "rsa2048 output is wrong size");
|
||||
_Static_assert(sizeof(pki_rsa3072_output) == 3072/8, "rsa3072 output is wrong size");
|
||||
_Static_assert(sizeof(pki_rsa4096_output) == 4096/8, "rsa4096 output is wrong size");
|
||||
|
||||
void mbedtls_mpi_printf(const char *name, const mbedtls_mpi *X);
|
||||
|
||||
|
||||
static void test_cert(const char *cert, const uint8_t *expected_output, size_t output_len);
|
||||
|
||||
TEST_CASE("mbedtls RSA4096 cert", "[mbedtls]")
|
||||
{
|
||||
|
||||
test_cert(rsa4096_cert, pki_rsa4096_output, 4096/8);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls RSA3072 cert", "[mbedtls]")
|
||||
{
|
||||
|
||||
test_cert(rsa3072_cert, pki_rsa3072_output, 3072/8);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls RSA2048 cert", "[mbedtls]")
|
||||
{
|
||||
test_cert(rsa2048_cert, pki_rsa2048_output, 2048/8);
|
||||
}
|
||||
|
||||
static void test_cert(const char *cert, const uint8_t *expected_output, size_t output_len)
|
||||
{
|
||||
mbedtls_x509_crt crt;
|
||||
mbedtls_rsa_context *rsa;
|
||||
char buf[output_len];
|
||||
int res;
|
||||
|
||||
bzero(buf, output_len);
|
||||
|
||||
mbedtls_x509_crt_init(&crt);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16_MESSAGE(0,
|
||||
-mbedtls_x509_crt_parse(&crt,
|
||||
(const uint8_t *)cert,
|
||||
strlen(cert)+1),
|
||||
"parse cert");
|
||||
|
||||
rsa = mbedtls_pk_rsa(crt.pk);
|
||||
TEST_ASSERT_NOT_NULL(rsa);
|
||||
|
||||
res = mbedtls_rsa_check_pubkey(rsa);
|
||||
TEST_ASSERT_EQUAL_HEX16_MESSAGE(0,
|
||||
-res,
|
||||
"check cert pubkey");
|
||||
|
||||
mbedtls_x509_crt_info(buf, sizeof(buf), "", &crt);
|
||||
puts(buf);
|
||||
|
||||
res = mbedtls_rsa_public(rsa, pki_input, (uint8_t *)buf);
|
||||
if (res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + MBEDTLS_ERR_RSA_PUBLIC_FAILED) {
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
TEST_IGNORE_MESSAGE("Hardware does not support this key length");
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16_MESSAGE(0,
|
||||
-res,
|
||||
"RSA PK operation");
|
||||
|
||||
/*
|
||||
// Dump buffer for debugging
|
||||
for(int i = 0; i < output_len; i++) {
|
||||
printf("0x%02x, ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_output, buf, output_len);
|
||||
|
||||
mbedtls_x509_crt_free(&crt);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_MPI
|
||||
static void rsa_key_operations(int keysize, bool check_performance, bool generate_new_rsa);
|
||||
|
||||
static int myrand(void *rng_state, unsigned char *output, size_t len)
|
||||
{
|
||||
size_t olen;
|
||||
return mbedtls_hardware_poll(rng_state, output, len, &olen);
|
||||
}
|
||||
|
||||
#ifdef PRINT_DEBUG_INFO
|
||||
static void print_rsa_details(mbedtls_rsa_context *rsa)
|
||||
{
|
||||
mbedtls_mpi X[5];
|
||||
for (int i=0; i<5; ++i) {
|
||||
mbedtls_mpi_init( &X[i] );
|
||||
}
|
||||
|
||||
if (0 == mbedtls_rsa_export(rsa, &X[0], &X[1], &X[2], &X[3], &X[4])) {
|
||||
for (int i=0; i<5; ++i) {
|
||||
mbedtls_mpi_printf((char*)"N\0P\0Q\0D\0E" + 2*i, &X[i]);
|
||||
mbedtls_mpi_free( &X[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_FREERTOS_SMP // IDF-5826
|
||||
TEST_CASE("test performance RSA key operations", "[bignum][timeout=60]")
|
||||
#else
|
||||
TEST_CASE("test performance RSA key operations", "[bignum]")
|
||||
#endif
|
||||
{
|
||||
/** NOTE:
|
||||
* For ESP32-S3, CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is enabled
|
||||
* by default; allocating a lock of 92 bytes, which is never freed.
|
||||
*
|
||||
* MR !18574 adds the MPI crypto lock for S3 increasing the leakage by
|
||||
* 92 bytes. This caused the RSA UT to fail with a leakage more than
|
||||
* 1024 bytes.
|
||||
*
|
||||
* The allocations made by ESP32-S2 (944 bytes) and ESP32-S3 are the same,
|
||||
* except for the JTAG lock (92 + 944 > 1024).
|
||||
*/
|
||||
TEST_ESP_OK(test_utils_set_leak_level(1088, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
|
||||
for (int keysize = 2048; keysize <= SOC_RSA_MAX_BIT_LEN; keysize += 1024) {
|
||||
rsa_key_operations(keysize, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_SMP // IDF-5826
|
||||
TEST_CASE("test RSA-3072 calculations", "[bignum][timeout=60]")
|
||||
#else
|
||||
TEST_CASE("test RSA-3072 calculations", "[bignum]")
|
||||
#endif
|
||||
{
|
||||
// use pre-genrated keys to make the test run a bit faster
|
||||
rsa_key_operations(3072, false, false);
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_SMP // IDF-5826
|
||||
TEST_CASE("test RSA-2048 calculations", "[bignum][timeout=60]")
|
||||
#else
|
||||
TEST_CASE("test RSA-2048 calculations", "[bignum]")
|
||||
#endif
|
||||
{
|
||||
// use pre-genrated keys to make the test run a bit faster
|
||||
rsa_key_operations(2048, false, false);
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_SMP // IDF-5826
|
||||
TEST_CASE("test RSA-4096 calculations", "[bignum][timeout=60]")
|
||||
#else
|
||||
TEST_CASE("test RSA-4096 calculations", "[bignum]")
|
||||
#endif
|
||||
{
|
||||
// use pre-genrated keys to make the test run a bit faster
|
||||
rsa_key_operations(4096, false, false);
|
||||
}
|
||||
|
||||
|
||||
static void rsa_key_operations(int keysize, bool check_performance, bool generate_new_rsa)
|
||||
{
|
||||
mbedtls_pk_context clientkey;
|
||||
mbedtls_rsa_context rsa;
|
||||
unsigned char orig_buf[4096 / 8];
|
||||
unsigned char encrypted_buf[4096 / 8];
|
||||
unsigned char decrypted_buf[4096 / 8];
|
||||
int res = 0;
|
||||
|
||||
printf("First, orig_buf is encrypted by the public key, and then decrypted by the private key\n");
|
||||
printf("keysize=%d check_performance=%d generate_new_rsa=%d\n", keysize, check_performance, generate_new_rsa);
|
||||
|
||||
memset(orig_buf, 0xAA, sizeof(orig_buf));
|
||||
orig_buf[0] = 0; // Ensure that orig_buf is smaller than rsa.N
|
||||
if (generate_new_rsa) {
|
||||
mbedtls_rsa_init(&rsa);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_rsa_gen_key(&rsa, myrand, NULL, keysize, 65537));
|
||||
} else {
|
||||
mbedtls_pk_init(&clientkey);
|
||||
|
||||
switch(keysize) {
|
||||
case 4096:
|
||||
res = mbedtls_pk_parse_key(&clientkey, (const uint8_t *)privkey_4096_buf, sizeof(privkey_4096_buf), NULL, 0, myrand, NULL);
|
||||
break;
|
||||
case 3072:
|
||||
res = mbedtls_pk_parse_key(&clientkey, (const uint8_t *)privkey_3072_buf, sizeof(privkey_3072_buf), NULL, 0, myrand, NULL);
|
||||
break;
|
||||
case 2048:
|
||||
res = mbedtls_pk_parse_key(&clientkey, (const uint8_t *)privkey_2048_buf, sizeof(privkey_2048_buf), NULL, 0, myrand, NULL);
|
||||
break;
|
||||
default:
|
||||
TEST_FAIL_MESSAGE("unsupported keysize, pass generate_new_rsa=true or update test");
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX16(0, -res);
|
||||
|
||||
memcpy(&rsa, mbedtls_pk_rsa(clientkey), sizeof(mbedtls_rsa_context));
|
||||
}
|
||||
|
||||
#ifdef PRINT_DEBUG_INFO
|
||||
print_rsa_details(&rsa);
|
||||
#endif
|
||||
|
||||
TEST_ASSERT_EQUAL(keysize, (int)rsa.MBEDTLS_PRIVATE(len) * 8);
|
||||
TEST_ASSERT_EQUAL(keysize, (int)rsa.MBEDTLS_PRIVATE(D).MBEDTLS_PRIVATE(n) * sizeof(mbedtls_mpi_uint) * 8); // The private exponent
|
||||
|
||||
#ifdef SOC_CCOMP_TIMER_SUPPORTED
|
||||
int public_perf, private_perf;
|
||||
ccomp_timer_start();
|
||||
res = mbedtls_rsa_public(&rsa, orig_buf, encrypted_buf);
|
||||
public_perf = ccomp_timer_stop();
|
||||
|
||||
if (res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + MBEDTLS_ERR_RSA_PUBLIC_FAILED) {
|
||||
mbedtls_rsa_free(&rsa);
|
||||
TEST_IGNORE_MESSAGE("Hardware does not support this key length");
|
||||
}
|
||||
TEST_ASSERT_EQUAL_HEX16(0, -res);
|
||||
|
||||
ccomp_timer_start();
|
||||
res = mbedtls_rsa_private(&rsa, myrand, NULL, encrypted_buf, decrypted_buf);
|
||||
private_perf = ccomp_timer_stop();
|
||||
TEST_ASSERT_EQUAL_HEX16(0, -res);
|
||||
|
||||
if (check_performance && keysize == 2048) {
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PUBLIC_OP, "%d us", public_perf);
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PRIVATE_OP, "%d us", private_perf);
|
||||
} else if (check_performance && keysize == 4096) {
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PUBLIC_OP, "%d us", public_perf);
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PRIVATE_OP, "%d us", private_perf);
|
||||
}
|
||||
#else
|
||||
res = mbedtls_rsa_public(&rsa, orig_buf, encrypted_buf);
|
||||
TEST_ASSERT_EQUAL_HEX16(0, -res);
|
||||
res = mbedtls_rsa_private(&rsa, myrand, NULL, encrypted_buf, decrypted_buf);
|
||||
TEST_ASSERT_EQUAL_HEX16(0, -res);
|
||||
TEST_IGNORE_MESSAGE("Performance check skipped! (soc doesn't support ccomp timer)");
|
||||
#endif
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(orig_buf, decrypted_buf, keysize / 8, "RSA operation");
|
||||
|
||||
mbedtls_rsa_free(&rsa);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls RSA Generate Key", "[mbedtls][timeout=60]")
|
||||
{
|
||||
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
|
||||
const unsigned int key_size = 2048;
|
||||
const int exponent = 65537;
|
||||
|
||||
#if CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT
|
||||
/* Check that generating keys doesn't starve the watchdog if interrupt-based driver is used */
|
||||
esp_task_wdt_config_t twdt_config = {
|
||||
.timeout_ms = 1000,
|
||||
.idle_core_mask = (1 << 0), // Watch core 0 idle
|
||||
.trigger_panic = true,
|
||||
};
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_init(&twdt_config));
|
||||
#endif // CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT
|
||||
|
||||
mbedtls_rsa_init(&ctx);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
TEST_ASSERT_FALSE( mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) );
|
||||
|
||||
TEST_ASSERT_FALSE( mbedtls_rsa_gen_key(&ctx, mbedtls_ctr_drbg_random, &ctr_drbg, key_size, exponent) );
|
||||
|
||||
mbedtls_rsa_free(&ctx);
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
|
||||
#if CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
|
||||
#endif // CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT
|
||||
|
||||
}
|
||||
|
||||
#endif // CONFIG_MBEDTLS_HARDWARE_MPI
|
||||
@@ -16,256 +16,385 @@
|
||||
#include "spi_flash_mmap.h"
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
#include "mbedtls/sha512.h"
|
||||
#endif
|
||||
|
||||
#include "sha/sha_parallel_engine.h"
|
||||
|
||||
/* Note: Most of the SHA functions are called as part of mbedTLS, so
|
||||
are tested as part of mbedTLS tests. Only esp_sha() is different.
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/md.h"
|
||||
#define TAG "sha_test"
|
||||
|
||||
#if SOC_SHA_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
TEST_CASE("Test esp_sha()", "[hw_crypto]")
|
||||
// New test for PSA SHA-512 implementation
|
||||
TEST_CASE("Test PSA SHA-512 with known test vectors", "[hw_crypto][psa]")
|
||||
{
|
||||
const size_t BUFFER_SZ = 32 * 1024 + 6; // NB: not an exact multiple of SHA block size
|
||||
ESP_LOGI(TAG, "Testing PSA SHA-512 implementation with known test vectors");
|
||||
|
||||
int64_t elapsed;
|
||||
uint32_t us_sha1;
|
||||
uint8_t sha1_result[20] = { 0 };
|
||||
// Test Vector 1: SHA-512("abc")
|
||||
// Expected: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
|
||||
const unsigned char test1_input[] = "abc";
|
||||
const size_t test1_input_len = 3;
|
||||
const unsigned char test1_expected[64] = {
|
||||
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
|
||||
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
|
||||
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
|
||||
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
|
||||
};
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
uint32_t us_sha512;
|
||||
uint8_t sha512_result[64] = { 0 };
|
||||
#endif
|
||||
// Test Vector 2: SHA-512("")
|
||||
// Expected: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
|
||||
const unsigned char test2_input[] = "";
|
||||
const size_t test2_input_len = 0;
|
||||
const unsigned char test2_expected[64] = {
|
||||
0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
|
||||
0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
|
||||
0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
|
||||
0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
|
||||
};
|
||||
|
||||
void *buffer = heap_caps_malloc(BUFFER_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buffer);
|
||||
memset(buffer, 0xEE, BUFFER_SZ);
|
||||
unsigned char psa_output[64];
|
||||
unsigned char mbedtls_output[64];
|
||||
size_t psa_output_len;
|
||||
psa_status_t psa_status;
|
||||
int mbedtls_ret;
|
||||
|
||||
const uint8_t sha1_expected[20] = { 0xc7, 0xbb, 0xd3, 0x74, 0xf2, 0xf6, 0x20, 0x86,
|
||||
0x61, 0xf4, 0x50, 0xd5, 0xf5, 0x18, 0x44, 0xcc,
|
||||
0x7a, 0xb7, 0xa5, 0x4a };
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
const uint8_t sha512_expected[64] = { 0xc7, 0x7f, 0xda, 0x8c, 0xb3, 0x58, 0x14, 0x8a,
|
||||
0x52, 0x3b, 0x46, 0x04, 0xc0, 0x85, 0xc5, 0xf0,
|
||||
0x46, 0x64, 0x14, 0xd5, 0x96, 0x7a, 0xa2, 0x80,
|
||||
0x20, 0x9c, 0x04, 0x27, 0x7d, 0x3b, 0xf9, 0x1f,
|
||||
0xb2, 0xa3, 0x45, 0x3c, 0xa1, 0x6a, 0x8d, 0xdd,
|
||||
0x35, 0x5e, 0x35, 0x57, 0x76, 0x22, 0x74, 0xd8,
|
||||
0x1e, 0x07, 0xc6, 0xa2, 0x9e, 0x3b, 0x65, 0x75,
|
||||
0x80, 0x7d, 0xe6, 0x6e, 0x47, 0x61, 0x2c, 0x94 };
|
||||
#endif
|
||||
ESP_LOGI(TAG, "=== Test 1: SHA-512(\"abc\") ===");
|
||||
|
||||
ccomp_timer_start();
|
||||
esp_sha(SHA1, buffer, BUFFER_SZ, sha1_result);
|
||||
elapsed = ccomp_timer_stop();
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, sha1_result, sizeof(sha1_expected));
|
||||
us_sha1 = elapsed;
|
||||
ESP_LOGI(TAG, "esp_sha() 32KB SHA1 in %" PRIu32 " us", us_sha1);
|
||||
// Test with PSA
|
||||
ESP_LOGI(TAG, "Testing PSA psa_hash_compute()...");
|
||||
psa_status = psa_hash_compute(PSA_ALG_SHA_512, test1_input, test1_input_len,
|
||||
psa_output, sizeof(psa_output), &psa_output_len);
|
||||
ESP_LOGI(TAG, "PSA status: 0x%x, output_len: %zu", (unsigned int)psa_status, psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(64, psa_output_len);
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
ccomp_timer_start();
|
||||
esp_sha(SHA2_512, buffer, BUFFER_SZ, sha512_result);
|
||||
elapsed = ccomp_timer_stop();
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, sha512_result, sizeof(sha512_expected));
|
||||
ESP_LOGI(TAG, "PSA result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
psa_output[0], psa_output[1], psa_output[2], psa_output[3],
|
||||
psa_output[4], psa_output[5], psa_output[6], psa_output[7]);
|
||||
ESP_LOGI(TAG, "Expected result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
test1_expected[0], test1_expected[1], test1_expected[2], test1_expected[3],
|
||||
test1_expected[4], test1_expected[5], test1_expected[6], test1_expected[7]);
|
||||
|
||||
us_sha512 = elapsed;
|
||||
ESP_LOGI(TAG, "esp_sha() 32KB SHA512 in %" PRIu32 " us", us_sha512);
|
||||
#endif
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, psa_output, 64);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-512(\"abc\") PASSED");
|
||||
|
||||
/* NOTE: The Mbed TLS ROM implementation needs to updated to support SHA224 operations */
|
||||
#if !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL
|
||||
#if SOC_SHA_SUPPORT_SHA224
|
||||
uint8_t sha224_result[28] = { 0 };
|
||||
const uint8_t sha224_expected[28] = { 0xc0, 0x2a, 0x54, 0x2f, 0x70, 0x93, 0xaa, 0x3e,
|
||||
0xb6, 0xec, 0xe6, 0xb2, 0xb8, 0xe6, 0x57, 0x27,
|
||||
0xf9, 0x34, 0x9e, 0xb7, 0xbc, 0x96, 0x0d, 0xf5,
|
||||
0xd9, 0x87, 0xa8, 0x17 };
|
||||
esp_sha(SHA2_224, buffer, BUFFER_SZ, sha224_result);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha224_expected, sha224_result, sizeof(sha224_expected));
|
||||
#endif
|
||||
#endif
|
||||
// Test with mbedtls_md
|
||||
ESP_LOGI(TAG, "Testing mbedtls_md()...");
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
||||
TEST_ASSERT_NOT_NULL(md_info);
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA384
|
||||
uint8_t sha384_result[48] = { 0 };
|
||||
const uint8_t sha384_expected[48] = { 0x72, 0x13, 0xc8, 0x09, 0x7b, 0xbc, 0x9e, 0x65,
|
||||
0x02, 0xf8, 0x1d, 0xd2, 0x02, 0xd3, 0xd1, 0x80,
|
||||
0x48, 0xb9, 0xfb, 0x10, 0x2f, 0x1b, 0xd1, 0x40,
|
||||
0x4c, 0xc6, 0x3c, 0xfe, 0xcf, 0xa0, 0x83, 0x1b,
|
||||
0x6e, 0xfb, 0x97, 0x17, 0x65, 0x08, 0x28, 0x04,
|
||||
0x2f, 0x06, 0x2c, 0x97, 0x4e, 0xf8, 0x26, 0x86 };
|
||||
esp_sha(SHA2_384, buffer, BUFFER_SZ, sha384_result);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha384_expected, sha384_result, sizeof(sha384_expected));
|
||||
#endif
|
||||
mbedtls_ret = mbedtls_md(md_info, test1_input, test1_input_len, mbedtls_output);
|
||||
ESP_LOGI(TAG, "mbedtls_md return: %d", mbedtls_ret);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ret);
|
||||
|
||||
free(buffer);
|
||||
ESP_LOGI(TAG, "mbedtls result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
mbedtls_output[0], mbedtls_output[1], mbedtls_output[2], mbedtls_output[3],
|
||||
mbedtls_output[4], mbedtls_output[5], mbedtls_output[6], mbedtls_output[7]);
|
||||
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA1_32KB, "%" PRId32 " us", us_sha1);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, mbedtls_output, 64);
|
||||
ESP_LOGI(TAG, "✓ mbedtls_md SHA-512(\"abc\") PASSED");
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA512_32KB, "%" PRId32 " us", us_sha512);
|
||||
#endif
|
||||
// Verify both methods produce the same result
|
||||
TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 64);
|
||||
ESP_LOGI(TAG, "✓ PSA and mbedtls_md results match");
|
||||
|
||||
ESP_LOGI(TAG, "=== Test 2: SHA-512(\"\") (empty string) ===");
|
||||
|
||||
// Test with PSA
|
||||
psa_status = psa_hash_compute(PSA_ALG_SHA_512, test2_input, test2_input_len,
|
||||
psa_output, sizeof(psa_output), &psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(64, psa_output_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, psa_output, 64);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-512(\"\") PASSED");
|
||||
|
||||
// Test with mbedtls_md
|
||||
mbedtls_ret = mbedtls_md(md_info, test2_input, test2_input_len, mbedtls_output);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ret);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, mbedtls_output, 64);
|
||||
ESP_LOGI(TAG, "✓ mbedtls_md SHA-512(\"\") PASSED");
|
||||
|
||||
// Verify both methods produce the same result
|
||||
TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 64);
|
||||
ESP_LOGI(TAG, "✓ All PSA SHA-512 tests PASSED!");
|
||||
}
|
||||
|
||||
/* NOTE: This test attempts to mmap 1MB of flash starting from address 0x00, which overlaps
|
||||
* the entire TEE protected region, causing the mmap operation to fail and triggering an
|
||||
* exception in the subsequent steps.
|
||||
*/
|
||||
#if !CONFIG_SECURE_ENABLE_TEE
|
||||
|
||||
TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]")
|
||||
TEST_CASE("Test PSA SHA-256 with known test vectors", "[hw_crypto][psa]")
|
||||
{
|
||||
int r = -1;
|
||||
const void* ptr;
|
||||
spi_flash_mmap_handle_t handle;
|
||||
#if CONFIG_MBEDTLS_SHA1_C
|
||||
uint8_t sha1_espsha[20] = { 0 };
|
||||
uint8_t sha1_mbedtls[20] = { 0 };
|
||||
#endif
|
||||
uint8_t sha256_espsha[32] = { 0 };
|
||||
uint8_t sha256_mbedtls[32] = { 0 };
|
||||
ESP_LOGI(TAG, "Testing PSA SHA-256 implementation with known test vectors");
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C
|
||||
uint8_t sha512_espsha[64] = { 0 };
|
||||
uint8_t sha512_mbedtls[64] = { 0 };
|
||||
#endif
|
||||
// Test Vector 1: SHA-256("abc")
|
||||
// Expected: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
|
||||
const unsigned char test1_input[] = "abc";
|
||||
const size_t test1_input_len = 3;
|
||||
const unsigned char test1_expected[32] = {
|
||||
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
|
||||
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
|
||||
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
|
||||
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
|
||||
};
|
||||
|
||||
const size_t LEN = 1024 * 1024;
|
||||
// Test Vector 2: SHA-256("")
|
||||
// Expected: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
const unsigned char test2_input[] = "";
|
||||
const size_t test2_input_len = 0;
|
||||
const unsigned char test2_expected[32] = {
|
||||
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
|
||||
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
|
||||
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
|
||||
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
|
||||
};
|
||||
|
||||
/* mmap() 1MB of flash, we don't care what it is really */
|
||||
esp_err_t err = spi_flash_mmap(0x0, LEN, SPI_FLASH_MMAP_DATA, &ptr, &handle);
|
||||
// Test Vector 3: SHA-256("hello world")
|
||||
// Expected: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
||||
const unsigned char test3_input[] = "hello world";
|
||||
const unsigned char test3_expected[32] = {
|
||||
0xb9, 0x4d, 0x27, 0xb9, 0x93, 0x4d, 0x3e, 0x08,
|
||||
0xa5, 0x2e, 0x52, 0xd7, 0xda, 0x7d, 0xab, 0xfa,
|
||||
0xc4, 0x84, 0xef, 0xe3, 0x7a, 0x53, 0x80, 0xee,
|
||||
0x90, 0x88, 0xf7, 0xac, 0xe2, 0xef, 0xcd, 0xe9
|
||||
};
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(ESP_OK, err);
|
||||
TEST_ASSERT_NOT_NULL(ptr);
|
||||
unsigned char psa_output[32];
|
||||
unsigned char mbedtls_output[32];
|
||||
size_t psa_output_len;
|
||||
psa_status_t psa_status;
|
||||
int mbedtls_ret;
|
||||
|
||||
/* Compare esp_sha() result to the mbedTLS result, should always be the same */
|
||||
#if CONFIG_MBEDTLS_SHA1_C
|
||||
esp_sha(SHA1, ptr, LEN, sha1_espsha);
|
||||
r = mbedtls_sha1(ptr, LEN, sha1_mbedtls);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
#endif
|
||||
ESP_LOGI(TAG, "=== Test 1: SHA-256(\"abc\") ===");
|
||||
|
||||
esp_sha(SHA2_256, ptr, LEN, sha256_espsha);
|
||||
r = mbedtls_sha256(ptr, LEN, sha256_mbedtls, 0);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
// Test with PSA
|
||||
ESP_LOGI(TAG, "Testing PSA psa_hash_compute()...");
|
||||
psa_status = psa_hash_compute(PSA_ALG_SHA_256, test1_input, test1_input_len,
|
||||
psa_output, sizeof(psa_output), &psa_output_len);
|
||||
ESP_LOGI(TAG, "PSA status: 0x%x, output_len: %zu", (unsigned int)psa_status, psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(32, psa_output_len);
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C
|
||||
esp_sha(SHA2_512, ptr, LEN, sha512_espsha);
|
||||
r = mbedtls_sha512(ptr, LEN, sha512_mbedtls, 0);
|
||||
TEST_ASSERT_EQUAL(0, r);
|
||||
#endif
|
||||
ESP_LOGI(TAG, "PSA result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
psa_output[0], psa_output[1], psa_output[2], psa_output[3],
|
||||
psa_output[4], psa_output[5], psa_output[6], psa_output[7]);
|
||||
ESP_LOGI(TAG, "Expected result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
test1_expected[0], test1_expected[1], test1_expected[2], test1_expected[3],
|
||||
test1_expected[4], test1_expected[5], test1_expected[6], test1_expected[7]);
|
||||
|
||||
/* munmap() 1MB of flash when the usge of memory-mapped ptr is over */
|
||||
spi_flash_munmap(handle);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, psa_output, 32);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-256(\"abc\") PASSED");
|
||||
|
||||
#if CONFIG_MBEDTLS_SHA1_C
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_espsha, sha1_mbedtls, sizeof(sha1_espsha), "SHA1 results should match");
|
||||
#endif
|
||||
// Test with mbedtls_md
|
||||
ESP_LOGI(TAG, "Testing mbedtls_md()...");
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||
TEST_ASSERT_NOT_NULL(md_info);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_espsha, sha256_mbedtls, sizeof(sha256_espsha), "SHA256 results should match");
|
||||
mbedtls_ret = mbedtls_md(md_info, test1_input, test1_input_len, mbedtls_output);
|
||||
ESP_LOGI(TAG, "mbedtls_md return: %d", mbedtls_ret);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ret);
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match");
|
||||
#endif
|
||||
ESP_LOGI(TAG, "mbedtls result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
mbedtls_output[0], mbedtls_output[1], mbedtls_output[2], mbedtls_output[3],
|
||||
mbedtls_output[4], mbedtls_output[5], mbedtls_output[6], mbedtls_output[7]);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, mbedtls_output, 32);
|
||||
ESP_LOGI(TAG, "✓ mbedtls_md SHA-256(\"abc\") PASSED");
|
||||
|
||||
// Verify both methods produce the same result
|
||||
TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 32);
|
||||
ESP_LOGI(TAG, "✓ PSA and mbedtls_md results match");
|
||||
|
||||
ESP_LOGI(TAG, "=== Test 2: SHA-256(\"\") (empty string) ===");
|
||||
|
||||
// Test with PSA
|
||||
psa_status = psa_hash_compute(PSA_ALG_SHA_256, test2_input, test2_input_len,
|
||||
psa_output, sizeof(psa_output), &psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(32, psa_output_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, psa_output, 32);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-256(\"\") PASSED");
|
||||
|
||||
// Test with mbedtls_md
|
||||
mbedtls_ret = mbedtls_md(md_info, test2_input, test2_input_len, mbedtls_output);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ret);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, mbedtls_output, 32);
|
||||
ESP_LOGI(TAG, "✓ mbedtls_md SHA-256(\"\") PASSED");
|
||||
|
||||
// Verify both methods produce the same result
|
||||
TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 32);
|
||||
ESP_LOGI(TAG, "✓ All PSA SHA-256 tests PASSED!");
|
||||
|
||||
// Test Vector 3: SHA-256("hello world")
|
||||
// This will do with PSA only but _update will be called multiple time
|
||||
|
||||
ESP_LOGI(TAG, "=== Test 3: SHA-256(\"hello world\") ===");
|
||||
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
|
||||
psa_status = psa_hash_setup(&operation, PSA_ALG_SHA_256);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_update(&operation, (const uint8_t *)test3_input, 5); // "hello"
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_update(&operation, (const uint8_t *)(test3_input + 5), 6); // " world"
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_finish(&operation, psa_output, sizeof(psa_output), &psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(32, psa_output_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test3_expected, psa_output, 32);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-256(\"hello world\") PASSED");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
|
||||
TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]")
|
||||
TEST_CASE("Test PSA SHA-384 with known test vectors", "[hw_crypto][psa]")
|
||||
{
|
||||
const size_t BUFFER_SZ = 128;
|
||||
int ret;
|
||||
unsigned char output[64] = { 0 };
|
||||
void *buffer = heap_caps_malloc(BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buffer);
|
||||
memset(buffer, 0xEE, BUFFER_SZ);
|
||||
ESP_LOGI(TAG, "Testing PSA SHA-384 implementation with known test vectors");
|
||||
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
// Test Vector 1: SHA-384("abc")
|
||||
// Expected: cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
|
||||
const unsigned char test1_input[] = "abc";
|
||||
const size_t test1_input_len = 3;
|
||||
const unsigned char test1_expected[48] = {
|
||||
0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
|
||||
0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
|
||||
0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
|
||||
0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
|
||||
0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
|
||||
0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7
|
||||
};
|
||||
|
||||
const uint8_t sha1_expected[20] = { 0x41, 0x63, 0x12, 0x5b, 0x9c, 0x68, 0x85, 0xc8,
|
||||
0x01, 0x40, 0xf4, 0x03, 0x5d, 0x0d, 0x84, 0x0e,
|
||||
0xa4, 0xae, 0x4d, 0xe9 };
|
||||
// Test Vector 2: SHA-384("")
|
||||
// Expected: 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
|
||||
const unsigned char test2_input[] = "";
|
||||
const size_t test2_input_len = 0;
|
||||
const unsigned char test2_expected[48] = {
|
||||
0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
|
||||
0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
|
||||
0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
|
||||
0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
|
||||
0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
|
||||
0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b
|
||||
};
|
||||
|
||||
mbedtls_sha1_init(&sha1_ctx);
|
||||
mbedtls_sha1_starts(&sha1_ctx);
|
||||
// Test Vector 3: SHA-384("hello world")
|
||||
// Expected: fdbd8e75a67f29f701a4e040385e2e23986303ea10239211af907fcbb83578b3e417cb71ce646efd0819dd8c088de1bd
|
||||
const unsigned char test3_input[] = "hello world";
|
||||
const unsigned char test3_expected[48] = {
|
||||
0xfd, 0xbd, 0x8e, 0x75, 0xa6, 0x7f, 0x29, 0xf7,
|
||||
0x01, 0xa4, 0xe0, 0x40, 0x38, 0x5e, 0x2e, 0x23,
|
||||
0x98, 0x63, 0x03, 0xea, 0x10, 0x23, 0x92, 0x11,
|
||||
0xaf, 0x90, 0x7f, 0xcb, 0xb8, 0x35, 0x78, 0xb3,
|
||||
0xe4, 0x17, 0xcb, 0x71, 0xce, 0x64, 0x6e, 0xfd,
|
||||
0x08, 0x19, 0xdd, 0x8c, 0x08, 0x8d, 0xe1, 0xbd
|
||||
};
|
||||
|
||||
ret = mbedtls_internal_sha1_process(&sha1_ctx, buffer);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
unsigned char psa_output[48];
|
||||
unsigned char mbedtls_output[48];
|
||||
size_t psa_output_len;
|
||||
psa_status_t psa_status;
|
||||
int mbedtls_ret;
|
||||
|
||||
ret = mbedtls_internal_sha1_process(&sha1_ctx, buffer);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
ESP_LOGI(TAG, "=== Test 1: SHA-384(\"abc\") ===");
|
||||
|
||||
#if SOC_SHA_ENDIANNESS_BE
|
||||
for (int i = 0; i < sizeof(sha1_ctx.state)/sizeof(sha1_ctx.state[0]); i++)
|
||||
{
|
||||
*(uint32_t *)(output + i*4) = __builtin_bswap32(sha1_ctx.state[i]);
|
||||
}
|
||||
#else
|
||||
memcpy(output, sha1_ctx.state, 20);
|
||||
#endif
|
||||
// Test with PSA
|
||||
ESP_LOGI(TAG, "Testing PSA psa_hash_compute()...");
|
||||
psa_status = psa_hash_compute(PSA_ALG_SHA_384, test1_input, test1_input_len,
|
||||
psa_output, sizeof(psa_output), &psa_output_len);
|
||||
ESP_LOGI(TAG, "PSA status: 0x%x, output_len: %zu", (unsigned int)psa_status, psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(48, psa_output_len);
|
||||
|
||||
// Check if the intermediate states are correct
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, output, sizeof(sha1_expected));
|
||||
ESP_LOGI(TAG, "PSA result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
psa_output[0], psa_output[1], psa_output[2], psa_output[3],
|
||||
psa_output[4], psa_output[5], psa_output[6], psa_output[7]);
|
||||
ESP_LOGI(TAG, "Expected result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
test1_expected[0], test1_expected[1], test1_expected[2], test1_expected[3],
|
||||
test1_expected[4], test1_expected[5], test1_expected[6], test1_expected[7]);
|
||||
|
||||
ret = mbedtls_sha1_finish(&sha1_ctx, output);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, psa_output, 48);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-384(\"abc\") PASSED");
|
||||
|
||||
mbedtls_sha1_free(&sha1_ctx);
|
||||
// Test with mbedtls_md
|
||||
ESP_LOGI(TAG, "Testing mbedtls_md()...");
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
|
||||
TEST_ASSERT_NOT_NULL(md_info);
|
||||
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
mbedtls_sha512_context sha512_ctx;
|
||||
mbedtls_ret = mbedtls_md(md_info, test1_input, test1_input_len, mbedtls_output);
|
||||
ESP_LOGI(TAG, "mbedtls_md return: %d", mbedtls_ret);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ret);
|
||||
|
||||
const uint8_t sha512_expected[64] = { 0x3c, 0x77, 0x5f, 0xb0, 0x3b, 0x25, 0x8d, 0x3b,
|
||||
0xa9, 0x28, 0xa2, 0x29, 0xf2, 0x14, 0x7d, 0xb3,
|
||||
0x64, 0x1e, 0x76, 0xd5, 0x0b, 0xbc, 0xdf, 0xb4,
|
||||
0x75, 0x1d, 0xe7, 0x7f, 0x62, 0x83, 0xdd, 0x78,
|
||||
0x6b, 0x0e, 0xa4, 0xd2, 0xbe, 0x51, 0x56, 0xd4,
|
||||
0xfe, 0x3b, 0xa3, 0x3a, 0xd7, 0xf6, 0xd3, 0xb3,
|
||||
0xe7, 0x9d, 0xb5, 0xe6, 0x76, 0x35, 0x2a, 0xae,
|
||||
0x07, 0x0a, 0x3a, 0x03, 0x44, 0xf0, 0xb8, 0xfe };
|
||||
ESP_LOGI(TAG, "mbedtls result: %02x %02x %02x %02x %02x %02x %02x %02x...",
|
||||
mbedtls_output[0], mbedtls_output[1], mbedtls_output[2], mbedtls_output[3],
|
||||
mbedtls_output[4], mbedtls_output[5], mbedtls_output[6], mbedtls_output[7]);
|
||||
|
||||
mbedtls_sha512_init(&sha512_ctx);
|
||||
mbedtls_sha512_starts(&sha512_ctx, 0);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, mbedtls_output, 48);
|
||||
ESP_LOGI(TAG, "✓ mbedtls_md SHA-384(\"abc\") PASSED");
|
||||
|
||||
ret = mbedtls_internal_sha512_process(&sha512_ctx, buffer);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
// Verify both methods produce the same result
|
||||
TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 48);
|
||||
ESP_LOGI(TAG, "✓ PSA and mbedtls_md results match");
|
||||
|
||||
ret = mbedtls_internal_sha512_process(&sha512_ctx, buffer);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
ESP_LOGI(TAG, "=== Test 2: SHA-384(\"\") (empty string) ===");
|
||||
|
||||
#if SOC_SHA_ENDIANNESS_BE
|
||||
for (int i = 0; i < sizeof(sha512_ctx.state)/sizeof(sha512_ctx.state[0]); i++)
|
||||
{
|
||||
*(uint64_t *)(output + i*8) = __builtin_bswap64(sha512_ctx.state[i]);
|
||||
}
|
||||
#else
|
||||
memcpy(output, sha512_ctx.state, 64);
|
||||
#endif
|
||||
// Test with PSA
|
||||
psa_status = psa_hash_compute(PSA_ALG_SHA_384, test2_input, test2_input_len,
|
||||
psa_output, sizeof(psa_output), &psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(48, psa_output_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, psa_output, 48);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-384(\"\") PASSED");
|
||||
|
||||
// Check if the intermediate states are correct
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, output, sizeof(sha512_expected));
|
||||
// Test with mbedtls_md
|
||||
mbedtls_ret = mbedtls_md(md_info, test2_input, test2_input_len, mbedtls_output);
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_ret);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, mbedtls_output, 48);
|
||||
ESP_LOGI(TAG, "✓ mbedtls_md SHA-384(\"\") PASSED");
|
||||
|
||||
ret = mbedtls_sha512_finish(&sha512_ctx, output);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
// Verify both methods produce the same result
|
||||
TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 48);
|
||||
ESP_LOGI(TAG, "✓ All PSA SHA-384 tests PASSED!");
|
||||
|
||||
mbedtls_sha512_free(&sha512_ctx);
|
||||
|
||||
#endif
|
||||
free(buffer);
|
||||
// Test Vector 3: SHA-384("hello world")
|
||||
// This will do with PSA only but _update will be called multiple time
|
||||
|
||||
ESP_LOGI(TAG, "=== Test 3: SHA-384(\"hello world\") ===");
|
||||
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
|
||||
psa_status = psa_hash_setup(&operation, PSA_ALG_SHA_384);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_update(&operation, (const uint8_t *)test3_input, 5); // "hello"
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_update(&operation, (const uint8_t *)(test3_input + 5), 6); // " world"
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_finish(&operation, psa_output, sizeof(psa_output), &psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(48, psa_output_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test3_expected, psa_output, 48);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-384(\"hello world\") PASSED");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SOC_SHA_SUPPORTED && CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
TEST_CASE("Test PSA SHA-384 with clone", "[hw_crypto][psa]")
|
||||
{
|
||||
// Test Vector 1: SHA-384("hello world")
|
||||
// Expected: fdbd8e75a67f29f701a4e040385e2e23986303ea10239211af907fcbb83578b3e417cb71ce646efd0819dd8c088de1bd
|
||||
const unsigned char test3_input[] = "hello world";
|
||||
const unsigned char test3_expected[48] = {
|
||||
0xfd, 0xbd, 0x8e, 0x75, 0xa6, 0x7f, 0x29, 0xf7,
|
||||
0x01, 0xa4, 0xe0, 0x40, 0x38, 0x5e, 0x2e, 0x23,
|
||||
0x98, 0x63, 0x03, 0xea, 0x10, 0x23, 0x92, 0x11,
|
||||
0xaf, 0x90, 0x7f, 0xcb, 0xb8, 0x35, 0x78, 0xb3,
|
||||
0xe4, 0x17, 0xcb, 0x71, 0xce, 0x64, 0x6e, 0xfd,
|
||||
0x08, 0x19, 0xdd, 0x8c, 0x08, 0x8d, 0xe1, 0xbd
|
||||
};
|
||||
|
||||
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t psa_status = psa_hash_setup(&operation, PSA_ALG_SHA_384);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_update(&operation, (const uint8_t *)test3_input, 5); // "hello"
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
|
||||
psa_hash_operation_t clone = PSA_HASH_OPERATION_INIT;
|
||||
psa_status = psa_hash_clone(&operation, &clone);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
psa_status = psa_hash_update(&clone, (const uint8_t *)(test3_input + 5), 6); // " world"
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
unsigned char psa_output[48];
|
||||
size_t psa_output_len;
|
||||
psa_status = psa_hash_finish(&clone, psa_output, sizeof(psa_output), &psa_output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status);
|
||||
TEST_ASSERT_EQUAL(48, psa_output_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(test3_expected, psa_output, 48);
|
||||
ESP_LOGI(TAG, "✓ PSA SHA-384(\"hello world\") with original PASSED");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,39 +10,45 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "test_utils.h"
|
||||
#include "ccomp_timer.h"
|
||||
#include "test_mbedtls_utils.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
TEST_CASE("mbedtls SHA performance", "[mbedtls]")
|
||||
TEST_CASE("psa SHA256 performance", "[mbedtls]")
|
||||
{
|
||||
const unsigned CALLS = 256;
|
||||
const unsigned CALL_SZ = 16 * 1024;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
float elapsed_usec;
|
||||
unsigned char sha256[32];
|
||||
|
||||
|
||||
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = psa_hash_setup(&operation, PSA_ALG_SHA_256);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
// allocate internal memory
|
||||
uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(buf);
|
||||
memset(buf, 0x55, CALL_SZ);
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
ccomp_timer_start();
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false));
|
||||
for (int c = 0; c < CALLS; c++) {
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, buf, CALL_SZ));
|
||||
status = psa_hash_update(&operation, buf, CALL_SZ);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256));
|
||||
size_t hash_length;
|
||||
status = psa_hash_finish(&operation, sha256, sizeof(sha256), &hash_length);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
elapsed_usec = ccomp_timer_stop();
|
||||
|
||||
free(buf);
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
|
||||
/* Check the result. Reference value can be calculated using:
|
||||
* dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\125' | sha256sum
|
||||
|
||||
@@ -91,17 +91,18 @@ def test_mbedtls_ecdsa_sign(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(group='efuse_key')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'rom_impl',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
|
||||
def test_mbedtls_rom_impl_esp32c2(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
# TODO: IDF-15012
|
||||
# @pytest.mark.generic
|
||||
# @pytest.mark.parametrize(
|
||||
# 'config',
|
||||
# [
|
||||
# 'rom_impl',
|
||||
# ],
|
||||
# indirect=True,
|
||||
# )
|
||||
# @idf_parametrize('target', ['esp32c2'], indirect=['target'])
|
||||
# def test_mbedtls_rom_impl_esp32c2(dut: Dut) -> None:
|
||||
# dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
CONFIG_IDF_TARGET="esp32c2"
|
||||
CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y
|
||||
# TODO: IDF-15012
|
||||
# CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y
|
||||
|
||||
Reference in New Issue
Block a user