mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-08-01 10:06:53 +03:00
Merge pull request #8521 from valeriosetti/issue8441
[G4] Make CTR-DRBG fall back on PSA when AES not built in
This commit is contained in:
@ -24,15 +24,60 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* Using error translation functions from PSA to MbedTLS */
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#include "psa_util_internal.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx,
|
||||
unsigned char *key, size_t key_len)
|
||||
{
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
|
||||
psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
|
||||
psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
|
||||
status = psa_import_key(&key_attr, key, key_len, &psa_ctx->key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_cipher_encrypt_setup(&psa_ctx->operation, psa_ctx->key_id, PSA_ALG_ECB_NO_PADDING);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx)
|
||||
{
|
||||
psa_cipher_abort(&psa_ctx->operation);
|
||||
psa_destroy_key(psa_ctx->key_id);
|
||||
|
||||
psa_ctx->operation = psa_cipher_operation_init();
|
||||
psa_ctx->key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CTR_DRBG context initialization
|
||||
*/
|
||||
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_init(&ctx->aes_ctx);
|
||||
#else
|
||||
ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
ctx->psa_ctx.operation = psa_cipher_operation_init();
|
||||
#endif
|
||||
/* Indicate that the entropy nonce length is not set explicitly.
|
||||
* See mbedtls_ctr_drbg_set_nonce_len(). */
|
||||
ctx->reseed_counter = -1;
|
||||
@ -56,7 +101,11 @@ void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
|
||||
mbedtls_mutex_free(&ctx->mutex);
|
||||
}
|
||||
#endif
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_free(&ctx->aes_ctx);
|
||||
#else
|
||||
ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
|
||||
#endif
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
|
||||
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
|
||||
ctx->reseed_counter = -1;
|
||||
@ -117,8 +166,17 @@ static int block_cipher_df(unsigned char *output,
|
||||
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
|
||||
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
|
||||
unsigned char *p, *iv;
|
||||
mbedtls_aes_context aes_ctx;
|
||||
int ret = 0;
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_context aes_ctx;
|
||||
#else
|
||||
psa_status_t status;
|
||||
size_t tmp_len;
|
||||
mbedtls_ctr_drbg_psa_context psa_ctx;
|
||||
|
||||
psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_ctx.operation = psa_cipher_operation_init();
|
||||
#endif
|
||||
|
||||
int i, j;
|
||||
size_t buf_len, use_len;
|
||||
@ -129,7 +187,6 @@ static int block_cipher_df(unsigned char *output,
|
||||
|
||||
memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
|
||||
MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
/*
|
||||
* Construct IV (16 bytes) and S in buffer
|
||||
@ -151,10 +208,20 @@ static int block_cipher_df(unsigned char *output,
|
||||
key[i] = i;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
|
||||
@ -170,10 +237,19 @@ static int block_cipher_df(unsigned char *output,
|
||||
use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
|
||||
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
chain, chain)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE,
|
||||
chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
|
||||
@ -187,23 +263,46 @@ static int block_cipher_df(unsigned char *output,
|
||||
/*
|
||||
* Do final encryption with reduced data
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
ctr_drbg_destroy_psa_contex(&psa_ctx);
|
||||
|
||||
status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
|
||||
p = output;
|
||||
|
||||
for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
iv, iv)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE,
|
||||
iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
|
||||
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
|
||||
}
|
||||
exit:
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_free(&aes_ctx);
|
||||
#else
|
||||
ctr_drbg_destroy_psa_contex(&psa_ctx);
|
||||
#endif
|
||||
/*
|
||||
* tidy up the stack
|
||||
*/
|
||||
@ -236,6 +335,10 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
|
||||
unsigned char *p = tmp;
|
||||
int i, j;
|
||||
int ret = 0;
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
psa_status_t status;
|
||||
size_t tmp_len;
|
||||
#endif
|
||||
|
||||
memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
|
||||
|
||||
@ -252,10 +355,19 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
|
||||
/*
|
||||
* Crypt counter block
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
ctx->counter, p)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
|
||||
p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
|
||||
}
|
||||
@ -267,10 +379,20 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
|
||||
/*
|
||||
* Update key and counter
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
|
||||
|
||||
status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
|
||||
MBEDTLS_CTR_DRBG_BLOCKSIZE);
|
||||
|
||||
@ -447,10 +569,20 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
|
||||
good_nonce_len(ctx->entropy_len));
|
||||
|
||||
/* Initialize with an empty key. */
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
psa_status_t status;
|
||||
|
||||
status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do the initial seeding. */
|
||||
if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
|
||||
@ -531,10 +663,22 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
|
||||
/*
|
||||
* Crypt counter block
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
ctx->counter, tmp)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
psa_status_t status;
|
||||
size_t tmp_len;
|
||||
|
||||
status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
|
||||
tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
|
||||
? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
|
||||
|
@ -7714,6 +7714,11 @@ psa_status_t psa_crypto_init(void)
|
||||
}
|
||||
global_data.drivers_initialized = 1;
|
||||
|
||||
status = psa_initialize_key_slots();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Initialize and seed the random generator. */
|
||||
mbedtls_psa_random_init(&global_data.rng);
|
||||
global_data.rng_state = RNG_INITIALIZED;
|
||||
@ -7723,11 +7728,6 @@ psa_status_t psa_crypto_init(void)
|
||||
}
|
||||
global_data.rng_state = RNG_SEEDED;
|
||||
|
||||
status = psa_initialize_key_slots();
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
status = psa_crypto_load_transaction();
|
||||
if (status == PSA_SUCCESS) {
|
||||
|
Reference in New Issue
Block a user