diff --git a/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c b/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c index 0954122bde2..1c9933a497a 100644 --- a/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c +++ b/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -161,11 +161,35 @@ esp_err_t esp_att_utils_eat_data_to_json(struct esp_att_sw_claim_list *head, con json_gen_obj_set_int(&json_gen, "nonce", cfg->nonce); json_gen_obj_set_int(&json_gen, "client_id", cfg->client_id); + json_gen_obj_set_int(&json_gen, "chip_id", cfg->chip_id); json_gen_obj_set_int(&json_gen, "device_ver", cfg->device_ver); - char dev_id_hexstr[ESP_ATT_EAT_DEV_ID_SZ * 2 + 1] = {0}; - esp_err_t err = esp_att_utils_hexbuf_to_hexstr(cfg->device_id, sizeof(cfg->device_id), dev_id_hexstr, sizeof(dev_id_hexstr)); + json_gen_push_object(&json_gen, "ueid"); + + char mac_hexstr[ESP_ATT_EAT_UEID_MAC_SZ * 2 + 1] = {0}; + esp_err_t err = esp_att_utils_hexbuf_to_hexstr(cfg->ueid_mac, sizeof(cfg->ueid_mac), + mac_hexstr, sizeof(mac_hexstr)); if (err != ESP_OK) { + free(json_buf); + return err; + } + json_gen_obj_set_string(&json_gen, "mac", mac_hexstr); + + char opt_id_hexstr[ESP_ATT_EAT_UEID_OPT_ID_SZ * 2 + 1] = {0}; + err = esp_att_utils_hexbuf_to_hexstr(cfg->ueid_opt_id, sizeof(cfg->ueid_opt_id), + opt_id_hexstr, sizeof(opt_id_hexstr)); + if (err != ESP_OK) { + free(json_buf); + return err; + } + json_gen_obj_set_string(&json_gen, "optional_id", opt_id_hexstr); + + json_gen_pop_object(&json_gen); + + char dev_id_hexstr[ESP_ATT_EAT_DEV_ID_SZ * 2 + 1] = {0}; + err = esp_att_utils_hexbuf_to_hexstr(cfg->device_id, sizeof(cfg->device_id), dev_id_hexstr, sizeof(dev_id_hexstr)); + if (err != ESP_OK) { + free(json_buf); return err; } json_gen_obj_set_string(&json_gen, "device_id", dev_id_hexstr); @@ -186,6 +210,7 @@ esp_err_t esp_att_utils_eat_data_to_json(struct esp_att_sw_claim_list *head, con esp_err_t err = part_metadata_to_json(&claim->metadata, &claim_json); if (err != ESP_OK || claim_json == NULL) { ESP_LOGE(TAG, "Failed to format the FW metadata to JSON!"); + free(json_buf); return err; } diff --git a/components/esp_tee/subproject/components/attestation/esp_attestation.c b/components/esp_tee/subproject/components/attestation/esp_attestation.c index 2fa56295f12..a24be4da953 100644 --- a/components/esp_tee/subproject/components/attestation/esp_attestation.c +++ b/components/esp_tee/subproject/components/attestation/esp_attestation.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -50,49 +50,23 @@ static void free_sw_claim_list(void) } } -static esp_err_t fetch_device_id(uint8_t *devid_buf) +static esp_err_t fetch_ueids(esp_att_token_cfg_t *cfg) { - if (devid_buf == NULL) { - return ESP_ERR_INVALID_ARG; - } - - uint8_t mac_addr[6] = {0}; - esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_MAC, mac_addr, sizeof(mac_addr) * 8); + /* UEID: raw eFuse MAC */ + esp_err_t err = esp_efuse_read_field_blob(ESP_EFUSE_MAC, cfg->ueid_mac, + ESP_ATT_EAT_UEID_MAC_SZ * 8); if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to read MAC from eFuse!"); - goto exit; + return err; } - mbedtls_sha256_context ctx; - mbedtls_sha256_init(&ctx); - - int ret = mbedtls_sha256_starts(&ctx, false); - if (ret != 0) { - mbedtls_sha256_free(&ctx); - err = ESP_FAIL; - goto exit; + /* UEID: 128-bit OPTIONAL_UNIQUE_ID */ + err = esp_efuse_read_field_blob(ESP_EFUSE_OPTIONAL_UNIQUE_ID, cfg->ueid_opt_id, + ESP_ATT_EAT_UEID_OPT_ID_SZ * 8); + if (err != ESP_OK) { + return err; } - ret = mbedtls_sha256_update(&ctx, (const unsigned char *)mac_addr, sizeof(mac_addr)); - if (ret != 0) { - mbedtls_sha256_free(&ctx); - err = ESP_FAIL; - goto exit; - } - - uint8_t digest[SHA256_DIGEST_SZ] = {0}; - ret = mbedtls_sha256_finish(&ctx, digest); - if (ret != 0) { - mbedtls_sha256_free(&ctx); - err = ESP_FAIL; - goto exit; - } - - memcpy(devid_buf, digest, SHA256_DIGEST_SZ); - mbedtls_sha256_free(&ctx); - -exit: - return err; + return ESP_OK; } static esp_err_t populate_att_token_cfg(esp_att_token_cfg_t *cfg, const esp_att_ecdsa_keypair_t *keypair) @@ -101,18 +75,29 @@ static esp_err_t populate_att_token_cfg(esp_att_token_cfg_t *cfg, const esp_att_ return ESP_ERR_INVALID_ARG; } - esp_err_t err = fetch_device_id(cfg->device_id); + esp_err_t err = fetch_ueids(cfg); if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to get the device ID!"); + ESP_LOGE(TAG, "Failed to get the UEIDs!"); return err; } + /* Device ID = SHA-256 of the MAC */ + int ret = mbedtls_sha256(cfg->ueid_mac, sizeof(cfg->ueid_mac), cfg->device_id, 0); + if (ret != 0) { + ESP_LOGE(TAG, "Failed to derive the device ID!"); + return ESP_FAIL; + } + err = esp_att_utils_ecdsa_get_pubkey_digest(keypair, cfg->instance_id, sizeof(cfg->instance_id)); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to get ECDSA public key hash!"); return err; } + /* Chip ID read from the ROM */ + extern const uint32_t _rom_chip_id; + cfg->chip_id = _rom_chip_id; + /* Chip revision read from eFuse */ cfg->device_ver = efuse_hal_chip_revision(); /* TODO: Decide what all fields we need here */ cfg->device_stat = 0xA5; diff --git a/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h b/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h index 31963a248a3..a9c5721b098 100644 --- a/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h +++ b/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,6 +33,8 @@ extern "C" { #define ESP_ATT_HDR_JSON_MAX_SZ (128) #define ESP_ATT_EAT_DEV_ID_SZ (32) +#define ESP_ATT_EAT_UEID_MAC_SZ (6) /* eFuse MAC */ +#define ESP_ATT_EAT_UEID_OPT_ID_SZ (16) /* eFuse OPTIONAL_UNIQUE_ID */ #define ESP_ATT_CLAIM_JSON_MAX_SZ (448) #define ESP_ATT_EAT_JSON_MAX_SZ (1344) @@ -110,13 +112,16 @@ typedef struct { * @brief Structure to hold the Entity Attestation Token initial configuration */ typedef struct { - uint32_t nonce; /**< Nonce value */ - uint32_t client_id; /**< Client identifier (Attestation relying party) */ - uint32_t device_ver; /**< Device version */ - uint8_t device_id[SHA256_DIGEST_SZ]; /**< Device identifier */ - uint8_t instance_id[SHA256_DIGEST_SZ]; /**< Instance identifier */ - char psa_cert_ref[32]; /**< PSA certificate reference */ - uint8_t device_stat; /**< Flags indicating device status */ + uint32_t nonce; /**< Nonce value */ + uint32_t client_id; /**< Client identifier (Attestation relying party) */ + uint32_t chip_id; /**< Chip identifier */ + uint32_t device_ver; /**< Device version */ + uint8_t ueid_mac[ESP_ATT_EAT_UEID_MAC_SZ]; /**< Device UEID: MAC from eFuse */ + uint8_t ueid_opt_id[ESP_ATT_EAT_UEID_OPT_ID_SZ]; /**< Device UEID: OPTIONAL_UNIQUE_ID from eFuse */ + uint8_t device_id[SHA256_DIGEST_SZ]; /**< Device identifier (SHA-256 of MAC) */ + uint8_t instance_id[SHA256_DIGEST_SZ]; /**< Instance identifier */ + char psa_cert_ref[32]; /**< PSA certificate reference */ + uint8_t device_stat; /**< Flags indicating device status */ } esp_att_token_cfg_t; /** * @brief Structure to hold an ECDSA key pair diff --git a/components/esp_tee/test_apps/tee_cli_app/README.md b/components/esp_tee/test_apps/tee_cli_app/README.md index e57e581d946..99922b85f85 100644 --- a/components/esp_tee/test_apps/tee_cli_app/README.md +++ b/components/esp_tee/test_apps/tee_cli_app/README.md @@ -123,10 +123,9 @@ help [] [-v <0|1>] ```log esp32c6> tee_att_info -I (8180) tee_attest: Attestation token - Length: 1455 +I (8180) tee_attest: Attestation token - Length: 1620 I (8180) tee_attest: Attestation token - Data: -'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"nonce":-1582119980,"client_id":262974944,"device_ver":0,"device_id":"cd9c173cb3675c7adfae243f0cd9841e4bce003237cb5321927a85a86cb4b32e","instance_id":"9616ef0ecf02cdc89a3749f8fc16b3103d5100bd42d9312fcd04593baa7bac64","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"v0.3.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"94536998e1dcb2a036477cb2feb01ed4fff67ba6208f30482346c62bca64b280","digest_validated":true,"sign_verified":true}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"3d4c038fcec76852b4d07acb9e94afaf5fca69fc2eb212a32032d09ce5b4f2b3","digest_validated":true,"sign_verified":true,"secure_padding":true}},"bootloader":{"type":0,"ver":"","idf_ver":"","secure_ver":-1,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"1bef421beb1a4642c6fcefb3e37fd4afad60cb4074e538f42605b012c482b946","digest_validated":true,"sign_verified":true}}}},"public_key":{"compressed":"02039c4bfab0762af1aff2fe5596b037f629cf839da8c4a9c0018afedfccf519a6"},"sign":{"r":"915e749f5a780bc21a2b21821cfeb54286dc742e9f12f2387e3de9b8b1a70bc9","s":"1e583236f2630b0fe8e291645ffa35d429f14035182e19868508d4dac0e1a441"}}' - +'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"nonce":-1582119980,"client_id":262974944,"chip_id":13,"device_ver":0,"ueid":{"mac":"d885ac67c978","optional_id":"94fa4d7e305682714d48e7bbd710c961"},"device_id":"cd9c173cb3675c7adfae243f0cd9841e4bce003237cb5321927a85a86cb4b32e","instance_id":"9616ef0ecf02cdc89a3749f8fc16b3103d5100bd42d9312fcd04593baa7bac64","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"v0.3.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"94536998e1dcb2a036477cb2feb01ed4fff67ba6208f30482346c62bca64b280","digest_validated":true,"sign_verified":true}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.1.4-241-g7ff01fd46f-dirty","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"3d4c038fcec76852b4d07acb9e94afaf5fca69fc2eb212a32032d09ce5b4f2b3","digest_validated":true,"sign_verified":true,"secure_padding":true}},"bootloader":{"type":0,"ver":"","idf_ver":"","secure_ver":-1,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"1bef421beb1a4642c6fcefb3e37fd4afad60cb4074e538f42605b012c482b946","digest_validated":true,"sign_verified":true}}}},"public_key":{"compressed":"02039c4bfab0762af1aff2fe5596b037f629cf839da8c4a9c0018afedfccf519a6"},"sign":{"r":"915e749f5a780bc21a2b21821cfeb54286dc742e9f12f2387e3de9b8b1a70bc9","s":"1e583236f2630b0fe8e291645ffa35d429f14035182e19868508d4dac0e1a441"}}' ``` diff --git a/docs/en/security/tee/tee-attestation.rst b/docs/en/security/tee/tee-attestation.rst index 7634d852c1e..07284bfb6f1 100644 --- a/docs/en/security/tee/tee-attestation.rst +++ b/docs/en/security/tee/tee-attestation.rst @@ -107,6 +107,12 @@ EAT: Claim Table * - Client ID - Relying Party identification - + * - Chip ID + - SoC chip identifier + - + * - UEID + - Universal Entity Identifiers, factory-burnt in eFuse + - Device MAC address and the Optional Unique ID from eFuse * - Device ID - Device identification (should be unique) - SHA256 digest of the device MAC address @@ -178,7 +184,12 @@ Sample EAT in JSON format "eat": { "nonce": -1582119980, "client_id": 262974944, + "chip_id": 13, "device_ver": 1, + "ueid": { + "mac": "d885ac67c978", + "optional_id": "94fa4d7e305682714d48e7bbd710c961" + }, "device_id": "e8cddb2a7f9a5a7c61735d6dda26e4bd153c6d772a9be6f26bd321dfe25e0ac8", "instance_id": "1adba85e0df997fd961f25a9e312430cef162b5c69466cd5b172f1e65ac7360c", "psa_cert_ref": "0716053550477-10100", diff --git a/examples/security/tee/tee_attestation/README.md b/examples/security/tee/tee_attestation/README.md index 87187254753..776aec067bc 100644 --- a/examples/security/tee/tee_attestation/README.md +++ b/examples/security/tee/tee_attestation/README.md @@ -28,7 +28,12 @@ "eat": { "nonce": -1582119980, "client_id": 262974944, + "chip_id": 13, "device_ver": 1, + "ueid": { + "mac": "d885ac67c978", + "optional_id": "94fa4d7e305682714d48e7bbd710c961" + }, "device_id": "e8cddb2a7f9a5a7c61735d6dda26e4bd153c6d772a9be6f26bd321dfe25e0ac8", "instance_id": "1adba85e0df997fd961f25a9e312430cef162b5c69466cd5b172f1e65ac7360c", "psa_cert_ref": "0716053550477-10100", @@ -127,9 +132,9 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ```log I (438) example_tee_attest: TEE Attestation Service -I (1008) example_tee_attest: Attestation token - Length: 1538 +I (1008) example_tee_attest: Attestation token - Length: 1705 I (1018) example_tee_attest: Attestation token - Data: -'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"nonce":-1582119980,"client_id":262974944,"device_ver":1,"device_id":"4ecc458ef4290329552b4dcdccb99d55e5ea7624f24c87b27b71515e1666f39c","instance_id":"66571b78918f4bb7ae2723f235a9e4fe1c7070ae6261ce5df7049b44b1f8a318","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"1.0.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"5213904fd8ca7538776bdf372c08c13138f20b2fac3503bc878f19c6e36a710d","digest_validated":true,"sign_verified":false,"secure_padding":false}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"65c905fc0fc135fdfa8def210d1c186627cb3a17ecb2e7f020b56411b2d2fc76","digest_validated":true,"sign_verified":false,"secure_padding":false}},"bootloader":{"type":0,"ver":"01000000","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"9efd37d29266f3239f7c6a095df880f1e85e41505f154cfd3bbfad4b8a2b18dd","digest_validated":true,"sign_verified":false}}}},"public_key":{"compressed":"02ce0188c61b0118c86ca20af7e01185dd687c6698b2265a288fee845d083e9066"},"sign":{"r":"362e2053bab26c779559793b2eae89e96c1a058e5fffc49d544d07b934ce3b32","s":"fc5f0e4d329fc6e031cbf425ef62d4756b728392b2a77282baa1f15b554d2716"}}' +'{"header":{"magic":"44fef7cc","encr_alg":"","sign_alg":"ecdsa_secp256r1_sha256","key_id":"tee_att_key0"},"eat":{"nonce":-1582119980,"client_id":262974944,"chip_id":13,"device_ver":1,"ueid":{"mac":"d885ac67c978","optional_id":"94fa4d7e305682714d48e7bbd710c961"},"device_id":"4ecc458ef4290329552b4dcdccb99d55e5ea7624f24c87b27b71515e1666f39c","instance_id":"66571b78918f4bb7ae2723f235a9e4fe1c7070ae6261ce5df7049b44b1f8a318","psa_cert_ref":"0716053550477-10100","device_status":165,"sw_claims":{"tee":{"type":1,"ver":"1.0.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"5213904fd8ca7538776bdf372c08c13138f20b2fac3503bc878f19c6e36a710d","digest_validated":true,"sign_verified":false,"secure_padding":false}},"app":{"type":2,"ver":"v0.1.0","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"65c905fc0fc135fdfa8def210d1c186627cb3a17ecb2e7f020b56411b2d2fc76","digest_validated":true,"sign_verified":false,"secure_padding":false}},"bootloader":{"type":0,"ver":"01000000","idf_ver":"v5.5-dev-2978-gd75a0105dac-dirt","secure_ver":0,"part_chip_rev":{"min":0,"max":99},"part_digest":{"type":0,"calc_digest":"9efd37d29266f3239f7c6a095df880f1e85e41505f154cfd3bbfad4b8a2b18dd","digest_validated":true,"sign_verified":false}}}},"public_key":{"compressed":"02ce0188c61b0118c86ca20af7e01185dd687c6698b2265a288fee845d083e9066"},"sign":{"r":"362e2053bab26c779559793b2eae89e96c1a058e5fffc49d544d07b934ce3b32","s":"fc5f0e4d329fc6e031cbf425ef62d4756b728392b2a77282baa1f15b554d2716"}}' I (1148) main_task: Returned from app_main() ```