mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user