Merge branch 'bugfix/eap_tls_psa_crypto_fail_v6.0' into 'release/v6.0'

fix(esp_wifi): EAP TLS RSA verify and CBC record decrypt with PSA crypto (v6.0)

See merge request espressif/esp-idf!46100
This commit is contained in:
Jiang Jiang Jian
2026-03-02 17:23:44 +08:00
2 changed files with 170 additions and 167 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,6 +13,9 @@
#include "utils/common.h"
#include "crypto.h"
#include "common/defs.h"
#include "tls/asn1.h"
#include "tls/rsa.h"
#include "tls/pkcs1.h"
#ifdef CONFIG_CRYPTO_MBEDTLS
// #include "mbedtls/entropy.h"
@@ -26,6 +29,8 @@
#include "psa/crypto.h"
#include <mbedtls/psa_util.h>
#define WPA_HEX_ERR(err) ((err) < 0 ? "-" : ""), (unsigned int) ((err) < 0 ? -(err) : (err))
/* Dummy structures; these are just typecast to struct crypto_rsa_key */
struct crypto_public_key;
struct crypto_private_key;
@@ -164,13 +169,13 @@ struct crypto_public_key *crypto_public_key_from_cert(const u8 *buf,
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
ret = mbedtls_pk_get_psa_attributes(&cert->pk, PSA_KEY_USAGE_VERIFY_HASH, &key_attributes);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", ret);
wpa_printf(MSG_ERROR, "%s:Failed to get key attributes, returned %s0x%X", __func__, WPA_HEX_ERR(ret));
goto fail;
}
ret = mbedtls_pk_import_into_psa(&cert->pk, &key_attributes, &key_id);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret);
wpa_printf(MSG_ERROR, "Failed to import key, returned %s0x%X", WPA_HEX_ERR(ret));
goto fail;
}
@@ -179,7 +184,7 @@ struct crypto_public_key *crypto_public_key_from_cert(const u8 *buf,
// Load the key from PSA into mbedTLS pk context
ret = mbedtls_pk_copy_from_psa(key_id, kctx);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to copy key from PSA, returned %d", ret);
wpa_printf(MSG_ERROR, "Failed to copy key from PSA, returned %s0x%X", WPA_HEX_ERR(ret));
goto fail;
}
@@ -210,7 +215,7 @@ int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
psa_status_t status = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_ENCRYPT, &key_attributes);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", (int) status);
wpa_printf(MSG_ERROR, "%s:Failed to get key attributes, returned %s0x%X", __func__, WPA_HEX_ERR(status));
ret = -1;
goto cleanup;
}
@@ -225,7 +230,7 @@ int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret);
wpa_printf(MSG_ERROR, "Failed to import key, returned %s0x%X", WPA_HEX_ERR(ret));
ret = -1;
goto cleanup;
}
@@ -233,7 +238,7 @@ int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
size_t output_len = 0;
status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, in, inlen, NULL, 0, out, *outlen, &output_len);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to encrypt data, returned %d", (int) status);
wpa_printf(MSG_ERROR, "Failed to encrypt data, returned %s0x%X", WPA_HEX_ERR((int) status));
ret = -1;
goto cleanup;
}
@@ -261,14 +266,14 @@ int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
psa_status_t status = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_DECRYPT, &key_attributes);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", (int) status);
wpa_printf(MSG_ERROR, "%s:Failed to get key attributes, returned %s0x%X", __func__, WPA_HEX_ERR(status));
ret = -1;
goto cleanup;
}
ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret);
wpa_printf(MSG_ERROR, "Failed to import key, returned %s0x%X", WPA_HEX_ERR(ret));
ret = -1;
goto cleanup;
}
@@ -276,7 +281,7 @@ int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
size_t output_len = 0;
status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, in, inlen, NULL, 0, out, *outlen, &output_len);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to decrypt data, returned %d", (int) status);
wpa_printf(MSG_ERROR, "Failed to decrypt data, returned %s0x%X", WPA_HEX_ERR((int) status));
ret = -1;
goto cleanup;
}
@@ -304,14 +309,14 @@ int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
psa_status_t status = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_SIGN_HASH, &key_attributes);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", (int) status);
wpa_printf(MSG_ERROR, "%s:Failed to get key attributes, returned %s0x%X", __func__, WPA_HEX_ERR(status));
ret = -1;
goto cleanup;
}
ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret);
wpa_printf(MSG_ERROR, "Failed to import key, returned %s0x%X", WPA_HEX_ERR(ret));
ret = -1;
goto cleanup;
}
@@ -319,7 +324,7 @@ int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
size_t output_len = 0;
status = psa_sign_hash(key_id, PSA_ALG_RSA_PKCS1V15_SIGN_RAW, in, inlen, out, *outlen, &output_len);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to sign data, returned %d", (int) status);
wpa_printf(MSG_ERROR, "Failed to sign data, returned %s0x%X", WPA_HEX_ERR((int) status));
ret = -1;
goto cleanup;
}
@@ -356,14 +361,14 @@ struct crypto_public_key *crypto_public_key_from_private_key(struct crypto_priva
// We use DECRYPT as a generic private key operation to get the key attributes
int ret = mbedtls_pk_get_psa_attributes(priv_ctx, PSA_KEY_USAGE_DECRYPT, &key_attributes);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", ret);
wpa_printf(MSG_ERROR, "%s:Failed to get key attributes, returned %s0x%X", __func__, WPA_HEX_ERR(ret));
os_free(pub_ctx);
return NULL;
}
ret = mbedtls_pk_import_into_psa(priv_ctx, &key_attributes, &key_id);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to import private key, returned %d", ret);
wpa_printf(MSG_ERROR, "Failed to import private key, returned %s0x%X", WPA_HEX_ERR(ret));
psa_reset_key_attributes(&key_attributes);
os_free(pub_ctx);
return NULL;
@@ -378,7 +383,7 @@ struct crypto_public_key *crypto_public_key_from_private_key(struct crypto_priva
psa_reset_key_attributes(&key_attributes);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to export public key, returned %d", (int) status);
wpa_printf(MSG_ERROR, "Failed to export public key, returned %s0x%X", WPA_HEX_ERR((int) status));
os_free(pub_ctx);
return NULL;
}
@@ -387,7 +392,7 @@ struct crypto_public_key *crypto_public_key_from_private_key(struct crypto_priva
mbedtls_pk_init(pub_ctx);
ret = mbedtls_pk_parse_public_key(pub_ctx, pub_key_buf, pub_key_len);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to parse public key, returned %d", ret);
wpa_printf(MSG_ERROR, "Failed to parse public key, returned %s0x%X", WPA_HEX_ERR(ret));
mbedtls_pk_free(pub_ctx);
os_free(pub_ctx);
return NULL;
@@ -422,101 +427,62 @@ int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
const u8 *crypt, size_t crypt_len,
u8 *plain, size_t *plain_len)
{
size_t len;
u8 *pos;
mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
struct crypto_rsa_key *rsa_key = NULL;
struct asn1_hdr hdr;
struct asn1_hdr bitstring;
const u8 *spki_pos, *spki_end;
int ret;
/* SubjectPublicKeyInfo DER for RSA-4096 is comfortably below this size. */
unsigned char pubkey_der[1024];
const u8 *pubkey = NULL;
size_t pubkey_len = 0;
// Load the key into PSA
psa_key_id_t key_id = 0;
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status;
int ret = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_DECRYPT, &key_attributes);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", ret);
psa_reset_key_attributes(&key_attributes);
if (!pkey || !crypt || !plain || !plain_len) {
return -1;
}
len = psa_get_key_bits(&key_attributes) / 8;
if (len != crypt_len) {
psa_reset_key_attributes(&key_attributes);
ret = mbedtls_pk_write_pubkey_der(pkey, pubkey_der, sizeof(pubkey_der));
if (ret <= 0) {
wpa_printf(MSG_ERROR, "%s: Failed to export public key in DER form, returned %s0x%X", __func__, WPA_HEX_ERR(ret));
return -1;
}
ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret);
psa_reset_key_attributes(&key_attributes);
return -1;
}
psa_reset_key_attributes(&key_attributes);
size_t output_len = 0;
status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, crypt, crypt_len, NULL, 0, plain, *plain_len, &output_len);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "Failed to decrypt data, returned %d", (int) status);
psa_destroy_key(key_id);
return -1;
}
*plain_len = output_len;
if (key_id) {
psa_destroy_key(key_id);
}
pubkey_len = (size_t) ret;
pubkey = pubkey_der + sizeof(pubkey_der) - pubkey_len;
/*
* PKCS #1 v1.5, 8.1:
*
* EB = 00 || BT || PS || 00 || D
* BT = 00 or 01
* PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
* k = length of modulus in octets
*
* Based on 10.1.3, "The block type shall be 01" for a signature.
* mbedtls_pk_write_pubkey_der() returns SubjectPublicKeyInfo.
* crypto_rsa_import_public_key() expects PKCS#1 RSAPublicKey,
* i.e. the BIT STRING payload inside SubjectPublicKeyInfo.
*/
if (asn1_get_next(pubkey, pubkey_len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
wpa_printf(MSG_ERROR, "%s: Failed to parse SubjectPublicKeyInfo sequence", __func__);
return -1;
}
spki_pos = hdr.payload;
spki_end = spki_pos + hdr.length;
if (len < 3 + 8 + 16 /* min hash len */ ||
plain[0] != 0x00 || plain[1] != 0x01) {
wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
"structure");
wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
if (asn1_get_next(spki_pos, spki_end - spki_pos, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
wpa_printf(MSG_ERROR, "%s: Failed to parse SubjectPublicKeyInfo algorithm", __func__);
return -1;
}
spki_pos = hdr.payload + hdr.length;
if (asn1_get_next(spki_pos, spki_end - spki_pos, &bitstring) < 0 || !asn1_is_bitstring(&bitstring) ||
bitstring.length < 1 || bitstring.payload[0] != 0) {
wpa_printf(MSG_ERROR, "%s: Failed to parse SubjectPublicKey BIT STRING", __func__);
return -1;
}
pos = plain + 3;
/* BT = 01 */
if (plain[2] != 0xff) {
wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
"PS (BT=01)");
wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
pubkey = bitstring.payload + 1;
pubkey_len = bitstring.length - 1;
rsa_key = crypto_rsa_import_public_key(pubkey, pubkey_len);
if (!rsa_key) {
wpa_printf(MSG_ERROR, "%s: Failed to import public key for PKCS#1 verification", __func__);
return -1;
}
while (pos < plain + len && *pos == 0xff) {
pos++;
}
if (pos - plain - 2 < 8) {
/* PKCS #1 v1.5, 8.1: At least eight octets long PS */
wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
"padding");
wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
return -1;
}
if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
"structure (2)");
wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
return -1;
}
pos++;
len -= pos - plain;
/* Strip PKCS #1 header */
os_memmove(plain, pos, len);
*plain_len = len;
return 0;
ret = pkcs1_decrypt_public_key(rsa_key, crypt, crypt_len, plain, plain_len);
crypto_rsa_free(rsa_key);
return ret;
}
#endif
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -36,6 +36,8 @@
#include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#define WPA_HEX_ERR(err) ((err) < 0 ? "-" : ""), (unsigned int) ((err) < 0 ? -(err) : (err))
#ifdef CONFIG_FAST_PBKDF2
#include "fastpbkdf2.h"
#include "fastpsk.h"
@@ -655,8 +657,9 @@ int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
#ifdef CONFIG_TLS_INTERNAL_CLIENT
struct crypto_cipher {
void *ctx_enc;
void *ctx_dec;
enum crypto_cipher_alg alg;
size_t iv_len;
u8 cbc[16];
psa_key_id_t key_id;
};
@@ -689,6 +692,19 @@ static uint32_t alg_to_psa_key_type(enum crypto_cipher_alg alg)
return 0;
}
static size_t alg_to_block_size(enum crypto_cipher_alg alg)
{
switch (alg) {
case CRYPTO_CIPHER_ALG_AES:
return 16;
case CRYPTO_CIPHER_ALG_3DES:
case CRYPTO_CIPHER_ALG_DES:
return 8;
default:
return 0;
}
}
struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg,
const u8 *iv, const u8 *key,
size_t key_len)
@@ -703,8 +719,12 @@ struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg,
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
psa_cipher_operation_t *enc_operation = NULL;
psa_cipher_operation_t *dec_operation = NULL;
size_t iv_len = alg_to_block_size(alg);
if (iv_len == 0 || iv == NULL || key == NULL) {
wpa_printf(MSG_ERROR, "%s: invalid args", __func__);
goto cleanup;
}
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
uint32_t psa_alg = alg_to_psa_cipher(alg);
@@ -729,47 +749,9 @@ struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg,
}
psa_reset_key_attributes(&attributes);
enc_operation = os_zalloc(sizeof(psa_cipher_operation_t));
if (!enc_operation) {
wpa_printf(MSG_ERROR, "%s: os_zalloc failed", __func__);
goto cleanup;
}
ctx->ctx_enc = (void *)enc_operation;
status = psa_cipher_encrypt_setup(enc_operation, key_id, psa_alg);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__);
goto cleanup;
}
status = psa_cipher_set_iv(enc_operation, iv, 16);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__);
goto cleanup;
}
dec_operation = os_zalloc(sizeof(psa_cipher_operation_t));
if (!dec_operation) {
wpa_printf(MSG_ERROR, "%s: os_zalloc failed", __func__);
goto cleanup;
}
ctx->ctx_dec = (void *)dec_operation;
status = psa_cipher_decrypt_setup(dec_operation, key_id, psa_alg);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_decrypt_setup failed", __func__);
goto cleanup;
}
status = psa_cipher_set_iv(dec_operation, iv, 16);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__);
goto cleanup;
}
ctx->alg = alg;
ctx->iv_len = iv_len;
os_memcpy(ctx->cbc, iv, iv_len);
ctx->key_id = key_id;
return ctx;
@@ -778,14 +760,6 @@ cleanup:
if (key_id) {
psa_destroy_key(key_id);
}
if (enc_operation) {
psa_cipher_abort(enc_operation);
os_free(enc_operation);
}
if (dec_operation) {
psa_cipher_abort(dec_operation);
os_free(dec_operation);
}
psa_reset_key_attributes(&attributes);
os_free(ctx);
return NULL;
@@ -795,22 +769,54 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
u8 *crypt, size_t len)
{
psa_status_t status;
psa_cipher_operation_t *operation = (psa_cipher_operation_t *)ctx->ctx_enc;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
uint32_t psa_alg;
size_t output_length = 0, finish_length = 0;
size_t output_length = 0;
if (!ctx || !plain || !crypt || ctx->iv_len == 0 || (len % ctx->iv_len)) {
return -1;
}
psa_alg = alg_to_psa_cipher(ctx->alg);
status = psa_cipher_update(operation, plain, len, crypt, len, &output_length);
status = psa_cipher_encrypt_setup(&operation, ctx->key_id, psa_alg);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__);
wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
return -1;
}
status = psa_cipher_finish(operation, crypt + output_length, len - output_length, &output_length);
status = psa_cipher_set_iv(&operation, ctx->cbc, ctx->iv_len);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__);
wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
psa_cipher_abort(&operation);
return -1;
}
status = psa_cipher_update(&operation, plain, len, crypt, len, &output_length);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
psa_cipher_abort(&operation);
return -1;
}
status = psa_cipher_finish(&operation, crypt + output_length, len - output_length, &finish_length);
psa_cipher_abort(&operation);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
return -1;
}
output_length += finish_length;
if (output_length != len) {
wpa_printf(MSG_ERROR, "%s: unexpected output length %u (expected %u)",
__func__, (unsigned) output_length, (unsigned) len);
return -1;
}
os_memcpy(ctx->cbc, crypt + len - ctx->iv_len, ctx->iv_len);
return 0;
}
@@ -818,36 +824,67 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
u8 *plain, size_t len)
{
psa_status_t status;
psa_cipher_operation_t *operation = (psa_cipher_operation_t *)ctx->ctx_dec;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
uint32_t psa_alg;
size_t output_length = 0, finish_length = 0;
u8 next_iv[16];
size_t output_length = 0;
if (!ctx || !plain || !crypt || ctx->iv_len == 0 || (len % ctx->iv_len)) {
return -1;
}
psa_alg = alg_to_psa_cipher(ctx->alg);
status = psa_cipher_update(operation, crypt, len, plain, len, &output_length);
os_memcpy(next_iv, crypt + len - ctx->iv_len, ctx->iv_len);
status = psa_cipher_decrypt_setup(&operation, ctx->key_id, psa_alg);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__);
wpa_printf(MSG_ERROR, "%s: psa_cipher_decrypt_setup failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
return -1;
}
status = psa_cipher_finish(operation, plain + output_length, len - output_length, &output_length);
status = psa_cipher_set_iv(&operation, ctx->cbc, ctx->iv_len);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__);
wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
psa_cipher_abort(&operation);
return -1;
}
status = psa_cipher_update(&operation, crypt, len, plain, len, &output_length);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
psa_cipher_abort(&operation);
return -1;
}
status = psa_cipher_finish(&operation, plain + output_length, len - output_length, &finish_length);
psa_cipher_abort(&operation);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed: %s0x%X",
__func__, WPA_HEX_ERR((int) status));
return -1;
}
output_length += finish_length;
if (output_length != len) {
wpa_printf(MSG_ERROR, "%s: unexpected output length %u (expected %u)",
__func__, (unsigned) output_length, (unsigned) len);
return -1;
}
os_memcpy(ctx->cbc, next_iv, ctx->iv_len);
return 0;
}
void crypto_cipher_deinit(struct crypto_cipher *ctx)
{
psa_status_t status;
psa_cipher_abort((psa_cipher_operation_t *)ctx->ctx_enc);
psa_cipher_abort((psa_cipher_operation_t *)ctx->ctx_dec);
status = psa_destroy_key(ctx->key_id);
if (status != PSA_SUCCESS) {
wpa_printf(MSG_ERROR, "%s: psa_destroy_key failed", __func__);
}
os_free(ctx->ctx_enc);
os_free(ctx->ctx_dec);
os_free(ctx);
}
#endif