diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c index bd7e4cd3351..59e3b9cb665 100644 --- a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c @@ -1,22 +1,18 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include "esp_log.h" -// #include "mbedtls/aes.h" #include "psa_crypto_core.h" -// #include "mbedtls/cipher.h" - #include "aes/esp_aes_gcm.h" #include "psa_crypto_driver_esp_aes_gcm.h" #include "../include/psa_crypto_driver_esp_aes_contexts.h" -// #ifdef ESP_MBEDTLS_AES_ACCEL #if defined(ESP_AES_DRIVER_ENABLED) -#define ESP_AES_GCM_TAG_LENGTH 16 +#define ESP_AES_GCM_TAG_LENGTH_DEFAULT 16 static psa_status_t esp_crypto_aes_gcm_setup( esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, @@ -26,12 +22,18 @@ static psa_status_t esp_crypto_aes_gcm_setup( { psa_status_t status = PSA_ERROR_GENERIC_ERROR; esp_gcm_context *ctx = NULL; + size_t tag_length; - if (alg != PSA_ALG_GCM) { + /* Extract the base algorithm and tag length */ + psa_algorithm_t base_alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0); + if (base_alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0)) { status = PSA_ERROR_NOT_SUPPORTED; goto exit; } + /* Get the tag length from the algorithm */ + tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg); + if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) { status = PSA_ERROR_NOT_SUPPORTED; goto exit; @@ -54,6 +56,7 @@ static psa_status_t esp_crypto_aes_gcm_setup( esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx = (void *) ctx; esp_aes_gcm_driver_ctx->mode = mode; + esp_aes_gcm_driver_ctx->tag_length = tag_length; exit: return status; @@ -129,18 +132,29 @@ psa_status_t esp_crypto_aes_gcm_finish( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t finish_output_size = 0; + size_t requested_tag_length = esp_aes_gcm_driver_ctx->tag_length; - if (tag_size < ESP_AES_GCM_TAG_LENGTH) { + if (tag_size < requested_tag_length) { return PSA_ERROR_BUFFER_TOO_SMALL; } + if (requested_tag_length > ESP_AES_GCM_TAG_LENGTH_DEFAULT) { + return PSA_ERROR_INVALID_ARGUMENT; + } + esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx; - status = mbedtls_to_psa_error(esp_aes_gcm_finish(ctx, output, output_size, output_length, tag, tag_size)); + + /* esp_aes_gcm_finish always generates a 16-byte tag, but we'll only use + * the first requested_tag_length bytes */ + uint8_t full_tag[ESP_AES_GCM_TAG_LENGTH_DEFAULT]; + status = mbedtls_to_psa_error(esp_aes_gcm_finish(ctx, output, output_size, output_length, full_tag, sizeof(full_tag))); if (status == PSA_SUCCESS) { /* This will be zero for all supported algorithms currently, but left * here for future support. */ *output_length = finish_output_size; - *tag_length = ESP_AES_GCM_TAG_LENGTH; + *tag_length = requested_tag_length; + /* Copy only the requested tag length */ + memcpy(tag, full_tag, requested_tag_length); } return status; } @@ -178,13 +192,18 @@ psa_status_t esp_crypto_aes_gcm_encrypt( goto exit; } + size_t tag_length = esp_aes_gcm_driver_ctx.tag_length; + /* For all currently supported modes, the tag is at the end of the * ciphertext. */ - if (ciphertext_size < (plaintext_length + ESP_AES_GCM_TAG_LENGTH)) { + if (ciphertext_size < (plaintext_length + tag_length)) { status = PSA_ERROR_BUFFER_TOO_SMALL; goto exit; } tag = ciphertext + plaintext_length; + + /* esp_aes_gcm_crypt_and_tag always generates a 16-byte tag */ + uint8_t full_tag[ESP_AES_GCM_TAG_LENGTH_DEFAULT]; status = mbedtls_to_psa_error( esp_aes_gcm_crypt_and_tag((esp_gcm_context *) esp_aes_gcm_driver_ctx.esp_aes_gcm_ctx, PSA_CRYPTO_DRIVER_ENCRYPT, @@ -192,10 +211,12 @@ psa_status_t esp_crypto_aes_gcm_encrypt( nonce, nonce_length, additional_data, additional_data_length, plaintext, ciphertext, - ESP_AES_GCM_TAG_LENGTH, tag)); + ESP_AES_GCM_TAG_LENGTH_DEFAULT, full_tag)); if (status == PSA_SUCCESS) { - *ciphertext_length = plaintext_length + ESP_AES_GCM_TAG_LENGTH; + /* Copy only the requested tag length */ + memcpy(tag, full_tag, tag_length); + *ciphertext_length = plaintext_length + tag_length; } exit: @@ -248,22 +269,26 @@ psa_status_t esp_crypto_aes_gcm_decrypt( goto exit; } - status = psa_aead_unpadded_locate_tag(ESP_AES_GCM_TAG_LENGTH, ciphertext, ciphertext_length, plaintext_size, &tag); + size_t tag_length = esp_aes_gcm_driver_ctx.tag_length; + + status = psa_aead_unpadded_locate_tag(tag_length, ciphertext, ciphertext_length, plaintext_size, &tag); if (status != PSA_SUCCESS) { goto exit; - } + } + /* esp_aes_gcm_auth_decrypt supports variable tag lengths (4-16 bytes) + * and will compare only the first tag_length bytes */ status = mbedtls_to_psa_error( esp_aes_gcm_auth_decrypt((esp_gcm_context *) esp_aes_gcm_driver_ctx.esp_aes_gcm_ctx, - ciphertext_length - ESP_AES_GCM_TAG_LENGTH, + ciphertext_length - tag_length, nonce, nonce_length, additional_data, additional_data_length, - tag, ESP_AES_GCM_TAG_LENGTH, + tag, tag_length, ciphertext, plaintext)); if (status == PSA_SUCCESS) { - *plaintext_length = ciphertext_length - ESP_AES_GCM_TAG_LENGTH; + *plaintext_length = ciphertext_length - tag_length; } exit: diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h index e9dfd66436e..cbe889c41c6 100644 --- a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h @@ -43,6 +43,7 @@ typedef struct { typedef struct { void *esp_aes_gcm_ctx; psa_encrypt_or_decrypt_t mode; + size_t tag_length; /* GCM authentication tag length (4, 8, 12-16 bytes) */ } esp_aes_gcm_operation_t; #endif /* ESP_AES_DRIVER_ENABLED */