mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
fix(esp_tee): Prevent IV reuse in the TEE secure storage AES-GCM service
This commit is contained in:
@@ -97,11 +97,12 @@ 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> <tag> <iv>
|
||||
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
|
||||
<tag> AES-GCM authentication tag
|
||||
<iv> AES-GCM initialization vector
|
||||
|
||||
help [<string>] [-v <0|1>]
|
||||
Print the summary of all registered commands if no arguments are given,
|
||||
@@ -135,8 +136,8 @@ I (8180) tee_attest: Attestation token - Data:
|
||||
- The TEE secure storage service provides the following commands:
|
||||
- `tee_sec_stg_gen_key`: Generate and store a new key (ECDSA or AES) in the TEE secure storage with the specified ID
|
||||
- `tee_sec_stg_sign`: Sign a message using an ECDSA `secp256r1` key pair with the specified ID and verify the signature
|
||||
- `tee_sec_stg_encrypt`: Encrypt data with AES256-GCM using the key with the specified ID and outputs the ciphertext and tag
|
||||
- `tee_sec_stg_decrypt`: Decrypt ciphertext using key with the specified ID and tag for integrity verification
|
||||
- `tee_sec_stg_encrypt`: Encrypt data with AES256-GCM using the key with the specified ID and outputs the ciphertext, tag and the IV used
|
||||
- `tee_sec_stg_decrypt`: Decrypt ciphertext using key with the specified ID, tag and used IV for integrity verification
|
||||
- The `get_msg_sha256` command computes the SHA256 hash of a given message, which can be used as input for the `tee_sec_stg_sign` command.
|
||||
|
||||
<details>
|
||||
@@ -163,14 +164,16 @@ I (6444) tee_sec_stg: Signature verified successfully!
|
||||
|
||||
```log
|
||||
esp32c6> tee_sec_stg_gen_key aes256_k0 0
|
||||
I (2784) tee_sec_stg: Generated AES256 key with ID key0
|
||||
I (2784) tee_sec_stg: Generated AES256 key with ID aes256_k0
|
||||
esp32c6> tee_sec_stg_encrypt aes256_k0 b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
|
||||
I (3084) tee_sec_stg: Ciphertext -
|
||||
58054310a96d48c2dccdf2e34005aa63b40817723d3ec3d597ab362efea084c1
|
||||
I (3594) tee_sec_stg: Tag -
|
||||
caeedb43e08dc3b4e35a58b2412908cc
|
||||
esp32c6> tee_sec_stg_decrypt aes256_k0 58054310a96d48c2dccdf2e34005aa63b40817723d3ec3d597ab362efea084c1 caeedb43e08dc3b4e35a58b2412908cc
|
||||
I (4314) tee_sec_stg: Decrypted plaintext -
|
||||
40ff09c61af2f94611fb605806489380132b0000f2c63863366aad56ad327e95
|
||||
I (3084) tee_sec_stg: Tag -
|
||||
8136e8bfc3c70ca792fa486b3eeca72b
|
||||
I (3084) tee_sec_stg: IV -
|
||||
0f202954f1a1a138a2ab8b06
|
||||
esp32c6> tee_sec_stg_decrypt aes256_k0 40ff09c61af2f94611fb605806489380132b0000f2c63863366aad56ad327e95 8136e8bfc3c70ca792fa486b3eeca72b 0f202954f1a1a138a2ab8b06
|
||||
I (3594) 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());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -416,8 +416,12 @@ 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[AES_GCM_SUPPORTED_IV_LEN * 2 + 1];
|
||||
hexbuf_to_hexstr(ctx.iv, sizeof(ctx.iv), iv_hexstr, sizeof(iv_hexstr));
|
||||
|
||||
ESP_LOGI(TAG, "Ciphertext -\n%s", ciphertext);
|
||||
ESP_LOGI(TAG, "Tag -\n%s", tag_hexstr);
|
||||
ESP_LOGI(TAG, "IV -\n%s", iv_hexstr);
|
||||
|
||||
free(plaintext_buf);
|
||||
free(ciphertext_buf);
|
||||
@@ -448,6 +452,7 @@ static struct {
|
||||
struct arg_str *key_str_id;
|
||||
struct arg_str *ciphertext;
|
||||
struct arg_str *tag;
|
||||
struct arg_str *iv;
|
||||
struct arg_end *end;
|
||||
} tee_sec_stg_decrypt_args;
|
||||
|
||||
@@ -466,6 +471,10 @@ static int tee_sec_stg_decrypt(int argc, char **argv)
|
||||
uint8_t tag[AES256_GCM_TAG_LEN];
|
||||
hexstr_to_hexbuf(tag_hexstr, strlen(tag_hexstr), tag, sizeof(tag));
|
||||
|
||||
const char *iv_hexstr = tee_sec_stg_decrypt_args.iv->sval[0];
|
||||
uint8_t iv[AES_GCM_SUPPORTED_IV_LEN];
|
||||
hexstr_to_hexbuf(iv_hexstr, strlen(iv_hexstr), iv, sizeof(iv));
|
||||
|
||||
const char *ciphertext = tee_sec_stg_decrypt_args.ciphertext->sval[0];
|
||||
size_t ciphertext_len = strnlen(ciphertext, MAX_AES_PLAINTEXT_LEN);
|
||||
if (ciphertext_len == MAX_AES_PLAINTEXT_LEN && ciphertext[MAX_AES_PLAINTEXT_LEN] != '\0') {
|
||||
@@ -499,6 +508,8 @@ static int tee_sec_stg_decrypt(int argc, char **argv)
|
||||
.input = (uint8_t *)ciphertext_buf,
|
||||
.input_len = ciphertext_buf_len
|
||||
};
|
||||
/* Copying the IV generated during encryption */
|
||||
memcpy(ctx.iv, iv, sizeof(iv));
|
||||
|
||||
err = esp_tee_sec_storage_aead_decrypt(&ctx, tag, sizeof(tag), plaintext_buf);
|
||||
if (err != ESP_OK) {
|
||||
@@ -528,7 +539,8 @@ 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.tag = arg_str1(NULL, NULL, "<tag>", "AES-GCM authentication tag");
|
||||
tee_sec_stg_decrypt_args.end = arg_end(3);
|
||||
tee_sec_stg_decrypt_args.iv = arg_str1(NULL, NULL, "<iv>", "AES-GCM initialization vector");
|
||||
tee_sec_stg_decrypt_args.end = arg_end(4);
|
||||
|
||||
const esp_console_cmd_t tee_sec_stg = {
|
||||
.command = "tee_sec_stg_decrypt",
|
||||
|
||||
@@ -77,8 +77,9 @@ 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_tag = dut.expect(r'Tag -\s*([0-9a-fA-F]{32})', timeout=30)[1].decode()
|
||||
test_msg_iv = dut.expect(r'IV -\s*([0-9a-fA-F]{24})', 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_tag} {test_msg_iv}')
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user