fix(esp_tee): Prevent IV reuse in the TEE secure storage AES-GCM service

This commit is contained in:
Laukik Hase
2026-02-11 12:29:52 +05:30
parent 148e333495
commit 68d31180f0
18 changed files with 105 additions and 104 deletions
@@ -112,10 +112,11 @@ tee_sec_stg_encrypt <key_id> <plaintext>
<key_id> TEE Secure storage key ID
<plaintext> Plaintext to be encrypted
tee_sec_stg_decrypt <key_id> <ciphertext> <tag>
tee_sec_stg_decrypt <key_id> <ciphertext> <iv> <tag>
Decrypt data using AES-GCM key with the given ID from secure storage
<key_id> TEE Secure storage key ID
<ciphertext> Ciphertext to be decrypted
<iv> AES-GCM initialization vector
<tag> AES-GCM authentication tag
help [<string>] [-v <0|1>]
@@ -180,10 +181,12 @@ esp32c6> tee_sec_stg_gen_key aes256_k0 0
I (2784) tee_sec_stg: Generated AES256 key with ID key0
esp32c6> tee_sec_stg_encrypt aes256_k0 b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
I (3084) tee_sec_stg: Ciphertext -
58054310a96d48c2dccdf2e34005aa63b40817723d3ec3d597ab362efea084c1
f72e44dda3b2d0a44ffc8cafd2f28b7933776dce78684c5514f9398daf3dc344
I (3294) tee_sec_stg: IV -
ef5c08c05828cf933440f121
I (3594) tee_sec_stg: Tag -
caeedb43e08dc3b4e35a58b2412908cc
esp32c6> tee_sec_stg_decrypt aes256_k0 58054310a96d48c2dccdf2e34005aa63b40817723d3ec3d597ab362efea084c1 caeedb43e08dc3b4e35a58b2412908cc
826a2e65f0e1d8aede1fb12e78957f0d
esp32c6> tee_sec_stg_decrypt aes256_k0 f72e44dda3b2d0a44ffc8cafd2f28b7933776dce78684c5514f9398daf3dc344 ef5c08c05828cf933440f121 826a2e65f0e1d8aede1fb12e78957f0d
I (4314) tee_sec_stg: Decrypted plaintext -
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
```
@@ -33,7 +33,7 @@ static void setup_console(void)
* This can be customized, made dynamic, etc.
*/
repl_config.prompt = PROMPT_STR ">";
repl_config.max_cmdline_length = 128;
repl_config.max_cmdline_length = 256;
/* Register help command */
ESP_ERROR_CHECK(esp_console_register_help_command());
@@ -28,6 +28,7 @@
#endif /* CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN */
#define AES256_GCM_TAG_LEN (16)
#define AES256_GCM_IV_LEN (12)
#define MAX_AES_PLAINTEXT_LEN (256)
#define ECDSA_SECP256R1_KEY_LEN (32)
@@ -347,6 +348,7 @@ static int tee_sec_stg_encrypt(int argc, char **argv)
esp_err_t err = ESP_FAIL;
uint8_t tag[AES256_GCM_TAG_LEN];
uint8_t iv[AES256_GCM_IV_LEN];
const char *key_id = (const char *)tee_sec_stg_encrypt_args.key_str_id->sval[0];
const char *plaintext = tee_sec_stg_encrypt_args.plaintext->sval[0];
@@ -383,7 +385,7 @@ static int tee_sec_stg_encrypt(int argc, char **argv)
.input_len = plaintext_buf_len
};
err = esp_tee_sec_storage_aead_encrypt(&ctx, tag, sizeof(tag), ciphertext_buf);
err = esp_tee_sec_storage_aead_encrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext_buf);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to encrypt data: %s", esp_err_to_name(err));
goto exit;
@@ -399,7 +401,11 @@ static int tee_sec_stg_encrypt(int argc, char **argv)
char tag_hexstr[AES256_GCM_TAG_LEN * 2 + 1];
hexbuf_to_hexstr(tag, sizeof(tag), tag_hexstr, sizeof(tag_hexstr));
char iv_hexstr[AES256_GCM_IV_LEN * 2 + 1];
hexbuf_to_hexstr(iv, sizeof(iv), iv_hexstr, sizeof(iv_hexstr));
ESP_LOGI(TAG, "Ciphertext -\n%s", ciphertext);
ESP_LOGI(TAG, "IV -\n%s", iv_hexstr);
ESP_LOGI(TAG, "Tag -\n%s", tag_hexstr);
free(plaintext_buf);
@@ -430,6 +436,7 @@ void register_srv_sec_stg_encrypt(void)
static struct {
struct arg_str *key_str_id;
struct arg_str *ciphertext;
struct arg_str *iv;
struct arg_str *tag;
struct arg_end *end;
} tee_sec_stg_decrypt_args;
@@ -445,6 +452,10 @@ static int tee_sec_stg_decrypt(int argc, char **argv)
esp_err_t err = ESP_FAIL;
const char *key_id = (const char *)tee_sec_stg_decrypt_args.key_str_id->sval[0];
const char *iv_hexstr = tee_sec_stg_decrypt_args.iv->sval[0];
uint8_t iv[AES256_GCM_IV_LEN];
hexstr_to_hexbuf(iv_hexstr, strlen(iv_hexstr), iv, sizeof(iv));
const char *tag_hexstr = tee_sec_stg_decrypt_args.tag->sval[0];
uint8_t tag[AES256_GCM_TAG_LEN];
hexstr_to_hexbuf(tag_hexstr, strlen(tag_hexstr), tag, sizeof(tag));
@@ -483,7 +494,7 @@ static int tee_sec_stg_decrypt(int argc, char **argv)
.input_len = ciphertext_buf_len
};
err = esp_tee_sec_storage_aead_decrypt(&ctx, tag, sizeof(tag), plaintext_buf);
err = esp_tee_sec_storage_aead_decrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), plaintext_buf);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to decrypt data: %s", esp_err_to_name(err));
goto exit;
@@ -510,8 +521,9 @@ void register_srv_sec_stg_decrypt(void)
{
tee_sec_stg_decrypt_args.key_str_id = arg_str1(NULL, NULL, "<key_id>", "TEE Secure storage key ID");
tee_sec_stg_decrypt_args.ciphertext = arg_str1(NULL, NULL, "<ciphertext>", "Ciphertext to be decrypted");
tee_sec_stg_decrypt_args.iv = arg_str1(NULL, NULL, "<iv>", "AES-GCM initialization vector");
tee_sec_stg_decrypt_args.tag = arg_str1(NULL, NULL, "<tag>", "AES-GCM authentication tag");
tee_sec_stg_decrypt_args.end = arg_end(3);
tee_sec_stg_decrypt_args.end = arg_end(4);
const esp_console_cmd_t tee_sec_stg = {
.command = "tee_sec_stg_decrypt",
@@ -76,9 +76,10 @@ def test_tee_cli_secure_storage(dut: Dut) -> None:
dut.write(f'tee_sec_stg_encrypt {sec_stg_key_ids.get(i)} {test_msg_hash}')
test_msg_cipher = dut.expect(r'Ciphertext -\s*([0-9a-fA-F]{64})', timeout=30)[1].decode()
test_msg_iv = dut.expect(r'IV -\s*([0-9a-fA-F]{24})', timeout=30)[1].decode()
test_msg_tag = dut.expect(r'Tag -\s*([0-9a-fA-F]{32})', timeout=30)[1].decode()
dut.write(f'tee_sec_stg_decrypt {sec_stg_key_ids.get(i)} {test_msg_cipher} {test_msg_tag}')
dut.write(f'tee_sec_stg_decrypt {sec_stg_key_ids.get(i)} {test_msg_cipher} {test_msg_iv} {test_msg_tag}')
test_msg_decipher = dut.expect(r'Decrypted plaintext -\s*([0-9a-fA-F]{64})', timeout=30)[1].decode()
assert test_msg_decipher == test_msg_hash