mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #12747 from jeromecoutant/PR_MBEDTLS
STM32 MBEDTLS support with HW cryptopull/12899/head
commit
3333f4185e
|
@ -1,530 +0,0 @@
|
||||||
/*
|
|
||||||
* Hardware aes implementation for STM32F4 STM32F7 and STM32L4 families
|
|
||||||
*******************************************************************************
|
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "mbedtls/aes.h"
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
|
||||||
|
|
||||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
|
||||||
#define TLSPRINT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint32_t swap(uint32_t in)
|
|
||||||
{
|
|
||||||
uint32_t in1, in2, in3, in4, out;
|
|
||||||
|
|
||||||
in1 = ((in & 0xff000000) >> 24);
|
|
||||||
in2 = ((in & 0x00FF0000) >> 8);
|
|
||||||
in3 = ((in & 0x0000FF00) << 8);
|
|
||||||
in4 = ((in & 0xFF) << 24);
|
|
||||||
out = in1 | in2 | in3 | in4;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int aes_set_key(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** aes_set_key *******\n");
|
|
||||||
mbedtls_printf("keybits = %d\n", keybits);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (keybits) {
|
|
||||||
case 128:
|
|
||||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_128B;
|
|
||||||
memcpy(ctx->aes_key, key, 16);
|
|
||||||
|
|
||||||
ctx->aes_key[0] = swap(ctx->aes_key[0]);
|
|
||||||
ctx->aes_key[1] = swap(ctx->aes_key[1]);
|
|
||||||
ctx->aes_key[2] = swap(ctx->aes_key[2]);
|
|
||||||
ctx->aes_key[3] = swap(ctx->aes_key[3]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 192:
|
|
||||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_192B;
|
|
||||||
memcpy(ctx->aes_key, key, 24);
|
|
||||||
|
|
||||||
ctx->aes_key[0] = swap(ctx->aes_key[0]);
|
|
||||||
ctx->aes_key[1] = swap(ctx->aes_key[1]);
|
|
||||||
ctx->aes_key[2] = swap(ctx->aes_key[2]);
|
|
||||||
ctx->aes_key[3] = swap(ctx->aes_key[3]);
|
|
||||||
ctx->aes_key[4] = swap(ctx->aes_key[4]);
|
|
||||||
ctx->aes_key[5] = swap(ctx->aes_key[5]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 256:
|
|
||||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_256B;
|
|
||||||
memcpy(ctx->aes_key, key, 32);
|
|
||||||
|
|
||||||
ctx->aes_key[0] = swap(ctx->aes_key[0]);
|
|
||||||
ctx->aes_key[1] = swap(ctx->aes_key[1]);
|
|
||||||
ctx->aes_key[2] = swap(ctx->aes_key[2]);
|
|
||||||
ctx->aes_key[3] = swap(ctx->aes_key[3]);
|
|
||||||
ctx->aes_key[4] = swap(ctx->aes_key[4]);
|
|
||||||
ctx->aes_key[5] = swap(ctx->aes_key[5]);
|
|
||||||
ctx->aes_key[6] = swap(ctx->aes_key[6]);
|
|
||||||
ctx->aes_key[7] = swap(ctx->aes_key[7]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
|
||||||
ctx->hcryp_aes.Instance = CRYP;
|
|
||||||
|
|
||||||
/* Deinitializes the CRYP peripheral */
|
|
||||||
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) == HAL_ERROR) {
|
|
||||||
return (HAL_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable CRYP clock */
|
|
||||||
__HAL_RCC_CRYP_CLK_ENABLE();
|
|
||||||
|
|
||||||
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
|
||||||
if (HAL_CRYP_Init(&ctx->hcryp_aes) == HAL_ERROR) {
|
|
||||||
return (HAL_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allow multi-instance of CRYP use: save context for CRYP HW module CR */
|
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implementation that should never be optimized out by the compiler */
|
|
||||||
static void mbedtls_zeroize(void *v, size_t n)
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_zeroize *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile unsigned char *p = (unsigned char *)v;
|
|
||||||
while (n--) {
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mbedtls_aes_init(mbedtls_aes_context *ctx)
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_init *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(mbedtls_aes_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mbedtls_aes_free(mbedtls_aes_context *ctx)
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_free *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if defined(DUAL_CORE)
|
|
||||||
uint32_t timeout = HSEM_TIMEOUT;
|
|
||||||
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID) && (--timeout != 0)) {
|
|
||||||
}
|
|
||||||
#endif /* DUAL_CORE */
|
|
||||||
/* Force the CRYP Periheral Clock Reset */
|
|
||||||
__HAL_RCC_CRYP_FORCE_RESET();
|
|
||||||
|
|
||||||
/* Release the CRYP Periheral Clock Reset */
|
|
||||||
__HAL_RCC_CRYP_RELEASE_RESET();
|
|
||||||
#if defined(DUAL_CORE)
|
|
||||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
|
|
||||||
#endif /* DUAL_CORE */
|
|
||||||
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_aes_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
|
||||||
unsigned int keybits)
|
|
||||||
{
|
|
||||||
int ret_val = 0;
|
|
||||||
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_setkey_enc *******\n");
|
|
||||||
mbedtls_printf("enc keybits : %d\n", keybits);
|
|
||||||
mbedtls_printf("enc key :\n");
|
|
||||||
for (int i = 1; i <= keybits / 8; i++) {
|
|
||||||
mbedtls_printf("%x\t", key[i - 1]);
|
|
||||||
if ((i % 8) == 0) {
|
|
||||||
mbedtls_printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret_val = aes_set_key(ctx, key, keybits);
|
|
||||||
return (ret_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
|
||||||
unsigned int keybits)
|
|
||||||
{
|
|
||||||
int ret_val = 0;
|
|
||||||
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_setkey_dec *******\n");
|
|
||||||
mbedtls_printf("dec keybits : %d\n", keybits);
|
|
||||||
mbedtls_printf("enc key:\n");
|
|
||||||
for (int i = 1; i <= keybits / 8; i++) {
|
|
||||||
mbedtls_printf("%x\t", key[i - 1]);
|
|
||||||
if ((i % 8) == 0) {
|
|
||||||
mbedtls_printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret_val = aes_set_key(ctx, key, keybits);
|
|
||||||
return (ret_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16])
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_crypt_ecb (%s)*******\n", mode == MBEDTLS_AES_DECRYPT ? "decrypt" : "encrypt");
|
|
||||||
mbedtls_printf("input:\n");
|
|
||||||
for (int i = 1; i <= 16; i++) {
|
|
||||||
mbedtls_printf("%x\t", input[i - 1]);
|
|
||||||
if ((i % 8) == 0) {
|
|
||||||
mbedtls_printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* allow multi-instance of CRYP use: restore context for CRYP hw module */
|
|
||||||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
|
||||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
|
||||||
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
|
||||||
|
|
||||||
/* Set the Algo if not configured till now */
|
|
||||||
if (CRYP_AES_ECB != (ctx->hcryp_aes.Instance->CR & CRYP_AES_ECB)) {
|
|
||||||
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_ECB;
|
|
||||||
|
|
||||||
/* Configure the CRYP */
|
|
||||||
HAL_CRYP_SetConfig(&ctx->hcryp_aes, &ctx->hcryp_aes.Init);
|
|
||||||
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** AES ECB algo configuration set : %ld *******\n", CRYP_AES_ECB);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) { /* AES decryption */
|
|
||||||
ret = mbedtls_internal_aes_decrypt(ctx, input, output);
|
|
||||||
if (ret) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
} else {
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf("dec output :\n");
|
|
||||||
for (int j = 1; j <= 16; j++) {
|
|
||||||
mbedtls_printf("%x\t", output[j - 1]);
|
|
||||||
if ((j % 8) == 0) {
|
|
||||||
mbedtls_printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else { /* AES encryption */
|
|
||||||
ret = mbedtls_internal_aes_encrypt(ctx, input, output);
|
|
||||||
if (ret) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
} else {
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf("enc output :\n");
|
|
||||||
for (int k = 1; k <= 16; k++) {
|
|
||||||
mbedtls_printf("%x\t", output[k - 1]);
|
|
||||||
if ((k % 8) == 0) {
|
|
||||||
mbedtls_printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* allow multi-instance of CRYP use: save context for CRYP HW module CR */
|
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
||||||
static int st_cbc_restore_context(mbedtls_aes_context *ctx)
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** st_cbc_restore_context *******\n");
|
|
||||||
#endif
|
|
||||||
/* allow multi-instance of CRYP use: restore context for CRYP hw module */
|
|
||||||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
|
||||||
/* Re-initialize AES processor with proper parameters
|
|
||||||
and (re-)apply key and IV for multi context usecases */
|
|
||||||
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
if (HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output)
|
|
||||||
{
|
|
||||||
uint32_t tickstart;
|
|
||||||
uint32_t *iv_ptr = (uint32_t *)&iv[0];
|
|
||||||
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_crypt_cbc *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (length % 16) {
|
|
||||||
return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
|
|
||||||
}
|
|
||||||
ctx->hcryp_aes.Init.pInitVect = (uint32_t *)&iv[0];
|
|
||||||
if (st_cbc_restore_context(ctx) != 0) {
|
|
||||||
return (ST_ERR_AES_BUSY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the Algo if not configured till now */
|
|
||||||
if (CRYP_AES_CBC != (ctx->hcryp_aes.Instance->CR & CRYP_AES_CBC)) {
|
|
||||||
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_CBC;
|
|
||||||
|
|
||||||
/* Configure the CRYP */
|
|
||||||
HAL_CRYP_SetConfig(&ctx->hcryp_aes, &ctx->hcryp_aes.Init);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
|
||||||
if (HAL_CRYP_Decrypt(&ctx->hcryp_aes, (uint32_t *)input, length / 4, (uint32_t *)output, 10) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
/* Save the internal IV vector for multi context purpose */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((ctx->hcryp_aes.Instance->SR & (CRYP_SR_IFEM | CRYP_SR_OFNE | CRYP_SR_BUSY)) != CRYP_SR_IFEM) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_AES_TIMEOUT) {
|
|
||||||
return ST_ERR_AES_BUSY; // timeout: CRYP processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR; // save here before overwritten
|
|
||||||
ctx->hcryp_aes.Instance->CR &= ~CRYP_CR_CRYPEN;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV0LR;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV0RR;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV1LR;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV1RR;
|
|
||||||
} else {
|
|
||||||
if (HAL_CRYP_Encrypt(&ctx->hcryp_aes, (uint32_t *)input, length / 4, (uint32_t *)output, 10) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
memcpy(iv, output, 16); /* current output is the IV vector for the next call */
|
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
|
||||||
int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
size_t *iv_off,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
size_t n = *iv_off;
|
|
||||||
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_crypt_cfb128 *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
|
||||||
while (length--) {
|
|
||||||
if (n == 0)
|
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv) != 0) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = *input++;
|
|
||||||
*output++ = (unsigned char)(c ^ iv[n]);
|
|
||||||
iv[n] = (unsigned char) c;
|
|
||||||
|
|
||||||
n = (n + 1) & 0x0F;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (length--) {
|
|
||||||
if (n == 0)
|
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv) != 0) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
iv[n] = *output++ = (unsigned char)(iv[n] ^ *input++);
|
|
||||||
|
|
||||||
n = (n + 1) & 0x0F;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*iv_off = n;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output)
|
|
||||||
{
|
|
||||||
unsigned char c;
|
|
||||||
unsigned char ov[17];
|
|
||||||
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_crypt_cfb8 *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (length--) {
|
|
||||||
memcpy(ov, iv, 16);
|
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv) != 0) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
|
||||||
ov[16] = *input;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = *output++ = (unsigned char)(iv[0] ^ *input++);
|
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_ENCRYPT) {
|
|
||||||
ov[16] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(iv, ov + 1, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
|
||||||
int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
|
||||||
size_t length,
|
|
||||||
size_t *nc_off,
|
|
||||||
unsigned char nonce_counter[16],
|
|
||||||
unsigned char stream_block[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output)
|
|
||||||
{
|
|
||||||
int c, i;
|
|
||||||
size_t n = *nc_off;
|
|
||||||
|
|
||||||
while (length--) {
|
|
||||||
if (n == 0) {
|
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block) != 0) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 16; i > 0; i--)
|
|
||||||
if (++nonce_counter[i - 1] != 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c = *input++;
|
|
||||||
*output++ = (unsigned char)(c ^ stream_block[n]);
|
|
||||||
|
|
||||||
n = (n + 1) & 0x0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
*nc_off = n;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
|
||||||
|
|
||||||
int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16])
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_internal_aes_encrypt *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (HAL_CRYP_Encrypt(&ctx->hcryp_aes, (uint32_t *)input, 4, (uint32_t *)output, 10) != HAL_OK) {
|
|
||||||
// error found
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16])
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_internal_aes_decrypt *******\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (HAL_CRYP_Decrypt(&ctx->hcryp_aes, (uint32_t *)input, 4, (uint32_t *)output, 10) != HAL_OK) {
|
|
||||||
// error found
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
|
||||||
void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16])
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_encrypt *******\n");
|
|
||||||
#endif
|
|
||||||
mbedtls_internal_aes_encrypt(ctx, input, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16])
|
|
||||||
{
|
|
||||||
#if TLSPRINT
|
|
||||||
mbedtls_printf(" ****** mbedtls_aes_decrypt *******\n");
|
|
||||||
#endif
|
|
||||||
mbedtls_internal_aes_decrypt(ctx, input, output);
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
|
||||||
#endif /*MBEDTLS_AES_ALT*/
|
|
|
@ -1,307 +0,0 @@
|
||||||
/*
|
|
||||||
* aes_alt.h AES block cipher
|
|
||||||
*******************************************************************************
|
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef MBEDTLS_AES_ALT_H
|
|
||||||
#define MBEDTLS_AES_ALT_H
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
|
||||||
#include "mbedtls/platform.h"
|
|
||||||
#include "mbedtls/config.h"
|
|
||||||
|
|
||||||
#include "cmsis.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ST_AES_TIMEOUT ((uint32_t) 0xFF) /* 255 ms timeout for the crypto processor */
|
|
||||||
#define ST_ERR_AES_BUSY (-0x0023) /* Crypto processor is busy, timeout occured */
|
|
||||||
/**
|
|
||||||
* \brief AES context structure
|
|
||||||
*
|
|
||||||
* \note buf is able to hold 32 extra bytes, which can be used:
|
|
||||||
* - for alignment purposes if VIA padlock is used, and/or
|
|
||||||
* - to simplify key expansion in the 256-bit case by
|
|
||||||
* generating an extra round key
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
uint32_t aes_key[8]; /* Decryption key */
|
|
||||||
CRYP_HandleTypeDef hcryp_aes;
|
|
||||||
uint32_t ctx_save_cr; /* save context for multi-instance */
|
|
||||||
}
|
|
||||||
mbedtls_aes_context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Initialize AES context
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be initialized
|
|
||||||
*/
|
|
||||||
void mbedtls_aes_init(mbedtls_aes_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clear AES context
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be cleared
|
|
||||||
*/
|
|
||||||
void mbedtls_aes_free(mbedtls_aes_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES key schedule (encryption)
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be initialized
|
|
||||||
* \param key encryption key
|
|
||||||
* \param keybits must be 128, 192 or 256
|
|
||||||
*
|
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
|
||||||
unsigned int keybits);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES key schedule (decryption)
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be initialized
|
|
||||||
* \param key decryption key
|
|
||||||
* \param keybits must be 128, 192 or 256
|
|
||||||
*
|
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
|
||||||
unsigned int keybits);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES-ECB block encryption/decryption
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param input 16-byte input block
|
|
||||||
* \param output 16-byte output block
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
||||||
/**
|
|
||||||
* \brief AES-CBC buffer encryption/decryption
|
|
||||||
* Length should be a multiple of the block
|
|
||||||
* size (16 bytes)
|
|
||||||
*
|
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
|
||||||
* call the function same function again on the following
|
|
||||||
* block(s) of data and get the same result as if it was
|
|
||||||
* encrypted in one call. This allows a "streaming" usage.
|
|
||||||
* If on the other hand you need to retain the contents of the
|
|
||||||
* IV, you should either save it manually or use the cipher
|
|
||||||
* module instead.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param length length of the input data
|
|
||||||
* \param iv initialization vector (updated after use)
|
|
||||||
* \param input buffer holding the input data
|
|
||||||
* \param output buffer holding the output data
|
|
||||||
*
|
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
|
||||||
/**
|
|
||||||
* \brief AES-CFB128 buffer encryption/decryption.
|
|
||||||
*
|
|
||||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
|
||||||
* both encryption and decryption. So a context initialized with
|
|
||||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
|
||||||
*
|
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
|
||||||
* call the function same function again on the following
|
|
||||||
* block(s) of data and get the same result as if it was
|
|
||||||
* encrypted in one call. This allows a "streaming" usage.
|
|
||||||
* If on the other hand you need to retain the contents of the
|
|
||||||
* IV, you should either save it manually or use the cipher
|
|
||||||
* module instead.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param length length of the input data
|
|
||||||
* \param iv_off offset in IV (updated after use)
|
|
||||||
* \param iv initialization vector (updated after use)
|
|
||||||
* \param input buffer holding the input data
|
|
||||||
* \param output buffer holding the output data
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
size_t *iv_off,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES-CFB8 buffer encryption/decryption.
|
|
||||||
*
|
|
||||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
|
||||||
* both encryption and decryption. So a context initialized with
|
|
||||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
|
||||||
*
|
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
|
||||||
* call the function same function again on the following
|
|
||||||
* block(s) of data and get the same result as if it was
|
|
||||||
* encrypted in one call. This allows a "streaming" usage.
|
|
||||||
* If on the other hand you need to retain the contents of the
|
|
||||||
* IV, you should either save it manually or use the cipher
|
|
||||||
* module instead.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param length length of the input data
|
|
||||||
* \param iv initialization vector (updated after use)
|
|
||||||
* \param input buffer holding the input data
|
|
||||||
* \param output buffer holding the output data
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
|
||||||
/**
|
|
||||||
* \brief AES-CTR buffer encryption/decryption
|
|
||||||
*
|
|
||||||
* Warning: You have to keep the maximum use of your counter in mind!
|
|
||||||
*
|
|
||||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
|
||||||
* both encryption and decryption. So a context initialized with
|
|
||||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param length The length of the data
|
|
||||||
* \param nc_off The offset in the current stream_block (for resuming
|
|
||||||
* within current cipher stream). The offset pointer to
|
|
||||||
* should be 0 at the start of a stream.
|
|
||||||
* \param nonce_counter The 128-bit nonce and counter.
|
|
||||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
|
||||||
* by the function.
|
|
||||||
* \param input The input data stream
|
|
||||||
* \param output The output data stream
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
|
||||||
size_t length,
|
|
||||||
size_t *nc_off,
|
|
||||||
unsigned char nonce_counter[16],
|
|
||||||
unsigned char stream_block[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Internal AES block encryption function
|
|
||||||
* (Only exposed to allow overriding it,
|
|
||||||
* see MBEDTLS_AES_ENCRYPT_ALT)
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Plaintext block
|
|
||||||
* \param output Output (ciphertext) block
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Internal AES block decryption function
|
|
||||||
* (Only exposed to allow overriding it,
|
|
||||||
* see MBEDTLS_AES_DECRYPT_ALT)
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Ciphertext block
|
|
||||||
* \param output Output (plaintext) block
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
|
||||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
|
||||||
#else
|
|
||||||
#define MBEDTLS_DEPRECATED
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* \brief Deprecated internal AES block encryption function
|
|
||||||
* without return value.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Plaintext block
|
|
||||||
* \param output Output (ciphertext) block
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Deprecated internal AES block decryption function
|
|
||||||
* without return value.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Ciphertext block
|
|
||||||
* \param output Output (plaintext) block
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_AES_ALT */
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_AES_ALT_H */
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* mbedtls_device.h
|
||||||
|
*******************************************************************************
|
||||||
|
* Copyright (c) 2017, STMicroelectronics
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_DEVICE_H
|
||||||
|
#define MBEDTLS_DEVICE_H
|
||||||
|
|
||||||
|
#define MBEDTLS_AES_ALT
|
||||||
|
#define MBEDTLS_MD5_ALT
|
||||||
|
#define MBEDTLS_SHA1_ALT
|
||||||
|
#define MBEDTLS_SHA256_ALT
|
||||||
|
// #define MBEDTLS_CCM_ALT // not fully supported yet
|
||||||
|
// #define MBEDTLS_GCM_ALT // not fully supported yet
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_DEVICE_H */
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* mbedtls_device.h
|
||||||
|
*******************************************************************************
|
||||||
|
* Copyright (c) 2017, STMicroelectronics
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_DEVICE_H
|
||||||
|
#define MBEDTLS_DEVICE_H
|
||||||
|
|
||||||
|
#define MBEDTLS_AES_ALT
|
||||||
|
#define MBEDTLS_MD5_ALT
|
||||||
|
#define MBEDTLS_SHA1_ALT
|
||||||
|
#define MBEDTLS_SHA256_ALT
|
||||||
|
// #define MBEDTLS_CCM_ALT // not fully supported yet
|
||||||
|
// #define MBEDTLS_GCM_ALT // not fully supported yet
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_DEVICE_H */
|
|
@ -1,502 +0,0 @@
|
||||||
/**
|
|
||||||
* \file aes_alt.h
|
|
||||||
*
|
|
||||||
* \brief This file contains AES definitions and functions.
|
|
||||||
*
|
|
||||||
* The Advanced Encryption Standard (AES) specifies a FIPS-approved
|
|
||||||
* cryptographic algorithm that can be used to protect electronic
|
|
||||||
* data.
|
|
||||||
*
|
|
||||||
* The AES algorithm is a symmetric block cipher that can
|
|
||||||
* encrypt and decrypt information. For more information, see
|
|
||||||
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and
|
|
||||||
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
|
|
||||||
* techniques -- Encryption algorithms -- Part 2: Asymmetric
|
|
||||||
* ciphers</em>.
|
|
||||||
*
|
|
||||||
* The AES-XTS block mode is standardized by NIST SP 800-38E
|
|
||||||
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
|
|
||||||
* and described in detail by IEEE P1619
|
|
||||||
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Copyright (C) 2006-2019, ARM Limited, All Rights Reserved.
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006-2019 STMicroelectronics, All Rights Reserved
|
|
||||||
*
|
|
||||||
* This file implements ST AES HW services based on API from mbed TLS
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MBEDTLS_AES_ALT_H
|
|
||||||
#define MBEDTLS_AES_ALT_H
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
|
||||||
#include "mbedtls/platform.h"
|
|
||||||
|
|
||||||
#include "cmsis.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ST_AES_TIMEOUT ((uint32_t) 0xFF) /* 255 ms timeout for the crypto processor */
|
|
||||||
#define ST_ERR_AES_BUSY (-0x0023) /* Crypto processor is busy, timeout occured */
|
|
||||||
/**
|
|
||||||
* \brief AES context structure
|
|
||||||
*
|
|
||||||
* \note buf is able to hold 32 extra bytes, which can be used:
|
|
||||||
* - for alignment purposes if VIA padlock is used, and/or
|
|
||||||
* - to simplify key expansion in the 256-bit case by
|
|
||||||
* generating an extra round key
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
uint32_t aes_key[8]; /* Decryption key */
|
|
||||||
CRYP_HandleTypeDef hcryp_aes;
|
|
||||||
uint32_t ctx_save_cr; /* save context for multi-instance */
|
|
||||||
}
|
|
||||||
mbedtls_aes_context;
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
|
||||||
/**
|
|
||||||
* \brief The AES XTS context-type definition.
|
|
||||||
*/
|
|
||||||
typedef struct mbedtls_aes_xts_context {
|
|
||||||
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
|
|
||||||
encryption or decryption. */
|
|
||||||
mbedtls_aes_context tweak; /*!< The AES context used for tweak
|
|
||||||
computation. */
|
|
||||||
} mbedtls_aes_xts_context;
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Initialize AES context
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be initialized
|
|
||||||
*/
|
|
||||||
void mbedtls_aes_init(mbedtls_aes_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clear AES context
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be cleared
|
|
||||||
*/
|
|
||||||
void mbedtls_aes_free(mbedtls_aes_context *ctx);
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
|
||||||
/**
|
|
||||||
* \brief This function initializes the specified AES XTS context.
|
|
||||||
*
|
|
||||||
* It must be the first API called before using
|
|
||||||
* the context.
|
|
||||||
*
|
|
||||||
* \param ctx The AES XTS context to initialize. This must not be \c NULL.
|
|
||||||
*/
|
|
||||||
void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief This function releases and clears the specified AES XTS context.
|
|
||||||
*
|
|
||||||
* \param ctx The AES XTS context to clear.
|
|
||||||
* If this is \c NULL, this function does nothing.
|
|
||||||
* Otherwise, the context must have been at least initialized.
|
|
||||||
*/
|
|
||||||
void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx);
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES key schedule (encryption)
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be initialized
|
|
||||||
* \param key encryption key
|
|
||||||
* \param keybits must be 128, 192 or 256
|
|
||||||
*
|
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
|
||||||
unsigned int keybits);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES key schedule (decryption)
|
|
||||||
*
|
|
||||||
* \param ctx AES context to be initialized
|
|
||||||
* \param key decryption key
|
|
||||||
* \param keybits must be 128, 192 or 256
|
|
||||||
*
|
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
|
||||||
unsigned int keybits);
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
|
||||||
/**
|
|
||||||
* \brief This function prepares an XTS context for encryption and
|
|
||||||
* sets the encryption key.
|
|
||||||
*
|
|
||||||
* \param ctx The AES XTS context to which the key should be bound.
|
|
||||||
* It must be initialized.
|
|
||||||
* \param key The encryption key. This is comprised of the XTS key1
|
|
||||||
* concatenated with the XTS key2.
|
|
||||||
* This must be a readable buffer of size \p keybits bits.
|
|
||||||
* \param keybits The size of \p key passed in bits. Valid options are:
|
|
||||||
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
|
|
||||||
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
|
||||||
*
|
|
||||||
* \return \c 0 on success.
|
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
|
|
||||||
const unsigned char *key,
|
|
||||||
unsigned int keybits);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief This function prepares an XTS context for decryption and
|
|
||||||
* sets the decryption key.
|
|
||||||
*
|
|
||||||
* \param ctx The AES XTS context to which the key should be bound.
|
|
||||||
* It must be initialized.
|
|
||||||
* \param key The decryption key. This is comprised of the XTS key1
|
|
||||||
* concatenated with the XTS key2.
|
|
||||||
* This must be a readable buffer of size \p keybits bits.
|
|
||||||
* \param keybits The size of \p key passed in bits. Valid options are:
|
|
||||||
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
|
|
||||||
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
|
||||||
*
|
|
||||||
* \return \c 0 on success.
|
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
|
|
||||||
const unsigned char *key,
|
|
||||||
unsigned int keybits);
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES-ECB block encryption/decryption
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param input 16-byte input block
|
|
||||||
* \param output 16-byte output block
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
|
||||||
/**
|
|
||||||
* \brief AES-CBC buffer encryption/decryption
|
|
||||||
* Length should be a multiple of the block
|
|
||||||
* size (16 bytes)
|
|
||||||
*
|
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
|
||||||
* call the function same function again on the following
|
|
||||||
* block(s) of data and get the same result as if it was
|
|
||||||
* encrypted in one call. This allows a "streaming" usage.
|
|
||||||
* If on the other hand you need to retain the contents of the
|
|
||||||
* IV, you should either save it manually or use the cipher
|
|
||||||
* module instead.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param length length of the input data
|
|
||||||
* \param iv initialization vector (updated after use)
|
|
||||||
* \param input buffer holding the input data
|
|
||||||
* \param output buffer holding the output data
|
|
||||||
*
|
|
||||||
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
|
||||||
/**
|
|
||||||
* \brief This function performs an AES-XTS encryption or decryption
|
|
||||||
* operation for an entire XTS data unit.
|
|
||||||
*
|
|
||||||
* AES-XTS encrypts or decrypts blocks based on their location as
|
|
||||||
* defined by a data unit number. The data unit number must be
|
|
||||||
* provided by \p data_unit.
|
|
||||||
*
|
|
||||||
* NIST SP 800-38E limits the maximum size of a data unit to 2^20
|
|
||||||
* AES blocks. If the data unit is larger than this, this function
|
|
||||||
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
|
|
||||||
*
|
|
||||||
* \param ctx The AES XTS context to use for AES XTS operations.
|
|
||||||
* It must be initialized and bound to a key.
|
|
||||||
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
|
||||||
* #MBEDTLS_AES_DECRYPT.
|
|
||||||
* \param length The length of a data unit in Bytes. This can be any
|
|
||||||
* length between 16 bytes and 2^24 bytes inclusive
|
|
||||||
* (between 1 and 2^20 block cipher blocks).
|
|
||||||
* \param data_unit The address of the data unit encoded as an array of 16
|
|
||||||
* bytes in little-endian format. For disk encryption, this
|
|
||||||
* is typically the index of the block device sector that
|
|
||||||
* contains the data.
|
|
||||||
* \param input The buffer holding the input data (which is an entire
|
|
||||||
* data unit). This function reads \p length Bytes from \p
|
|
||||||
* input.
|
|
||||||
* \param output The buffer holding the output data (which is an entire
|
|
||||||
* data unit). This function writes \p length Bytes to \p
|
|
||||||
* output.
|
|
||||||
*
|
|
||||||
* \return \c 0 on success.
|
|
||||||
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
|
|
||||||
* smaller than an AES block in size (16 Bytes) or if \p
|
|
||||||
* length is larger than 2^20 blocks (16 MiB).
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
const unsigned char data_unit[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
|
||||||
/**
|
|
||||||
* \brief AES-CFB128 buffer encryption/decryption.
|
|
||||||
*
|
|
||||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
|
||||||
* both encryption and decryption. So a context initialized with
|
|
||||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
|
||||||
*
|
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
|
||||||
* call the function same function again on the following
|
|
||||||
* block(s) of data and get the same result as if it was
|
|
||||||
* encrypted in one call. This allows a "streaming" usage.
|
|
||||||
* If on the other hand you need to retain the contents of the
|
|
||||||
* IV, you should either save it manually or use the cipher
|
|
||||||
* module instead.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param length length of the input data
|
|
||||||
* \param iv_off offset in IV (updated after use)
|
|
||||||
* \param iv initialization vector (updated after use)
|
|
||||||
* \param input buffer holding the input data
|
|
||||||
* \param output buffer holding the output data
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
size_t *iv_off,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief AES-CFB8 buffer encryption/decryption.
|
|
||||||
*
|
|
||||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
|
||||||
* both encryption and decryption. So a context initialized with
|
|
||||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
|
||||||
*
|
|
||||||
* \note Upon exit, the content of the IV is updated so that you can
|
|
||||||
* call the function same function again on the following
|
|
||||||
* block(s) of data and get the same result as if it was
|
|
||||||
* encrypted in one call. This allows a "streaming" usage.
|
|
||||||
* If on the other hand you need to retain the contents of the
|
|
||||||
* IV, you should either save it manually or use the cipher
|
|
||||||
* module instead.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
|
|
||||||
* \param length length of the input data
|
|
||||||
* \param iv initialization vector (updated after use)
|
|
||||||
* \param input buffer holding the input data
|
|
||||||
* \param output buffer holding the output data
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
|
||||||
int mode,
|
|
||||||
size_t length,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
|
||||||
/**
|
|
||||||
* \brief This function performs an AES-OFB (Output Feedback Mode)
|
|
||||||
* encryption or decryption operation.
|
|
||||||
*
|
|
||||||
* For OFB, you must set up the context with
|
|
||||||
* mbedtls_aes_setkey_enc(), regardless of whether you are
|
|
||||||
* performing an encryption or decryption operation. This is
|
|
||||||
* because OFB mode uses the same key schedule for encryption and
|
|
||||||
* decryption.
|
|
||||||
*
|
|
||||||
* The OFB operation is identical for encryption or decryption,
|
|
||||||
* therefore no operation mode needs to be specified.
|
|
||||||
*
|
|
||||||
* \note Upon exit, the content of iv, the Initialisation Vector, is
|
|
||||||
* updated so that you can call the same function again on the next
|
|
||||||
* block(s) of data and get the same result as if it was encrypted
|
|
||||||
* in one call. This allows a "streaming" usage, by initialising
|
|
||||||
* iv_off to 0 before the first call, and preserving its value
|
|
||||||
* between calls.
|
|
||||||
*
|
|
||||||
* For non-streaming use, the iv should be initialised on each call
|
|
||||||
* to a unique value, and iv_off set to 0 on each call.
|
|
||||||
*
|
|
||||||
* If you need to retain the contents of the initialisation vector,
|
|
||||||
* you must either save it manually or use the cipher module
|
|
||||||
* instead.
|
|
||||||
*
|
|
||||||
* \warning For the OFB mode, the initialisation vector must be unique
|
|
||||||
* every encryption operation. Reuse of an initialisation vector
|
|
||||||
* will compromise security.
|
|
||||||
*
|
|
||||||
* \param ctx The AES context to use for encryption or decryption.
|
|
||||||
* It must be initialized and bound to a key.
|
|
||||||
* \param length The length of the input data.
|
|
||||||
* \param iv_off The offset in IV (updated after use).
|
|
||||||
* It must point to a valid \c size_t.
|
|
||||||
* \param iv The initialization vector (updated after use).
|
|
||||||
* It must be a readable and writeable buffer of \c 16 Bytes.
|
|
||||||
* \param input The buffer holding the input data.
|
|
||||||
* It must be readable and of size \p length Bytes.
|
|
||||||
* \param output The buffer holding the output data.
|
|
||||||
* It must be writeable and of size \p length Bytes.
|
|
||||||
*
|
|
||||||
* \return \c 0 on success.
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
|
|
||||||
size_t length,
|
|
||||||
size_t *iv_off,
|
|
||||||
unsigned char iv[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_OFB */
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
|
||||||
/**
|
|
||||||
* \brief AES-CTR buffer encryption/decryption
|
|
||||||
*
|
|
||||||
* Warning: You have to keep the maximum use of your counter in mind!
|
|
||||||
*
|
|
||||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
|
||||||
* both encryption and decryption. So a context initialized with
|
|
||||||
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param length The length of the data
|
|
||||||
* \param nc_off The offset in the current stream_block (for resuming
|
|
||||||
* within current cipher stream). The offset pointer to
|
|
||||||
* should be 0 at the start of a stream.
|
|
||||||
* \param nonce_counter The 128-bit nonce and counter.
|
|
||||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
|
||||||
* by the function.
|
|
||||||
* \param input The input data stream
|
|
||||||
* \param output The output data stream
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
|
||||||
size_t length,
|
|
||||||
size_t *nc_off,
|
|
||||||
unsigned char nonce_counter[16],
|
|
||||||
unsigned char stream_block[16],
|
|
||||||
const unsigned char *input,
|
|
||||||
unsigned char *output);
|
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Internal AES block encryption function
|
|
||||||
* (Only exposed to allow overriding it,
|
|
||||||
* see MBEDTLS_AES_ENCRYPT_ALT)
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Plaintext block
|
|
||||||
* \param output Output (ciphertext) block
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Internal AES block decryption function
|
|
||||||
* (Only exposed to allow overriding it,
|
|
||||||
* see MBEDTLS_AES_DECRYPT_ALT)
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Ciphertext block
|
|
||||||
* \param output Output (plaintext) block
|
|
||||||
*
|
|
||||||
* \return 0 if successful
|
|
||||||
*/
|
|
||||||
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
|
||||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
|
||||||
#else
|
|
||||||
#define MBEDTLS_DEPRECATED
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* \brief Deprecated internal AES block encryption function
|
|
||||||
* without return value.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Plaintext block
|
|
||||||
* \param output Output (ciphertext) block
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Deprecated internal AES block decryption function
|
|
||||||
* without return value.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0
|
|
||||||
*
|
|
||||||
* \param ctx AES context
|
|
||||||
* \param input Ciphertext block
|
|
||||||
* \param output Output (plaintext) block
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
|
||||||
const unsigned char input[16],
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_AES_ALT */
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_AES_ALT_H */
|
|
||||||
|
|
|
@ -21,9 +21,10 @@
|
||||||
#define MBEDTLS_DEVICE_H
|
#define MBEDTLS_DEVICE_H
|
||||||
|
|
||||||
#define MBEDTLS_AES_ALT
|
#define MBEDTLS_AES_ALT
|
||||||
|
|
||||||
#define MBEDTLS_SHA1_ALT
|
|
||||||
|
|
||||||
#define MBEDTLS_MD5_ALT
|
#define MBEDTLS_MD5_ALT
|
||||||
|
#define MBEDTLS_SHA1_ALT
|
||||||
|
#define MBEDTLS_SHA256_ALT
|
||||||
|
// #define MBEDTLS_CCM_ALT // not fully supported yet
|
||||||
|
// #define MBEDTLS_GCM_ALT // not fully supported yet
|
||||||
|
|
||||||
#endif /* MBEDTLS_DEVICE_H */
|
#endif /* MBEDTLS_DEVICE_H */
|
|
@ -20,4 +20,6 @@
|
||||||
#ifndef MBEDTLS_DEVICE_H
|
#ifndef MBEDTLS_DEVICE_H
|
||||||
#define MBEDTLS_DEVICE_H
|
#define MBEDTLS_DEVICE_H
|
||||||
|
|
||||||
|
#define MBEDTLS_AES_ALT
|
||||||
|
|
||||||
#endif /* MBEDTLS_DEVICE_H */
|
#endif /* MBEDTLS_DEVICE_H */
|
|
@ -21,8 +21,10 @@
|
||||||
#define MBEDTLS_DEVICE_H
|
#define MBEDTLS_DEVICE_H
|
||||||
|
|
||||||
#define MBEDTLS_AES_ALT
|
#define MBEDTLS_AES_ALT
|
||||||
#define MBEDTLS_SHA1_ALT
|
|
||||||
|
|
||||||
#define MBEDTLS_MD5_ALT
|
#define MBEDTLS_MD5_ALT
|
||||||
|
#define MBEDTLS_SHA1_ALT
|
||||||
|
#define MBEDTLS_SHA256_ALT
|
||||||
|
// #define MBEDTLS_CCM_ALT // not fully supported yet
|
||||||
|
// #define MBEDTLS_GCM_ALT // not fully supported yet
|
||||||
|
|
||||||
#endif /* MBEDTLS_DEVICE_H */
|
#endif /* MBEDTLS_DEVICE_H */
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* mbedtls_device.h
|
||||||
|
*******************************************************************************
|
||||||
|
* Copyright (c) 2017, STMicroelectronics
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef MBEDTLS_DEVICE_H
|
||||||
|
#define MBEDTLS_DEVICE_H
|
||||||
|
|
||||||
|
#define MBEDTLS_AES_ALT
|
||||||
|
// #define MBEDTLS_MD5_ALT // HASH IP not available for STM32WB
|
||||||
|
// #define MBEDTLS_SHA1_ALT // HASH IP not available for STM32WB
|
||||||
|
// #define MBEDTLS_SHA256_ALT // HASH IP not available for STM32WB
|
||||||
|
// #define MBEDTLS_CCM_ALT // not fully supported yet
|
||||||
|
// #define MBEDTLS_GCM_ALT // not fully supported yet
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_DEVICE_H */
|
|
@ -1,40 +1,50 @@
|
||||||
/*
|
/*
|
||||||
* FIPS-197 compliant AES implementation
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
*
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
* Copyright (C) 2006-2019, ARM Limited, All Rights Reserved
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
*
|
||||||
*
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
* not use this file except in compliance with the License.
|
||||||
* not use this file except in compliance with the License.
|
* You may obtain a copy of the License at
|
||||||
* You may obtain a copy of the License at
|
*
|
||||||
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
||||||
*
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
||||||
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
||||||
* limitations under the License.
|
*
|
||||||
*
|
* This file implements ST AES HW services based on API from mbed TLS
|
||||||
* Copyright (C) 2006-2019 STMicroelectronics, All Rights Reserved
|
*
|
||||||
*
|
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
|
||||||
* This file implements ST AES HW services based on API from mbed TLS
|
*
|
||||||
*
|
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
|
||||||
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
|
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
||||||
*
|
*/
|
||||||
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
|
|
||||||
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if !(TARGET_STM32L4)
|
||||||
|
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_C)
|
#if defined(MBEDTLS_AES_C)
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
#if defined(MBEDTLS_AES_ALT)
|
||||||
#include "mbedtls/platform_util.h"
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
|
#include "platform/PlatformMutex.h"
|
||||||
|
#include "platform/SingletonPtr.h"
|
||||||
|
|
||||||
|
static SingletonPtr<PlatformMutex> aes_mutex;
|
||||||
|
|
||||||
|
#define MBEDTLS_DEBUG 0
|
||||||
|
|
||||||
/* Parameter validation macros based on platform_util.h */
|
/* Parameter validation macros based on platform_util.h */
|
||||||
#define AES_VALIDATE_RET( cond ) \
|
#define AES_VALIDATE_RET( cond ) \
|
||||||
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
|
||||||
|
@ -43,25 +53,7 @@
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
#define TIMEOUT_VALUE 0xFF
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
/* Private macro -------------------------------------------------------------*/
|
||||||
#define SWAP_B32_TO_B8(b32,b8,i) \
|
|
||||||
{ \
|
|
||||||
(b8)[(i) + 3] = (unsigned char) ( ( (b32) ) & 0xFF ); \
|
|
||||||
(b8)[(i) + 2] = (unsigned char) ( ( (b32) >> 8 ) & 0xFF ); \
|
|
||||||
(b8)[(i) + 1] = (unsigned char) ( ( (b32) >> 16 ) & 0xFF ); \
|
|
||||||
(b8)[(i) ] = (unsigned char) ( ( (b32) >> 24 ) & 0xFF ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SWAP_B8_TO_B32(b32,b8,i) \
|
|
||||||
{ \
|
|
||||||
(b32) = ( (uint32_t) (b8)[(i) + 3] ) \
|
|
||||||
| ( (uint32_t) (b8)[(i) + 2] << 8 ) \
|
|
||||||
| ( (uint32_t) (b8)[(i) + 1] << 16 ) \
|
|
||||||
| ( (uint32_t) (b8)[(i) ] << 24 ); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
@ -69,99 +61,125 @@ static int aes_set_key(mbedtls_aes_context *ctx,
|
||||||
const unsigned char *key,
|
const unsigned char *key,
|
||||||
unsigned int keybits)
|
unsigned int keybits)
|
||||||
{
|
{
|
||||||
/* Deinitializes the CRYP peripheral */
|
unsigned int i;
|
||||||
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) == HAL_ERROR) {
|
int ret = 0;
|
||||||
return (HAL_ERROR);
|
|
||||||
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] aes_set_key\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AES_VALIDATE_RET(ctx != NULL);
|
||||||
|
AES_VALIDATE_RET(key != NULL);
|
||||||
|
|
||||||
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
}
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* include the appropriate instance name */
|
||||||
|
#if defined (AES)
|
||||||
|
ctx->hcryp_aes.Instance = AES;
|
||||||
|
#elif defined (AES1)
|
||||||
|
ctx->hcryp_aes.Instance = AES1;
|
||||||
|
#else /* CRYP */
|
||||||
|
ctx->hcryp_aes.Instance = CRYP;
|
||||||
|
#endif /* AES */
|
||||||
|
|
||||||
switch (keybits) {
|
switch (keybits) {
|
||||||
case 128:
|
case 128:
|
||||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_128B;;
|
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_128B;
|
||||||
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[0], key, 0);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[1], key, 4);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[2], key, 8);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[3], key, 12);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 192:
|
case 192:
|
||||||
|
#if ( USE_AES_KEY192 == 1 )
|
||||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_192B;
|
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_192B;
|
||||||
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[0], key, 0);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[1], key, 4);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[2], key, 8);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[3], key, 12);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[4], key, 16);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[5], key, 20);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
#else
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||||
|
goto exit;
|
||||||
|
#endif /* USE_AES_KEY192 */
|
||||||
|
|
||||||
case 256:
|
case 256:
|
||||||
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_256B;
|
ctx->hcryp_aes.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||||
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[0], key, 0);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[1], key, 4);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[2], key, 8);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[3], key, 12);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[4], key, 16);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[5], key, 20);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[6], key, 24);
|
|
||||||
SWAP_B8_TO_B32(ctx->aes_key[7], key, 28);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
return (MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
|
ret = MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format and fill AES key */
|
||||||
|
for (i = 0; i < (keybits / 32); i++) {
|
||||||
|
GET_UINT32_BE(ctx->aes_key[i], key, 4 * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
||||||
ctx->hcryp_aes.Instance = CRYP;
|
ctx->hcryp_aes.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||||
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
||||||
|
|
||||||
/* Enable CRYP clock */
|
if (HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK) {
|
||||||
__HAL_RCC_CRYP_CLK_ENABLE();
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
if (HAL_CRYP_Init(&ctx->hcryp_aes) == HAL_ERROR) {
|
|
||||||
return (HAL_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allow multi-instance of CRYP use: save context for CRYP HW module CR */
|
/* allow multi-context of CRYP : save context */
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
||||||
return (0);
|
|
||||||
|
|
||||||
}
|
exit :
|
||||||
|
/* Free context access */
|
||||||
/* Implementation that should never be optimized out by the compiler */
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
static void mbedtls_zeroize(void *v, size_t n)
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
{
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
volatile unsigned char *p = (unsigned char *)v;
|
|
||||||
while (n--) {
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_aes_init(mbedtls_aes_context *ctx)
|
void mbedtls_aes_init(mbedtls_aes_context *ctx)
|
||||||
{
|
{
|
||||||
AES_VALIDATE(ctx != NULL);
|
AES_VALIDATE(ctx != NULL);
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(mbedtls_aes_context));
|
aes_mutex->lock();
|
||||||
|
cryp_context_count++;
|
||||||
|
aes_mutex->unlock();
|
||||||
|
|
||||||
|
cryp_zeroize((void *)ctx, sizeof(mbedtls_aes_context));
|
||||||
|
|
||||||
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] mbedtls_aes_init %u\n", cryp_context_count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mbedtls_aes_free(mbedtls_aes_context *ctx)
|
void mbedtls_aes_free(mbedtls_aes_context *ctx)
|
||||||
{
|
{
|
||||||
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] mbedtls_aes_free %u\n", cryp_context_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Force the CRYP Periheral Clock Reset */
|
|
||||||
__HAL_RCC_CRYP_FORCE_RESET();
|
|
||||||
|
|
||||||
/* Release the CRYP Periheral Clock Reset */
|
aes_mutex->lock();
|
||||||
__HAL_RCC_CRYP_RELEASE_RESET();
|
if (cryp_context_count > 0) {
|
||||||
|
cryp_context_count--;
|
||||||
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_aes_context));
|
/* Shut down CRYP on last context */
|
||||||
|
if (cryp_context_count == 0) {
|
||||||
|
HAL_CRYP_DeInit(&ctx->hcryp_aes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aes_mutex->unlock();
|
||||||
|
|
||||||
|
cryp_zeroize((void *)ctx, sizeof(mbedtls_aes_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XTS SW implementation inherited code from aes.c */
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
|
void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
|
||||||
{
|
{
|
||||||
|
@ -188,13 +206,14 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
|
||||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||||
unsigned int keybits)
|
unsigned int keybits)
|
||||||
{
|
{
|
||||||
int ret_val = 0;
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] mbedtls_aes_setkey_enc\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
AES_VALIDATE_RET(ctx != NULL);
|
AES_VALIDATE_RET(ctx != NULL);
|
||||||
AES_VALIDATE_RET(key != NULL);
|
AES_VALIDATE_RET(key != NULL);
|
||||||
|
|
||||||
ret_val = aes_set_key(ctx, key, keybits);
|
return (aes_set_key(ctx, key, keybits));
|
||||||
return (ret_val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -203,13 +222,14 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||||
unsigned int keybits)
|
unsigned int keybits)
|
||||||
{
|
{
|
||||||
int ret_val = 0;
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] mbedtls_aes_setkey_dec\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
AES_VALIDATE_RET(ctx != NULL);
|
AES_VALIDATE_RET(ctx != NULL);
|
||||||
AES_VALIDATE_RET(key != NULL);
|
AES_VALIDATE_RET(key != NULL);
|
||||||
|
|
||||||
ret_val = aes_set_key(ctx, key, keybits);
|
return (aes_set_key(ctx, key, keybits));
|
||||||
return (ret_val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
|
@ -237,7 +257,7 @@ static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
|
||||||
*key1 = &key[0];
|
*key1 = &key[0];
|
||||||
*key2 = &key[half_keybytes];
|
*key2 = &key[half_keybytes];
|
||||||
|
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
|
int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
|
||||||
|
@ -303,7 +323,7 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16])
|
unsigned char output[16])
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
AES_VALIDATE_RET(ctx != NULL);
|
AES_VALIDATE_RET(ctx != NULL);
|
||||||
AES_VALIDATE_RET(input != NULL);
|
AES_VALIDATE_RET(input != NULL);
|
||||||
|
@ -311,7 +331,15 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||||
AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
|
AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
|
||||||
mode == MBEDTLS_AES_DECRYPT);
|
mode == MBEDTLS_AES_DECRYPT);
|
||||||
|
|
||||||
/* allow multi-instance of CRYP use: restore context for CRYP hw module */
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP use: restore context */
|
||||||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
||||||
|
|
||||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
||||||
|
@ -322,45 +350,45 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||||
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_ECB;
|
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_ECB;
|
||||||
|
|
||||||
/* Configure the CRYP */
|
/* Configure the CRYP */
|
||||||
HAL_CRYP_SetConfig(&ctx->hcryp_aes, &ctx->hcryp_aes.Init);
|
if (HAL_CRYP_SetConfig(&ctx->hcryp_aes,
|
||||||
|
&ctx->hcryp_aes.Init) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) { /* AES decryption */
|
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||||
|
/* AES decryption */
|
||||||
ret = mbedtls_internal_aes_decrypt(ctx, input, output);
|
ret = mbedtls_internal_aes_decrypt(ctx, input, output);
|
||||||
if (ret) {
|
if (ret != 0) {
|
||||||
return ST_ERR_AES_BUSY;
|
goto exit;
|
||||||
}
|
}
|
||||||
} else { /* AES encryption */
|
} else {
|
||||||
|
/* AES encryption */
|
||||||
ret = mbedtls_internal_aes_encrypt(ctx, input, output);
|
ret = mbedtls_internal_aes_encrypt(ctx, input, output);
|
||||||
if (ret) {
|
if (ret != 0) {
|
||||||
return ST_ERR_AES_BUSY;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* allow multi-instance of CRYP use: save context for CRYP HW module CR */
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
||||||
|
|
||||||
return (0);
|
exit:
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
/*
|
/*
|
||||||
* AES-CBC buffer encryption/decryption
|
* AES-CBC buffer encryption/decryption
|
||||||
*/
|
*/
|
||||||
static int st_cbc_restore_context(mbedtls_aes_context *ctx)
|
|
||||||
{
|
|
||||||
/* allow multi-instance of CRYP use: restore context for CRYP hw module */
|
|
||||||
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
|
||||||
/* Re-initialize AES processor with proper parameters
|
|
||||||
and (re-)apply key and IV for multi context usecases */
|
|
||||||
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
if (HAL_CRYP_Init(&ctx->hcryp_aes) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
||||||
int mode,
|
int mode,
|
||||||
size_t length,
|
size_t length,
|
||||||
|
@ -368,10 +396,10 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output)
|
unsigned char *output)
|
||||||
{
|
{
|
||||||
uint32_t tickstart;
|
unsigned int i;
|
||||||
uint32_t *iv_ptr = (uint32_t *)&iv[0];
|
__ALIGN_BEGIN static uint32_t iv_32B[4];
|
||||||
|
__ALIGN_END
|
||||||
ALIGN_32BYTES(static uint32_t iv_32B[4]);
|
int ret = 0;
|
||||||
|
|
||||||
AES_VALIDATE_RET(ctx != NULL);
|
AES_VALIDATE_RET(ctx != NULL);
|
||||||
AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
|
AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
|
||||||
|
@ -384,61 +412,74 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
||||||
return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
|
return (MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st_cbc_restore_context(ctx) != 0) {
|
/* Protect context access */
|
||||||
return (ST_ERR_AES_BUSY);
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
}
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP use: restore context */
|
||||||
|
ctx->hcryp_aes.Instance->CR = ctx->ctx_save_cr;
|
||||||
|
|
||||||
/* Set the Algo if not configured till now */
|
/* Set the Algo if not configured till now */
|
||||||
if (CRYP_AES_CBC != ctx->hcryp_aes.Init.Algorithm) {
|
if (CRYP_AES_CBC != ctx->hcryp_aes.Init.Algorithm) {
|
||||||
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_CBC;
|
ctx->hcryp_aes.Init.Algorithm = CRYP_AES_CBC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
/* Set IV with invert endianness */
|
||||||
ctx->hcryp_aes.Init.pInitVect = (uint32_t *)&iv[0];
|
for (i = 0; i < 4; i++) {
|
||||||
|
GET_UINT32_BE(iv_32B[i], iv, 4 * i);
|
||||||
/* reconfigure the CRYP */
|
|
||||||
HAL_CRYP_SetConfig(&ctx->hcryp_aes, &ctx->hcryp_aes.Init);
|
|
||||||
|
|
||||||
if (HAL_CRYP_Decrypt(&ctx->hcryp_aes, (uint32_t *)input, length / 4, (uint32_t *)output, TIMEOUT_VALUE) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save the internal IV vector for multi context purpose */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((ctx->hcryp_aes.Instance->SR & (CRYP_SR_IFEM | CRYP_SR_OFNE | CRYP_SR_BUSY)) != CRYP_SR_IFEM) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_AES_TIMEOUT) {
|
|
||||||
return ST_ERR_AES_BUSY; // timeout: CRYP processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR; // save here before overwritten
|
|
||||||
ctx->hcryp_aes.Instance->CR &= ~CRYP_CR_CRYPEN;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV0LR;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV0RR;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV1LR;
|
|
||||||
*iv_ptr++ = ctx->hcryp_aes.Instance->IV1RR;
|
|
||||||
} else {
|
|
||||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
|
||||||
ctx->hcryp_aes.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
|
||||||
|
|
||||||
SWAP_B8_TO_B32(iv_32B[0], iv, 0);
|
|
||||||
SWAP_B8_TO_B32(iv_32B[1], iv, 4);
|
|
||||||
SWAP_B8_TO_B32(iv_32B[2], iv, 8);
|
|
||||||
SWAP_B8_TO_B32(iv_32B[3], iv, 12);
|
|
||||||
|
|
||||||
ctx->hcryp_aes.Init.pInitVect = iv_32B;
|
|
||||||
|
|
||||||
/* reconfigure the CRYP */
|
|
||||||
HAL_CRYP_SetConfig(&ctx->hcryp_aes, &ctx->hcryp_aes.Init);
|
|
||||||
|
|
||||||
if (HAL_CRYP_Encrypt(&ctx->hcryp_aes, (uint32_t *)input, length, (uint32_t *)output, TIMEOUT_VALUE) != HAL_OK) {
|
|
||||||
return ST_ERR_AES_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(iv, output, 16); /* current output is the IV vector for the next call */
|
|
||||||
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
ctx->hcryp_aes.Init.pInitVect = iv_32B;
|
||||||
|
|
||||||
|
/* reconfigure the CRYP */
|
||||||
|
if (HAL_CRYP_SetConfig(&ctx->hcryp_aes,
|
||||||
|
&ctx->hcryp_aes.Init) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||||
|
/* current input is the IV vector for the next decrypt */
|
||||||
|
memcpy(iv, input, 16);
|
||||||
|
|
||||||
|
if (HAL_CRYP_Decrypt(&ctx->hcryp_aes,
|
||||||
|
(uint32_t *)input,
|
||||||
|
length,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (HAL_CRYP_Encrypt(&ctx->hcryp_aes,
|
||||||
|
(uint32_t *)input,
|
||||||
|
length,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* current output is the IV vector for the next encrypt */
|
||||||
|
memcpy(iv, output, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
|
ctx->ctx_save_cr = ctx->hcryp_aes.Instance->CR;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||||
|
|
||||||
|
@ -623,6 +664,7 @@ int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output)
|
unsigned char *output)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
int c;
|
int c;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
|
@ -638,10 +680,12 @@ int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||||
while (length--) {
|
while (length--) {
|
||||||
if (n == 0)
|
if (n == 0) {
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv) != 0) {
|
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
|
||||||
return ST_ERR_AES_BUSY;
|
if (ret != 0) {
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c = *input++;
|
c = *input++;
|
||||||
*output++ = (unsigned char)(c ^ iv[n]);
|
*output++ = (unsigned char)(c ^ iv[n]);
|
||||||
|
@ -651,10 +695,12 @@ int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (length--) {
|
while (length--) {
|
||||||
if (n == 0)
|
if (n == 0) {
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv) != 0) {
|
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
|
||||||
return ST_ERR_AES_BUSY;
|
if (ret != 0) {
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iv[n] = *output++ = (unsigned char)(iv[n] ^ *input++);
|
iv[n] = *output++ = (unsigned char)(iv[n] ^ *input++);
|
||||||
|
|
||||||
|
@ -677,6 +723,7 @@ int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
unsigned char *output)
|
unsigned char *output)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
unsigned char ov[17];
|
unsigned char ov[17];
|
||||||
|
|
||||||
|
@ -689,8 +736,9 @@ int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
while (length--) {
|
while (length--) {
|
||||||
memcpy(ov, iv, 16);
|
memcpy(ov, iv, 16);
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv) != 0) {
|
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
|
||||||
return ST_ERR_AES_BUSY;
|
if (ret != 0) {
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||||
|
@ -780,10 +828,14 @@ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
n = *nc_off;
|
n = *nc_off;
|
||||||
|
|
||||||
|
if (n > 0x0F) {
|
||||||
|
return (MBEDTLS_ERR_AES_BAD_INPUT_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
while (length--) {
|
while (length--) {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block) != 0) {
|
if (mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block) != 0) {
|
||||||
return ST_ERR_AES_BUSY;
|
return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 16; i > 0; i--)
|
for (i = 16; i > 0; i--)
|
||||||
|
@ -808,11 +860,14 @@ int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
||||||
unsigned char output[16])
|
unsigned char output[16])
|
||||||
{
|
{
|
||||||
|
|
||||||
if (HAL_CRYP_Encrypt(&ctx->hcryp_aes, (uint32_t *)input, 4, (uint32_t *)output, TIMEOUT_VALUE) != HAL_OK) {
|
if (HAL_CRYP_Encrypt(&ctx->hcryp_aes,
|
||||||
// error found
|
(uint32_t *)input,
|
||||||
return ST_ERR_AES_BUSY;
|
16,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
|
||||||
}
|
}
|
||||||
return 0;
|
return (0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,27 +875,31 @@ int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16])
|
unsigned char output[16])
|
||||||
{
|
{
|
||||||
if (HAL_CRYP_Decrypt(&ctx->hcryp_aes, (uint32_t *)input, 4, (uint32_t *)output, TIMEOUT_VALUE) != HAL_OK) {
|
if (HAL_CRYP_Decrypt(&ctx->hcryp_aes,
|
||||||
// error found
|
(uint32_t *)input,
|
||||||
return ST_ERR_AES_BUSY;
|
16,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
return (MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED);
|
||||||
}
|
}
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
#if defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||||
void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
|
void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16])
|
unsigned char output[16])
|
||||||
{
|
{
|
||||||
mbedtls_internal_aes_encrypt(ctx, input, output);
|
#error "mbedtls_aes_encrypt() is a deprecated function (not implemented)"
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
||||||
const unsigned char input[16],
|
const unsigned char input[16],
|
||||||
unsigned char output[16])
|
unsigned char output[16])
|
||||||
{
|
{
|
||||||
mbedtls_internal_aes_decrypt(ctx, input, output);
|
#error "mbedtls_aes_decrypt() is a deprecated function (not implemented)"
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
#endif /*MBEDTLS_AES_ALT*/
|
#endif /*MBEDTLS_AES_ALT*/
|
||||||
#endif /* MBEDTLS_AES_C */
|
#endif /* MBEDTLS_AES_C */
|
||||||
|
#endif /* !(TARGET_STM32L4) */
|
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
* \file aes_alt.h
|
||||||
|
*
|
||||||
|
* \brief This file contains AES definitions and functions.
|
||||||
|
*
|
||||||
|
* The Advanced Encryption Standard (AES) specifies a FIPS-approved
|
||||||
|
* cryptographic algorithm that can be used to protect electronic
|
||||||
|
* data.
|
||||||
|
*
|
||||||
|
* The AES algorithm is a symmetric block cipher that can
|
||||||
|
* encrypt and decrypt information. For more information, see
|
||||||
|
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and
|
||||||
|
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
|
||||||
|
* techniques -- Encryption algorithms -- Part 2: Asymmetric
|
||||||
|
* ciphers</em>.
|
||||||
|
*
|
||||||
|
* The AES-XTS block mode is standardized by NIST SP 800-38E
|
||||||
|
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
|
||||||
|
* and described in detail by IEEE P1619
|
||||||
|
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
|
||||||
|
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements ST AES HW services based on API from mbed TLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef MBEDTLS_AES_ALT_H
|
||||||
|
#define MBEDTLS_AES_ALT_H
|
||||||
|
|
||||||
|
#if (TARGET_STM32L4)
|
||||||
|
#include "aes_alt_stm32l4.h"
|
||||||
|
#else
|
||||||
|
#if defined(MBEDTLS_AES_ALT)
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "cryp_stm32.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief AES context structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/* Encryption/Decryption key */
|
||||||
|
uint32_t aes_key[8];
|
||||||
|
|
||||||
|
CRYP_HandleTypeDef hcryp_aes; /* AES context */
|
||||||
|
uint32_t ctx_save_cr; /* save context for multi-context */
|
||||||
|
}
|
||||||
|
mbedtls_aes_context;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||||
|
/**
|
||||||
|
* \brief The AES XTS context-type definition.
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_aes_xts_context {
|
||||||
|
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
|
||||||
|
encryption or decryption. */
|
||||||
|
mbedtls_aes_context tweak; /*!< The AES context used for tweak
|
||||||
|
computation. */
|
||||||
|
} mbedtls_aes_xts_context;
|
||||||
|
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_AES_ALT */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_AES_ALT_H */
|
||||||
|
|
||||||
|
#endif /* ! TARGET_STM32L4 */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Hardware aes implementation for STM32F4 STM32F7 and STM32L4 families
|
* Hardware AES implementation for STM32L4 family
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
* Copyright (c) 2017, STMicroelectronics
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
@ -18,17 +18,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#if (TARGET_STM32L4)
|
||||||
|
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
|
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
#if defined(MBEDTLS_AES_ALT)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "mbedtls/platform.h"
|
#include "mbedtls/platform.h"
|
||||||
//the following defines are provided to maintain compatibility between STM32 families
|
|
||||||
#define __HAL_RCC_CRYP_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE
|
|
||||||
#define __HAL_RCC_CRYP_FORCE_RESET __HAL_RCC_AES_FORCE_RESET
|
|
||||||
#define __HAL_RCC_CRYP_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET
|
|
||||||
#define CRYP AES
|
|
||||||
|
|
||||||
static int aes_set_key(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
|
static int aes_set_key(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits)
|
||||||
{
|
{
|
||||||
|
@ -48,7 +46,7 @@ static int aes_set_key(mbedtls_aes_context *ctx, const unsigned char *key, unsig
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
ctx->hcryp_aes.Init.DataType = CRYP_DATATYPE_8B;
|
||||||
ctx->hcryp_aes.Instance = CRYP;
|
ctx->hcryp_aes.Instance = AES;
|
||||||
|
|
||||||
/* Deinitializes the CRYP peripheral */
|
/* Deinitializes the CRYP peripheral */
|
||||||
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) == HAL_ERROR) {
|
if (HAL_CRYP_DeInit(&ctx->hcryp_aes) == HAL_ERROR) {
|
||||||
|
@ -56,7 +54,7 @@ static int aes_set_key(mbedtls_aes_context *ctx, const unsigned char *key, unsig
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable CRYP clock */
|
/* Enable CRYP clock */
|
||||||
__HAL_RCC_CRYP_CLK_ENABLE();
|
__HAL_RCC_AES_CLK_ENABLE();
|
||||||
|
|
||||||
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
ctx->hcryp_aes.Init.pKey = ctx->aes_key;
|
||||||
ctx->hcryp_aes.Init.KeyWriteFlag = CRYP_KEY_WRITE_ENABLE;
|
ctx->hcryp_aes.Init.KeyWriteFlag = CRYP_KEY_WRITE_ENABLE;
|
||||||
|
@ -97,10 +95,10 @@ void mbedtls_aes_free(mbedtls_aes_context *ctx)
|
||||||
}
|
}
|
||||||
#endif /* DUAL_CORE */
|
#endif /* DUAL_CORE */
|
||||||
/* Force the CRYP Periheral Clock Reset */
|
/* Force the CRYP Periheral Clock Reset */
|
||||||
__HAL_RCC_CRYP_FORCE_RESET();
|
__HAL_RCC_AES_FORCE_RESET();
|
||||||
|
|
||||||
/* Release the CRYP Periheral Clock Reset */
|
/* Release the CRYP Periheral Clock Reset */
|
||||||
__HAL_RCC_CRYP_RELEASE_RESET();
|
__HAL_RCC_AES_RELEASE_RESET();
|
||||||
#if defined(DUAL_CORE)
|
#if defined(DUAL_CORE)
|
||||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
|
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
|
||||||
#endif /* DUAL_CORE */
|
#endif /* DUAL_CORE */
|
||||||
|
@ -388,3 +386,4 @@ void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||||
#endif /*MBEDTLS_AES_ALT*/
|
#endif /*MBEDTLS_AES_ALT*/
|
||||||
|
#endif /* TARGET_STM32L4 */
|
|
@ -17,10 +17,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef MBEDTLS_AES_ALT_H
|
#ifndef MBEDTLS_STM32L4_AES_ALT_H
|
||||||
#define MBEDTLS_AES_ALT_H
|
#define MBEDTLS_STM32L4_AES_ALT_H
|
||||||
|
|
||||||
|
|
||||||
|
#if (TARGET_STM32L4)
|
||||||
#if defined(MBEDTLS_AES_ALT)
|
#if defined(MBEDTLS_AES_ALT)
|
||||||
#include "mbedtls/platform.h"
|
#include "mbedtls/platform.h"
|
||||||
#include "mbedtls/config.h"
|
#include "mbedtls/config.h"
|
||||||
|
@ -303,5 +304,6 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
||||||
|
|
||||||
#endif /* MBEDTLS_AES_ALT */
|
#endif /* MBEDTLS_AES_ALT */
|
||||||
|
|
||||||
#endif /* MBEDTLS_AES_ALT_H */
|
#endif /* TARGET_STM32L4 */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_STM32L4_AES_ALT_H */
|
|
@ -0,0 +1,504 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements ST CCM HW services based on API from mbed TLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition of CCM:
|
||||||
|
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
|
||||||
|
* RFC 3610 "Counter with CBC-MAC (CCM)"
|
||||||
|
*
|
||||||
|
* Related:
|
||||||
|
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "mbedtls/ccm.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CCM_C)
|
||||||
|
#if defined(MBEDTLS_CCM_ALT)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
|
#include "platform/PlatformMutex.h"
|
||||||
|
#include "platform/SingletonPtr.h"
|
||||||
|
|
||||||
|
static SingletonPtr<PlatformMutex> ccm_mutex;
|
||||||
|
|
||||||
|
#define MBEDTLS_DEBUG 0
|
||||||
|
|
||||||
|
/* Parameter validation macros */
|
||||||
|
#define CCM_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
|
||||||
|
#define CCM_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
#define CCM_ENCRYPT 0
|
||||||
|
#define CCM_DECRYPT 1
|
||||||
|
|
||||||
|
#define H_LENGTH 2 /* Formatting of the Associated Data */
|
||||||
|
/* If 0 < a < 2e16-2e8, */
|
||||||
|
/* then a is encoded as [a]16, i.e., two octets */
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Initialize context
|
||||||
|
*/
|
||||||
|
void mbedtls_ccm_init(mbedtls_ccm_context *ctx)
|
||||||
|
{
|
||||||
|
CCM_VALIDATE(ctx != NULL);
|
||||||
|
|
||||||
|
ccm_mutex->lock();
|
||||||
|
cryp_context_count++;
|
||||||
|
ccm_mutex->unlock();
|
||||||
|
|
||||||
|
cryp_zeroize((void *)ctx, sizeof(mbedtls_ccm_context));
|
||||||
|
|
||||||
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] mbedtls_ccm_init %u\n", cryp_context_count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx,
|
||||||
|
mbedtls_cipher_id_t cipher,
|
||||||
|
const unsigned char *key,
|
||||||
|
unsigned int keybits)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] mbedtls_ccm_setkey\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
CCM_VALIDATE_RET(key != NULL);
|
||||||
|
|
||||||
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
switch (keybits) {
|
||||||
|
case 128:
|
||||||
|
ctx->hcryp_ccm.Init.KeySize = CRYP_KEYSIZE_128B;;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 192:
|
||||||
|
#if ( USE_AES_KEY192 == 1 )
|
||||||
|
ctx->hcryp_ccm.Init.KeySize = CRYP_KEYSIZE_192B;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||||
|
goto exit;
|
||||||
|
#endif /* USE_AES_KEY192 */
|
||||||
|
|
||||||
|
case 256:
|
||||||
|
ctx->hcryp_ccm.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
ret = MBEDTLS_ERR_CCM_BAD_INPUT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format and fill AES key */
|
||||||
|
for (i = 0; i < (keybits / 32) ; i++) {
|
||||||
|
GET_UINT32_BE(ctx->ccm_key[i], key, 4 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* include the appropriate instance name */
|
||||||
|
#if defined (AES)
|
||||||
|
ctx->hcryp_ccm.Instance = AES;
|
||||||
|
#elif defined (AES1)
|
||||||
|
ctx->hcryp_ccm.Instance = AES1;
|
||||||
|
#else /* CRYP */
|
||||||
|
ctx->hcryp_ccm.Instance = CRYP;
|
||||||
|
#endif /* AES */
|
||||||
|
|
||||||
|
ctx->hcryp_ccm.Init.DataType = CRYP_DATATYPE_8B;
|
||||||
|
ctx->hcryp_ccm.Init.pKey = ctx->ccm_key;
|
||||||
|
ctx->hcryp_ccm.Init.pInitVect = NULL;
|
||||||
|
ctx->hcryp_ccm.Init.Algorithm = CRYP_AES_CCM;
|
||||||
|
ctx->hcryp_ccm.Init.Header = NULL;
|
||||||
|
ctx->hcryp_ccm.Init.HeaderSize = 0;
|
||||||
|
ctx->hcryp_ccm.Init.B0 = NULL;
|
||||||
|
ctx->hcryp_ccm.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||||
|
|
||||||
|
if (HAL_CRYP_Init(&ctx->hcryp_ccm) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
|
ctx->ctx_save_cr = ctx->hcryp_ccm.Instance->CR;
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free context
|
||||||
|
*/
|
||||||
|
void mbedtls_ccm_free(mbedtls_ccm_context *ctx)
|
||||||
|
{
|
||||||
|
#if (MBEDTLS_DEBUG)
|
||||||
|
printf("[ALT] mbedtls_ccm_free %u\n", cryp_context_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccm_mutex->lock();
|
||||||
|
|
||||||
|
if (cryp_context_count > 0) {
|
||||||
|
cryp_context_count--;
|
||||||
|
|
||||||
|
/* Shut down CRYP on last context */
|
||||||
|
if (cryp_context_count == 0) {
|
||||||
|
HAL_CRYP_DeInit(&ctx->hcryp_ccm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ccm_mutex->unlock();
|
||||||
|
|
||||||
|
cryp_zeroize((void *)ctx, sizeof(mbedtls_ccm_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authenticated encryption or decryption
|
||||||
|
*/
|
||||||
|
static int ccm_auth_crypt(mbedtls_ccm_context *ctx, int mode, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
unsigned char *tag, size_t tag_len)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
unsigned char i;
|
||||||
|
unsigned char q;
|
||||||
|
size_t len_left;
|
||||||
|
unsigned int j;
|
||||||
|
|
||||||
|
__ALIGN_BEGIN unsigned char b0[16] __ALIGN_END; /* Formatting of B0 */
|
||||||
|
__ALIGN_BEGIN uint32_t b0_32B[4] __ALIGN_END; /* B0 data swapping */
|
||||||
|
unsigned char *b1_padded_addr = NULL; /* Formatting of B1 */
|
||||||
|
unsigned char *b1_aligned_addr = NULL;
|
||||||
|
size_t b1_length; /* B1 with padding */
|
||||||
|
uint8_t b1_padding; /* B1 word alignement */
|
||||||
|
|
||||||
|
__ALIGN_BEGIN uint8_t mac[16] __ALIGN_END; /* temporary mac */
|
||||||
|
|
||||||
|
|
||||||
|
CCM_VALIDATE_RET(mode != CCM_ENCRYPT || mode != CCM_DECRYPT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check length requirements: SP800-38C A.1
|
||||||
|
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
|
||||||
|
* 'length' checked later (when writing it to the first block)
|
||||||
|
*
|
||||||
|
* Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tag_len, aka t, is an element of {4, 6, 8, 10, 12, 14, 16} */
|
||||||
|
if (tag_len < 4 || tag_len > 16 || tag_len % 2 != 0) {
|
||||||
|
return (MBEDTLS_ERR_CCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Also implies q is within bounds */
|
||||||
|
/* iv_len, aka n, is an element of {7, 8, 9, 10, 11, 12, 13} */
|
||||||
|
if (iv_len < 7 || iv_len > 13) {
|
||||||
|
return (MBEDTLS_ERR_CCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add_len, aka a, a < 2^16 - 2^8 */
|
||||||
|
if (add_len > 0xFF00) {
|
||||||
|
return (MBEDTLS_ERR_CCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The octet length of Q, denoted q */
|
||||||
|
q = 15 - (unsigned char) iv_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First block B_0:
|
||||||
|
* 0 .. 0 flags
|
||||||
|
* 1 .. iv_len nonce (aka iv)
|
||||||
|
* iv_len+1 .. 15 length
|
||||||
|
*
|
||||||
|
* With flags as (bits):
|
||||||
|
* 7 0
|
||||||
|
* 6 add present?
|
||||||
|
* 5 .. 3 (t - 2) / 2
|
||||||
|
* 2 .. 0 q - 1
|
||||||
|
*/
|
||||||
|
memset(b0, 0, 16);
|
||||||
|
if (add_len > 0) {
|
||||||
|
b0[0] |= 0x40;
|
||||||
|
}
|
||||||
|
b0[0] |= ((tag_len - 2) / 2) << 3;
|
||||||
|
b0[0] |= q - 1;
|
||||||
|
|
||||||
|
/* Nonce concatenation */
|
||||||
|
memcpy(b0 + 1, iv, iv_len);
|
||||||
|
|
||||||
|
/* Data length concatenation */
|
||||||
|
for (i = 0, len_left = length; i < q; i++, len_left >>= 8) {
|
||||||
|
b0[15 - i] = (unsigned char)(len_left & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len_left > 0) {
|
||||||
|
return (MBEDTLS_ERR_CCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP use: restore context */
|
||||||
|
ctx->hcryp_ccm.Instance->CR = ctx->ctx_save_cr;
|
||||||
|
/*
|
||||||
|
* If there is additional data, update with
|
||||||
|
* add_len, add, 0 (padding to a block boundary)
|
||||||
|
*/
|
||||||
|
if (add_len > 0) {
|
||||||
|
/* Extra bytes to deal with data padding such that */
|
||||||
|
/* the resulting string can be partitioned into words */
|
||||||
|
b1_padding = ((add_len + H_LENGTH) % 4);
|
||||||
|
b1_length = add_len + H_LENGTH + b1_padding;
|
||||||
|
|
||||||
|
/* reserve extra bytes to deal with 4-bytes memory alignement */
|
||||||
|
b1_padded_addr =
|
||||||
|
mbedtls_calloc(1, b1_length + 3);
|
||||||
|
|
||||||
|
if (b1_padded_addr == NULL) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move up to a 4-bytes aligned address in the reserved memory chuck */
|
||||||
|
b1_aligned_addr =
|
||||||
|
(unsigned char *)((uint32_t)(b1_padded_addr + 3) & 0xFFFFFFFC);
|
||||||
|
|
||||||
|
/* Header length */
|
||||||
|
b1_aligned_addr[0] = (unsigned char)((add_len >> 8) & 0xFF);
|
||||||
|
b1_aligned_addr[1] = (unsigned char)((add_len) & 0xFF);
|
||||||
|
|
||||||
|
/* data concatenation */
|
||||||
|
memcpy(b1_aligned_addr + H_LENGTH, add, add_len);
|
||||||
|
|
||||||
|
/* blocks (B) associated to the Associated Data (A) */
|
||||||
|
ctx->hcryp_ccm.Init.Header = (uint32_t *)b1_aligned_addr;
|
||||||
|
|
||||||
|
ctx->hcryp_ccm.Init.HeaderSize = b1_length / 4;
|
||||||
|
} else {
|
||||||
|
ctx->hcryp_ccm.Init.Header = NULL;
|
||||||
|
ctx->hcryp_ccm.Init.HeaderSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first authentication block */
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
GET_UINT32_BE(b0_32B[j], b0, 4 * j);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->hcryp_ccm.Init.B0 = b0_32B;
|
||||||
|
|
||||||
|
/* reconfigure the CRYP */
|
||||||
|
if (HAL_CRYP_SetConfig(&ctx->hcryp_ccm, &ctx->hcryp_ccm.Init) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto free_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* blocks (B) associated to the plaintext message (P) */
|
||||||
|
if (mode == CCM_DECRYPT) {
|
||||||
|
if (HAL_CRYP_Decrypt(&ctx->hcryp_ccm,
|
||||||
|
(uint32_t *)input,
|
||||||
|
length,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto free_block;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (HAL_CRYP_Encrypt(&ctx->hcryp_ccm,
|
||||||
|
(uint32_t *)input,
|
||||||
|
length,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto free_block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tag has a variable length */
|
||||||
|
memset(mac, 0, sizeof(mac));
|
||||||
|
|
||||||
|
/* Generate the authentication TAG */
|
||||||
|
if (HAL_CRYPEx_AESCCM_GenerateAuthTAG(&ctx->hcryp_ccm,
|
||||||
|
(uint32_t *)mac,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto free_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tag, mac, tag_len);
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
|
ctx->ctx_save_cr = ctx->hcryp_ccm.Instance->CR;
|
||||||
|
|
||||||
|
free_block:
|
||||||
|
if (add_len > 0) {
|
||||||
|
mbedtls_free(b1_padded_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authenticated encryption
|
||||||
|
*/
|
||||||
|
int mbedtls_ccm_star_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
unsigned char *tag, size_t tag_len)
|
||||||
|
{
|
||||||
|
CCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
CCM_VALIDATE_RET(iv != NULL);
|
||||||
|
CCM_VALIDATE_RET(add_len == 0 || add != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || input != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || output != NULL);
|
||||||
|
CCM_VALIDATE_RET(tag_len == 0 || tag != NULL);
|
||||||
|
return (ccm_auth_crypt(ctx, CCM_ENCRYPT, length, iv, iv_len,
|
||||||
|
add, add_len, input, output, tag, tag_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
unsigned char *tag, size_t tag_len)
|
||||||
|
{
|
||||||
|
CCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
CCM_VALIDATE_RET(iv != NULL);
|
||||||
|
CCM_VALIDATE_RET(add_len == 0 || add != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || input != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || output != NULL);
|
||||||
|
CCM_VALIDATE_RET(tag_len == 0 || tag != NULL);
|
||||||
|
if (tag_len == 0) {
|
||||||
|
return (MBEDTLS_ERR_CCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (mbedtls_ccm_star_encrypt_and_tag(ctx, length, iv, iv_len, add,
|
||||||
|
add_len, input, output, tag, tag_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Authenticated decryption
|
||||||
|
*/
|
||||||
|
int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
const unsigned char *tag, size_t tag_len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char check_tag[16];
|
||||||
|
unsigned char i;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
CCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
CCM_VALIDATE_RET(iv != NULL);
|
||||||
|
CCM_VALIDATE_RET(add_len == 0 || add != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || input != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || output != NULL);
|
||||||
|
CCM_VALIDATE_RET(tag_len == 0 || tag != NULL);
|
||||||
|
|
||||||
|
if ((ret = ccm_auth_crypt(ctx, CCM_DECRYPT, length,
|
||||||
|
iv, iv_len, add, add_len,
|
||||||
|
input, output, check_tag, tag_len)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check tag in "constant-time" */
|
||||||
|
for (diff = 0, i = 0; i < tag_len; i++) {
|
||||||
|
diff |= tag[i] ^ check_tag[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff != 0) {
|
||||||
|
mbedtls_platform_zeroize(output, length);
|
||||||
|
return (MBEDTLS_ERR_CCM_AUTH_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx, size_t length,
|
||||||
|
const unsigned char *iv, size_t iv_len,
|
||||||
|
const unsigned char *add, size_t add_len,
|
||||||
|
const unsigned char *input, unsigned char *output,
|
||||||
|
const unsigned char *tag, size_t tag_len)
|
||||||
|
{
|
||||||
|
CCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
CCM_VALIDATE_RET(iv != NULL);
|
||||||
|
CCM_VALIDATE_RET(add_len == 0 || add != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || input != NULL);
|
||||||
|
CCM_VALIDATE_RET(length == 0 || output != NULL);
|
||||||
|
CCM_VALIDATE_RET(tag_len == 0 || tag != NULL);
|
||||||
|
|
||||||
|
if (tag_len == 0) {
|
||||||
|
return (MBEDTLS_ERR_CCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (mbedtls_ccm_star_auth_decrypt(ctx, length, iv, iv_len, add,
|
||||||
|
add_len, input, output, tag, tag_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*MBEDTLS_CCM_ALT*/
|
||||||
|
#endif /*MBEDTLS_CCM_C*/
|
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* \file ccm.h
|
||||||
|
*
|
||||||
|
* \brief This file provides an API for the CCM authenticated encryption
|
||||||
|
* mode for block ciphers.
|
||||||
|
*
|
||||||
|
* CCM combines Counter mode encryption with CBC-MAC authentication
|
||||||
|
* for 128-bit block ciphers.
|
||||||
|
*
|
||||||
|
* Input to CCM includes the following elements:
|
||||||
|
* <ul><li>Payload - data that is both authenticated and encrypted.</li>
|
||||||
|
* <li>Associated data (Adata) - data that is authenticated but not
|
||||||
|
* encrypted, For example, a header.</li>
|
||||||
|
* <li>Nonce - A unique value that is assigned to the payload and the
|
||||||
|
* associated data.</li></ul>
|
||||||
|
*
|
||||||
|
* Definition of CCM:
|
||||||
|
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
|
||||||
|
* RFC 3610 "Counter with CBC-MAC (CCM)"
|
||||||
|
*
|
||||||
|
* Related:
|
||||||
|
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
|
||||||
|
*
|
||||||
|
* Definition of CCM*:
|
||||||
|
* IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
|
||||||
|
* Integer representation is fixed most-significant-octet-first order and
|
||||||
|
* the representation of octets is most-significant-bit-first order. This is
|
||||||
|
* consistent with RFC 3610.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements ST CCM HW services based on API from mbed TLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef MBEDTLS_CCM_ALT_H
|
||||||
|
#define MBEDTLS_CCM_ALT_H
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_CCM_ALT)
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "cryp_stm32.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief The CCM context-type definition. The CCM context is passed
|
||||||
|
* to the APIs called.
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_ccm_context {
|
||||||
|
/* Encryption/Decryption key */
|
||||||
|
uint32_t ccm_key[8];
|
||||||
|
|
||||||
|
CRYP_HandleTypeDef hcryp_ccm; /* CCM context */
|
||||||
|
uint32_t ctx_save_cr; /* save context for multi-context */
|
||||||
|
}
|
||||||
|
mbedtls_ccm_context;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_CCM_ALT */
|
||||||
|
#endif /* MBEDTLS_CCM_ALT_H */
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements ST shared CRYP services based on API from mbed TLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(TARGET_STM32L4)
|
||||||
|
#if defined(MBEDTLS_AES_ALT) || defined(MBEDTLS_CCM_ALT) || defined(MBEDTLS_GCM_ALT)
|
||||||
|
|
||||||
|
#include "cryp_stm32.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Variables -----------------------------------------------------------------*/
|
||||||
|
/* Mutex protection because of one Crypt Hw instance is shared over several */
|
||||||
|
/* mode of operations (AES, GCM, CCM implementations may be enabled together) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
mbedtls_threading_mutex_t cryp_mutex;
|
||||||
|
unsigned char cryp_mutex_started = 0;
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
unsigned int cryp_context_count = 0;
|
||||||
|
|
||||||
|
/* Functions -----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Implementation that should never be optimized out by the compiler */
|
||||||
|
void cryp_zeroize(void *v, size_t n)
|
||||||
|
{
|
||||||
|
volatile unsigned char *p = (unsigned char *)v;
|
||||||
|
while (n--) {
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* HAL function that should be implemented in the user file */
|
||||||
|
/**
|
||||||
|
* @brief CRYP MSP Initialization
|
||||||
|
* This function configures the hardware resources used in this example:
|
||||||
|
* - Peripherals clock enable
|
||||||
|
* @param hcryp: CRYP handle pointer
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
|
||||||
|
{
|
||||||
|
#if defined (AES)
|
||||||
|
/* Enable CRYP clock */
|
||||||
|
__HAL_RCC_AES_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Force the CRYP Peripheral Clock Reset */
|
||||||
|
__HAL_RCC_AES_FORCE_RESET();
|
||||||
|
|
||||||
|
/* Release the CRYP Peripheral Clock Reset */
|
||||||
|
__HAL_RCC_AES_RELEASE_RESET();
|
||||||
|
#elif defined (AES1)
|
||||||
|
/* Enable CRYP clock */
|
||||||
|
__HAL_RCC_AES1_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Force the CRYP Peripheral Clock Reset */
|
||||||
|
__HAL_RCC_AES1_FORCE_RESET();
|
||||||
|
|
||||||
|
/* Release the CRYP Peripheral Clock Reset */
|
||||||
|
__HAL_RCC_AES1_RELEASE_RESET();
|
||||||
|
#else /* CRYP */
|
||||||
|
/* Enable CRYP clock */
|
||||||
|
__HAL_RCC_CRYP_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Force the CRYP Peripheral Clock Reset */
|
||||||
|
__HAL_RCC_CRYP_FORCE_RESET();
|
||||||
|
|
||||||
|
/* Release the CRYP Peripheral Clock Reset */
|
||||||
|
__HAL_RCC_CRYP_RELEASE_RESET();
|
||||||
|
#endif /* AES */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CRYP MSP De-Initialization
|
||||||
|
* This function freeze the hardware resources used in this example:
|
||||||
|
* - Disable the Peripherals clock
|
||||||
|
* @param hcryp: CRYP handle pointer
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
|
||||||
|
{
|
||||||
|
#if defined (AES)
|
||||||
|
__HAL_RCC_AES_CLK_DISABLE();
|
||||||
|
#elif defined (AES1)
|
||||||
|
__HAL_RCC_AES1_CLK_DISABLE();
|
||||||
|
#else /* CRYP */
|
||||||
|
/* Disable CRYP clock */
|
||||||
|
__HAL_RCC_CRYP_CLK_DISABLE();
|
||||||
|
#endif /* AES */
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_AES_ALT or MBEDTLS_CCM_ALT or MBEDTLS_GCM_ALT */
|
||||||
|
#endif /* ! TARGET_STM32L4 */
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Header file of mbed TLS HW crypto (CRYP) implementation.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Apache 2.0 license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* https://opensource.org/licenses/Apache-2.0
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __CRYP_H
|
||||||
|
#define __CRYP_H
|
||||||
|
|
||||||
|
#if !(TARGET_STM32L4)
|
||||||
|
#if defined(MBEDTLS_AES_ALT) || defined(MBEDTLS_CCM_ALT) || defined(MBEDTLS_GCM_ALT)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "cmsis.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
#include "mbedtls/threading.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* macros --------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
#ifndef GET_UINT32_BE
|
||||||
|
#define GET_UINT32_BE(n,b,i) \
|
||||||
|
do { \
|
||||||
|
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||||
|
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||||
|
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||||
|
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||||
|
} while( 0 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PUT_UINT32_BE
|
||||||
|
#define PUT_UINT32_BE(n,b,i) \
|
||||||
|
do { \
|
||||||
|
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||||
|
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||||
|
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||||
|
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||||
|
} while( 0 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* constants -----------------------------------------------------------------*/
|
||||||
|
#define ST_CRYP_TIMEOUT 1000 /* timeout (in ms) for the crypto processor */
|
||||||
|
|
||||||
|
/* defines -------------------------------------------------------------------*/
|
||||||
|
/* AES 192 bits key length may be optional in the HW */
|
||||||
|
#if defined CRYP_KEYSIZE_192B
|
||||||
|
#define USE_AES_KEY192 1
|
||||||
|
#else
|
||||||
|
#define USE_AES_KEY192 0
|
||||||
|
#endif /* USE_AES_KEY192 */
|
||||||
|
|
||||||
|
/* variables -----------------------------------------------------------------*/
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
extern mbedtls_threading_mutex_t cryp_mutex;
|
||||||
|
extern unsigned char cryp_mutex_started;
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
extern unsigned int cryp_context_count;
|
||||||
|
|
||||||
|
/* functions prototypes ------------------------------------------------------*/
|
||||||
|
extern void cryp_zeroize(void *v, size_t n);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_AES_ALT or MBEDTLS_CCM_ALT or MBEDTLS_GCM_ALT */
|
||||||
|
#endif /* ! TARGET_STM32L4 */
|
||||||
|
#endif /*__CRYP_H */
|
|
@ -0,0 +1,518 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements ST GCM HW services based on API from mbed TLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "mbedtls/gcm.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_GCM_C)
|
||||||
|
#if defined(MBEDTLS_GCM_ALT)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
|
||||||
|
#include "platform/PlatformMutex.h"
|
||||||
|
#include "platform/SingletonPtr.h"
|
||||||
|
|
||||||
|
static SingletonPtr<PlatformMutex> gcm_mutex;
|
||||||
|
|
||||||
|
|
||||||
|
/* Parameter validation macros */
|
||||||
|
#define GCM_VALIDATE_RET( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
|
||||||
|
#define GCM_VALIDATE( cond ) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
#define IV_LENGTH 12U /* implementations restrict support to 96 bits */
|
||||||
|
|
||||||
|
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
#define AAD_WORD_ALIGN 4U /* implementations restrict AAD support on a */
|
||||||
|
/* buffer multiple of 32 bits */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize a context
|
||||||
|
*/
|
||||||
|
void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
|
||||||
|
{
|
||||||
|
GCM_VALIDATE(ctx != NULL);
|
||||||
|
|
||||||
|
sha1_mutex->lock();
|
||||||
|
cryp_context_count++;
|
||||||
|
sha1_mutex->unlock();
|
||||||
|
|
||||||
|
cryp_zeroize((void *)ctx, sizeof(mbedtls_gcm_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
|
||||||
|
mbedtls_cipher_id_t cipher,
|
||||||
|
const unsigned char *key,
|
||||||
|
unsigned int keybits)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
GCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
GCM_VALIDATE_RET(key != NULL);
|
||||||
|
|
||||||
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
switch (keybits) {
|
||||||
|
case 128:
|
||||||
|
ctx->hcryp_gcm.Init.KeySize = CRYP_KEYSIZE_128B;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 192:
|
||||||
|
#if ( USE_AES_KEY192 == 1 )
|
||||||
|
ctx->hcryp_gcm.Init.KeySize = CRYP_KEYSIZE_192B;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||||
|
goto exit;
|
||||||
|
#endif /* USE_AES_KEY192 */
|
||||||
|
|
||||||
|
case 256:
|
||||||
|
ctx->hcryp_gcm.Init.KeySize = CRYP_KEYSIZE_256B;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
ret = MBEDTLS_ERR_GCM_BAD_INPUT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format and fill AES key */
|
||||||
|
for (i = 0; i < (keybits / 32); i++) {
|
||||||
|
GET_UINT32_BE(ctx->gcm_key[i], key, 4 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* include the appropriate instance name */
|
||||||
|
#if defined (AES)
|
||||||
|
ctx->hcryp_gcm.Instance = AES;
|
||||||
|
ctx->hcryp_gcm.Init.Algorithm = CRYP_AES_GCM_GMAC;
|
||||||
|
#elif defined (AES1)
|
||||||
|
ctx->hcryp_gcm.Instance = AES1;
|
||||||
|
ctx->hcryp_gcm.Init.Algorithm = CRYP_AES_GCM_GMAC;
|
||||||
|
#else /* CRYP */
|
||||||
|
ctx->hcryp_gcm.Instance = CRYP;
|
||||||
|
ctx->hcryp_gcm.Init.Algorithm = CRYP_AES_GCM;
|
||||||
|
#endif /* AES */
|
||||||
|
|
||||||
|
ctx->hcryp_gcm.Init.DataType = CRYP_DATATYPE_8B;
|
||||||
|
ctx->hcryp_gcm.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||||
|
ctx->hcryp_gcm.Init.pKey = ctx->gcm_key;
|
||||||
|
|
||||||
|
if (HAL_CRYP_Init(&ctx->hcryp_gcm) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
|
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
|
||||||
|
int mode,
|
||||||
|
const unsigned char *iv,
|
||||||
|
size_t iv_len,
|
||||||
|
const unsigned char *add,
|
||||||
|
size_t add_len)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
unsigned int i;
|
||||||
|
__ALIGN_BEGIN static uint32_t iv_32B[4] __ALIGN_END;
|
||||||
|
|
||||||
|
GCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
GCM_VALIDATE_RET(mode != MBEDTLS_GCM_ENCRYPT || mode != MBEDTLS_GCM_DECRYPT);
|
||||||
|
GCM_VALIDATE_RET(iv != NULL);
|
||||||
|
GCM_VALIDATE_RET(add_len == 0 || add != NULL);
|
||||||
|
|
||||||
|
/* IV and AD are limited to 2^64 bits, so 2^61 bytes */
|
||||||
|
/* IV is not allowed to be zero length */
|
||||||
|
if (iv_len == 0 ||
|
||||||
|
((uint64_t) iv_len) >> 61 != 0 ||
|
||||||
|
((uint64_t) add_len) >> 61 != 0) {
|
||||||
|
return (MBEDTLS_ERR_GCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* implementation restrict support to the length of 96 bits */
|
||||||
|
if (IV_LENGTH != iv_len) {
|
||||||
|
return (MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
/* implementation restrict support to a buffer multiple of 32 bits */
|
||||||
|
if ((add_len % AAD_WORD_ALIGN) != 0U) {
|
||||||
|
return (MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
if (HAL_CRYP_Init(&ctx->hcryp_gcm) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP use: restore context */
|
||||||
|
ctx->hcryp_gcm.Instance->CR = ctx->ctx_save_cr;
|
||||||
|
|
||||||
|
ctx->mode = mode;
|
||||||
|
ctx->len = 0;
|
||||||
|
|
||||||
|
/* Set IV with invert endianness */
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
GET_UINT32_BE(iv_32B[i], iv, 4 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* According to NIST specification, the counter value is 0x2 when
|
||||||
|
processing the first block of payload */
|
||||||
|
iv_32B[3] = 0x00000002;
|
||||||
|
|
||||||
|
ctx->hcryp_gcm.Init.pInitVect = iv_32B;
|
||||||
|
|
||||||
|
if (add_len > 0) {
|
||||||
|
ctx->hcryp_gcm.Init.Header = (uint32_t *)add;
|
||||||
|
#if defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
/* header buffer in byte length */
|
||||||
|
ctx->hcryp_gcm.Init.HeaderSize = (uint32_t)add_len;
|
||||||
|
#else
|
||||||
|
/* header buffer in word length */
|
||||||
|
ctx->hcryp_gcm.Init.HeaderSize = (uint32_t)(add_len / AAD_WORD_ALIGN);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
ctx->hcryp_gcm.Init.Header = NULL;
|
||||||
|
ctx->hcryp_gcm.Init.HeaderSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
/* Additional Authentication Data in bytes unit */
|
||||||
|
ctx->hcryp_gcm.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Do not Allow IV reconfiguration at every gcm update */
|
||||||
|
ctx->hcryp_gcm.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
|
||||||
|
|
||||||
|
/* reconfigure the CRYP */
|
||||||
|
if (HAL_CRYP_SetConfig(&ctx->hcryp_gcm, &ctx->hcryp_gcm.Init) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
|
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
size_t rest_length = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
GCM_VALIDATE_RET(length == 0 || input != NULL);
|
||||||
|
GCM_VALIDATE_RET(length == 0 || output != NULL);
|
||||||
|
|
||||||
|
if (output > input && (size_t)(output - input) < length) {
|
||||||
|
return (MBEDTLS_ERR_GCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
|
||||||
|
* Also check for possible overflow */
|
||||||
|
if (((ctx->len + length) < ctx->len) ||
|
||||||
|
((uint64_t)(ctx->len + length) > 0xFFFFFFFE0ull)) {
|
||||||
|
return (MBEDTLS_ERR_GCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP use: restore context */
|
||||||
|
ctx->hcryp_gcm.Instance->CR = ctx->ctx_save_cr;
|
||||||
|
|
||||||
|
ctx->len += length;
|
||||||
|
|
||||||
|
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
/* compute remaining data (data buffer in word) */
|
||||||
|
if ((length % AAD_WORD_ALIGN) != 0U) {
|
||||||
|
rest_length = length % AAD_WORD_ALIGN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ctx->mode == MBEDTLS_GCM_DECRYPT) {
|
||||||
|
if (HAL_CRYP_Decrypt(&ctx->hcryp_gcm,
|
||||||
|
(uint32_t *)input,
|
||||||
|
length,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
/* manage last bytes */
|
||||||
|
if (rest_length != 0) {
|
||||||
|
if (HAL_CRYP_Decrypt(&ctx->hcryp_gcm,
|
||||||
|
(uint32_t *)(input + (length / AAD_WORD_ALIGN)),
|
||||||
|
rest_length,
|
||||||
|
(uint32_t *)(output + (length / AAD_WORD_ALIGN)),
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
if (HAL_CRYP_Encrypt(&ctx->hcryp_gcm,
|
||||||
|
(uint32_t *)input,
|
||||||
|
length,
|
||||||
|
(uint32_t *)output,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
#if !defined(STM32_AAD_ANY_LENGTH_SUPPORT)
|
||||||
|
/* manage last bytes */
|
||||||
|
if (rest_length != 0) {
|
||||||
|
if (HAL_CRYP_Encrypt(&ctx->hcryp_gcm,
|
||||||
|
(uint32_t *)(input + (length / AAD_WORD_ALIGN)),
|
||||||
|
rest_length,
|
||||||
|
(uint32_t *)(output + (length / AAD_WORD_ALIGN)),
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
|
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
|
||||||
|
unsigned char *tag,
|
||||||
|
size_t tag_len)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
__ALIGN_BEGIN uint8_t mac[16] __ALIGN_END; /* temporary mac */
|
||||||
|
|
||||||
|
GCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
GCM_VALIDATE_RET(tag != NULL);
|
||||||
|
|
||||||
|
if (tag_len > 16 || tag_len < 4) {
|
||||||
|
return (MBEDTLS_ERR_GCM_BAD_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Protect context access */
|
||||||
|
/* (it may occur at a same time in a threaded environment) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_lock(&cryp_mutex) != 0) {
|
||||||
|
return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP use: restore context */
|
||||||
|
ctx->hcryp_gcm.Instance->CR = ctx->ctx_save_cr;
|
||||||
|
|
||||||
|
/* Tag has a variable length */
|
||||||
|
memset(mac, 0, sizeof(mac));
|
||||||
|
|
||||||
|
/* Generate the authentication TAG */
|
||||||
|
if (HAL_CRYPEx_AESGCM_GenerateAuthTAG(&ctx->hcryp_gcm,
|
||||||
|
(uint32_t *)mac,
|
||||||
|
ST_CRYP_TIMEOUT) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tag, mac, tag_len);
|
||||||
|
|
||||||
|
/* allow multi-context of CRYP : save context */
|
||||||
|
ctx->ctx_save_cr = ctx->hcryp_gcm.Instance->CR;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&cryp_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
|
||||||
|
int mode,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char *iv,
|
||||||
|
size_t iv_len,
|
||||||
|
const unsigned char *add,
|
||||||
|
size_t add_len,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output,
|
||||||
|
size_t tag_len,
|
||||||
|
unsigned char *tag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
GCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
GCM_VALIDATE_RET(iv != NULL);
|
||||||
|
GCM_VALIDATE_RET(add_len == 0 || add != NULL);
|
||||||
|
GCM_VALIDATE_RET(length == 0 || input != NULL);
|
||||||
|
GCM_VALIDATE_RET(length == 0 || output != NULL);
|
||||||
|
GCM_VALIDATE_RET(tag != NULL);
|
||||||
|
|
||||||
|
if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len, add, add_len)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = mbedtls_gcm_update(ctx, length, input, output)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = mbedtls_gcm_finish(ctx, tag, tag_len)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
|
||||||
|
size_t length,
|
||||||
|
const unsigned char *iv,
|
||||||
|
size_t iv_len,
|
||||||
|
const unsigned char *add,
|
||||||
|
size_t add_len,
|
||||||
|
const unsigned char *tag,
|
||||||
|
size_t tag_len,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char check_tag[16];
|
||||||
|
size_t i;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
GCM_VALIDATE_RET(ctx != NULL);
|
||||||
|
GCM_VALIDATE_RET(iv != NULL);
|
||||||
|
GCM_VALIDATE_RET(add_len == 0 || add != NULL);
|
||||||
|
GCM_VALIDATE_RET(tag != NULL);
|
||||||
|
GCM_VALIDATE_RET(length == 0 || input != NULL);
|
||||||
|
GCM_VALIDATE_RET(length == 0 || output != NULL);
|
||||||
|
|
||||||
|
if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length,
|
||||||
|
iv, iv_len, add, add_len,
|
||||||
|
input, output, tag_len, check_tag)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check tag in "constant-time" */
|
||||||
|
for (diff = 0, i = 0; i < tag_len; i++) {
|
||||||
|
diff |= tag[i] ^ check_tag[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff != 0) {
|
||||||
|
mbedtls_platform_zeroize(output, length);
|
||||||
|
return (MBEDTLS_ERR_GCM_AUTH_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gcm_mutex->lock();
|
||||||
|
if (cryp_context_count > 0) {
|
||||||
|
cryp_context_count--;
|
||||||
|
|
||||||
|
/* Shut down CRYP on last context */
|
||||||
|
if (cryp_context_count == 0) {
|
||||||
|
HAL_CRYP_DeInit(&ctx->hcryp_gcm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gcm_mutex->unlock();
|
||||||
|
|
||||||
|
cryp_zeroize((void *)ctx, sizeof(mbedtls_gcm_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*MBEDTLS_GCM_ALT*/
|
||||||
|
#endif /*MBEDTLS_GCM_C*/
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* \file gcm_alt.h.h
|
||||||
|
*
|
||||||
|
* \brief This file contains GCM definitions and functions.
|
||||||
|
*
|
||||||
|
* The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
|
||||||
|
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
|
||||||
|
* (GCM), Natl. Inst. Stand. Technol.</em>
|
||||||
|
*
|
||||||
|
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
|
||||||
|
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020 STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements ST GCM HW services based on API from mbed TLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef MBEDTLS_GCM_ALT_H
|
||||||
|
#define MBEDTLS_GCM_ALT_H
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_GCM_ALT)
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "cryp_stm32.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief AES context structure
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct mbedtls_gcm_context {
|
||||||
|
/* Encryption/Decryption key */
|
||||||
|
uint32_t gcm_key[8];
|
||||||
|
|
||||||
|
CRYP_HandleTypeDef hcryp_gcm; /* HW driver handle */
|
||||||
|
uint32_t ctx_save_cr; /* save context for multi-context */
|
||||||
|
uint64_t len; /* total length of the encrypted data. */
|
||||||
|
int mode; /* The operation to perform:
|
||||||
|
#MBEDTLS_GCM_ENCRYPT or
|
||||||
|
#MBEDTLS_GCM_DECRYPT. */
|
||||||
|
}
|
||||||
|
mbedtls_gcm_context;
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* Uncomment if ADD (Additional Authentication Data) may have not a length */
|
||||||
|
/* over a multiple of 32 bits (Hw implementation dependance) */
|
||||||
|
//#define STM32_AAD_ANY_LENGTH_SUPPORT
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_GCM_ALT */
|
||||||
|
#endif /* MBEDTLS_GCM_ALT_H */
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements ST shared HASH services based on API from mbed TLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_MD5_ALT)
|
||||||
|
|
||||||
|
#include "hash_stm32.h"
|
||||||
|
|
||||||
|
/* Variables -----------------------------------------------------------------*/
|
||||||
|
/* Mutex protection because of one Hash Hw instance is shared over several */
|
||||||
|
/* algorithms (SHA-1, SHA-256, MD5 implementations may be enabled together) */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
mbedtls_threading_mutex_t hash_mutex;
|
||||||
|
unsigned char hash_mutex_started = 0;
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
unsigned int hash_context_count = 0;
|
||||||
|
|
||||||
|
/* Functions -----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Implementation that should never be optimized out by the compiler */
|
||||||
|
void hash_zeroize(void *v, size_t n)
|
||||||
|
{
|
||||||
|
volatile unsigned char *p = (unsigned char *)v;
|
||||||
|
while (n--) {
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HAL function that should be implemented in the user file */
|
||||||
|
/**
|
||||||
|
* @brief HASH MSP Initialization
|
||||||
|
* This function configures the hardware resources used in this example
|
||||||
|
* @param hhash: HASH handle pointer
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash)
|
||||||
|
{
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
__HAL_RCC_HASH_CLK_ENABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HASH MSP De-Initialization
|
||||||
|
* This function freeze the hardware resources used in this example
|
||||||
|
* @param hhash: HASH handle pointer
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash)
|
||||||
|
{
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_HASH_CLK_DISABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SHA1_ALT or MBEDTLS_SHA256_ALT or MBEDTLS_MD5_ALT */
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @brief Header file of mbed TLS HW crypto (HASH) implementation.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019 STMicroelectronics, All Rights Reserved
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under Apache 2.0 license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* https://opensource.org/licenses/Apache-2.0
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __HASH_H
|
||||||
|
#define __HASH_H
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_MD5_ALT)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "cmsis.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
#include "mbedtls/threading.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* macros --------------------------------------------------------------------*/
|
||||||
|
/* constants -----------------------------------------------------------------*/
|
||||||
|
#define ST_HASH_TIMEOUT ((uint32_t) 1000) /* TO in ms for the hash processor */
|
||||||
|
|
||||||
|
/* defines -------------------------------------------------------------------*/
|
||||||
|
/* variables -----------------------------------------------------------------*/
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
extern mbedtls_threading_mutex_t hash_mutex;
|
||||||
|
extern unsigned char hash_mutex_started;
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
extern unsigned int hash_context_count;
|
||||||
|
|
||||||
|
/* functions prototypes ------------------------------------------------------*/
|
||||||
|
extern void hash_zeroize(void *v, size_t n);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SHA1_ALT or MBEDTLS_SHA256_ALT or MBEDTLS_MD5_ALT */
|
||||||
|
#endif /*__HASH_H */
|
|
@ -1,209 +0,0 @@
|
||||||
/*
|
|
||||||
* MD5 hw acceleration
|
|
||||||
*******************************************************************************
|
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "mbedtls/md5.h"
|
|
||||||
#if defined(MBEDTLS_MD5_C)
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD5_ALT)
|
|
||||||
#include "mbedtls/platform.h"
|
|
||||||
|
|
||||||
/* Implementation that should never be optimized out by the compiler */
|
|
||||||
static void mbedtls_zeroize(void *v, size_t n)
|
|
||||||
{
|
|
||||||
volatile unsigned char *p = v;
|
|
||||||
while (n--) {
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int st_md5_restore_hw_context(mbedtls_md5_context *ctx)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t tickstart;
|
|
||||||
/* allow multi-instance of HASH use: save context for HASH HW module CR */
|
|
||||||
/* Check that there is no HASH activity on going */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_MD5_TIMEOUT) {
|
|
||||||
return 0; // timeout: HASH processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HASH->STR = ctx->ctx_save_str;
|
|
||||||
HASH->CR = (ctx->ctx_save_cr | HASH_CR_INIT);
|
|
||||||
for (i = 0; i < 38; i++) {
|
|
||||||
HASH->CSR[i] = ctx->ctx_save_csr[i];
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int st_md5_save_hw_context(mbedtls_md5_context *ctx)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t tickstart;
|
|
||||||
/* Check that there is no HASH activity on going */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_MD5_TIMEOUT) {
|
|
||||||
return 0; // timeout: HASH processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* allow multi-instance of HASH use: restore context for HASH HW module CR */
|
|
||||||
ctx->ctx_save_cr = HASH->CR;
|
|
||||||
ctx->ctx_save_str = HASH->STR;
|
|
||||||
for (i = 0; i < 38; i++) {
|
|
||||||
ctx->ctx_save_csr[i] = HASH->CSR[i];
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_md5_init(mbedtls_md5_context *ctx)
|
|
||||||
{
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_md5_context));
|
|
||||||
|
|
||||||
/* Enable HASH clock */
|
|
||||||
__HAL_RCC_HASH_CLK_ENABLE();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_md5_free(mbedtls_md5_context *ctx)
|
|
||||||
{
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_md5_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_md5_clone(mbedtls_md5_context *dst,
|
|
||||||
const mbedtls_md5_context *src)
|
|
||||||
{
|
|
||||||
*dst = *src;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_md5_starts_ret(mbedtls_md5_context *ctx)
|
|
||||||
{
|
|
||||||
/* HASH IP initialization */
|
|
||||||
if (HAL_HASH_DeInit(&ctx->hhash_md5) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* HASH Configuration */
|
|
||||||
ctx->hhash_md5.Init.DataType = HASH_DATATYPE_8B;
|
|
||||||
/* clear CR ALGO value */
|
|
||||||
HASH->CR &= ~HASH_CR_ALGO_Msk;
|
|
||||||
if (HAL_HASH_Init(&ctx->hhash_md5) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (st_md5_save_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, const unsigned char data[ST_MD5_BLOCK_SIZE])
|
|
||||||
{
|
|
||||||
if (st_md5_restore_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (HAL_HASH_MD5_Accumulate(&ctx->hhash_md5, (uint8_t *)data, ST_MD5_BLOCK_SIZE) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (st_md5_save_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_md5_update_ret(mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
size_t currentlen = ilen;
|
|
||||||
/* If ilen = 0 : do nothing */
|
|
||||||
if (currentlen != 0) {
|
|
||||||
if (st_md5_restore_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store mechanism to accumulate ST_MD5_BLOCK_SIZE bytes (512 bits) in the HW
|
|
||||||
if (currentlen < (ST_MD5_BLOCK_SIZE - ctx->sbuf_len)) {
|
|
||||||
// only buffurize
|
|
||||||
memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
|
|
||||||
ctx->sbuf_len += currentlen;
|
|
||||||
} else {
|
|
||||||
// fill buffer and process it
|
|
||||||
memcpy(ctx->sbuf + ctx->sbuf_len, input, (ST_MD5_BLOCK_SIZE - ctx->sbuf_len));
|
|
||||||
currentlen -= (ST_MD5_BLOCK_SIZE - ctx->sbuf_len);
|
|
||||||
err = mbedtls_internal_md5_process(ctx, ctx->sbuf);
|
|
||||||
if (err != 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
// Process every input as long as it is %64 bytes, ie 512 bits
|
|
||||||
size_t iter = currentlen / ST_MD5_BLOCK_SIZE;
|
|
||||||
if (iter != 0) {
|
|
||||||
if (HAL_HASH_MD5_Accumulate(&ctx->hhash_md5, (uint8_t *)(input + ST_MD5_BLOCK_SIZE - ctx->sbuf_len), (iter * ST_MD5_BLOCK_SIZE)) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sbuf is completely accumulated, now copy up to 63 remaining bytes
|
|
||||||
ctx->sbuf_len = currentlen % ST_MD5_BLOCK_SIZE;
|
|
||||||
if (ctx->sbuf_len != 0) {
|
|
||||||
memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st_md5_save_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_md5_finish_ret(mbedtls_md5_context *ctx, unsigned char output[16])
|
|
||||||
{
|
|
||||||
if (st_md5_restore_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
/* Last accumulation for extra bytes in sbuf_len */
|
|
||||||
/* This sets HW flags in case mbedtls_md5_update has not been called yet */
|
|
||||||
if (HAL_HASH_MD5_Accumulate(&ctx->hhash_md5, ctx->sbuf, ctx->sbuf_len) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_zeroize(ctx->sbuf, ST_MD5_BLOCK_SIZE);
|
|
||||||
ctx->sbuf_len = 0;
|
|
||||||
__HAL_HASH_START_DIGEST();
|
|
||||||
|
|
||||||
if (HAL_HASH_MD5_Finish(&ctx->hhash_md5, output, 10)) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (st_md5_save_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_MD5_ALT */
|
|
||||||
#endif /* MBEDTLS_MD5_C */
|
|
|
@ -0,0 +1,279 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements STMicroelectronics MD5 with HW services based on API
|
||||||
|
* from mbed TLS
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The MD5 algorithm was designed by Ron Rivest in 1991.
|
||||||
|
*
|
||||||
|
* http://www.ietf.org/rfc/rfc1321.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "mbedtls/md5.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_MD5_C)
|
||||||
|
#if defined(MBEDTLS_MD5_ALT)
|
||||||
|
#include <string.h>
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
|
#include "platform/PlatformMutex.h"
|
||||||
|
#include "platform/SingletonPtr.h"
|
||||||
|
|
||||||
|
static SingletonPtr<PlatformMutex> md5_mutex;
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
#define MD5_VALIDATE_RET(cond) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MD5_BAD_INPUT_DATA )
|
||||||
|
#define MD5_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
void mbedtls_md5_init(mbedtls_md5_context *ctx)
|
||||||
|
{
|
||||||
|
MD5_VALIDATE(ctx != NULL);
|
||||||
|
|
||||||
|
md5_mutex->lock();
|
||||||
|
hash_context_count++;
|
||||||
|
md5_mutex->unlock();
|
||||||
|
|
||||||
|
hash_zeroize(ctx, sizeof(mbedtls_md5_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_md5_free(mbedtls_md5_context *ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
md5_mutex->lock();
|
||||||
|
if (hash_context_count > 0) {
|
||||||
|
hash_context_count--;
|
||||||
|
|
||||||
|
/* Shut down HASH on last context */
|
||||||
|
if (hash_context_count == 0) {
|
||||||
|
HAL_HASH_DeInit(&ctx->hhash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
md5_mutex->unlock();
|
||||||
|
|
||||||
|
hash_zeroize(ctx, sizeof(mbedtls_md5_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_md5_clone(mbedtls_md5_context *dst,
|
||||||
|
const mbedtls_md5_context *src)
|
||||||
|
{
|
||||||
|
MD5_VALIDATE(dst != NULL);
|
||||||
|
MD5_VALIDATE(src != NULL);
|
||||||
|
|
||||||
|
*dst = *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_md5_starts_ret(mbedtls_md5_context *ctx)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
MD5_VALIDATE_RET(ctx != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* HASH Configuration */
|
||||||
|
if (HAL_HASH_DeInit(&ctx->hhash) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
|
||||||
|
if (HAL_HASH_Init(&ctx->hhash) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_internal_md5_process(mbedtls_md5_context *ctx,
|
||||||
|
const unsigned char data[ST_MD5_BLOCK_SIZE])
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
MD5_VALIDATE_RET(ctx != NULL);
|
||||||
|
MD5_VALIDATE_RET((const unsigned char *)data != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
if (HAL_HASH_MD5_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *) data,
|
||||||
|
ST_MD5_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_md5_update_ret(mbedtls_md5_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
size_t ilen)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
size_t currentlen = ilen;
|
||||||
|
|
||||||
|
MD5_VALIDATE_RET(ctx != NULL);
|
||||||
|
MD5_VALIDATE_RET(ilen == 0 || input != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
if (currentlen < (ST_MD5_BLOCK_SIZE - ctx->sbuf_len)) {
|
||||||
|
/* only store input data in context buffer */
|
||||||
|
memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
|
||||||
|
ctx->sbuf_len += currentlen;
|
||||||
|
} else {
|
||||||
|
/* fill context buffer until ST_MD5_BLOCK_SIZE bytes, and process it */
|
||||||
|
memcpy(ctx->sbuf + ctx->sbuf_len,
|
||||||
|
input,
|
||||||
|
(ST_MD5_BLOCK_SIZE - ctx->sbuf_len));
|
||||||
|
currentlen -= (ST_MD5_BLOCK_SIZE - ctx->sbuf_len);
|
||||||
|
|
||||||
|
if (HAL_HASH_MD5_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(ctx->sbuf),
|
||||||
|
ST_MD5_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process following input data
|
||||||
|
with size multiple of ST_MD5_BLOCK_SIZE bytes */
|
||||||
|
size_t iter = currentlen / ST_MD5_BLOCK_SIZE;
|
||||||
|
if (iter != 0) {
|
||||||
|
if (HAL_HASH_MD5_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(input + ST_MD5_BLOCK_SIZE - ctx->sbuf_len),
|
||||||
|
(iter * ST_MD5_BLOCK_SIZE)) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store only the remaining input data
|
||||||
|
up to (ST_MD5_BLOCK_SIZE - 1) bytes */
|
||||||
|
ctx->sbuf_len = currentlen % ST_MD5_BLOCK_SIZE;
|
||||||
|
if (ctx->sbuf_len != 0) {
|
||||||
|
memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_md5_finish_ret(mbedtls_md5_context *ctx, unsigned char output[32])
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
MD5_VALIDATE_RET(ctx != NULL);
|
||||||
|
MD5_VALIDATE_RET((unsigned char *)output != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
/* Last accumulation for pending bytes in sbuf_len,
|
||||||
|
then trig processing and get digest */
|
||||||
|
if (HAL_HASH_MD5_Accmlt_End(&ctx->hhash,
|
||||||
|
ctx->sbuf,
|
||||||
|
ctx->sbuf_len,
|
||||||
|
output,
|
||||||
|
ST_HASH_TIMEOUT) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->sbuf_len = 0;
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_MD5_ALT*/
|
||||||
|
#endif /* MBEDTLS_MD5_C */
|
|
@ -1,9 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* \file md5_alt.h
|
* \file md5.h
|
||||||
*
|
*
|
||||||
* \brief MD5 hw acceleration (hash function)
|
* \brief MD5 message digest algorithm (hash function)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
* \warning MD5 is considered a weak message digest and its use constitutes a
|
||||||
|
* security risk. We recommend considering stronger message
|
||||||
|
* digests instead.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -18,172 +24,40 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
|
* This file implements STMicroelectronics MD5 API with HW services based
|
||||||
|
* on mbed TLS API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_MD5_ALT_H
|
#ifndef MBEDTLS_MD5_ALT_H
|
||||||
#define MBEDTLS_MD5_ALT_H
|
#define MBEDTLS_MD5_ALT_H
|
||||||
|
|
||||||
#if defined(MBEDTLS_MD5_ALT)
|
#if defined (MBEDTLS_MD5_ALT)
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "hash_stm32.h"
|
||||||
|
|
||||||
#include "cmsis.h"
|
#ifndef MBEDTLS_ERR_MD5_BAD_INPUT_DATA
|
||||||
#include <string.h>
|
#define MBEDTLS_ERR_MD5_BAD_INPUT_DATA -0x00AF
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ST_MD5_BLOCK_SIZE ((size_t)(64)) // HW handles 512 bits, ie 64 bytes
|
#define ST_MD5_BLOCK_SIZE ((size_t) 64) /*!< HW handles 512 bits, ie 64 bytes */
|
||||||
#define ST_MD5_TIMEOUT ((uint32_t) 3)
|
#define ST_MD5_NB_HASH_REG ((uint32_t)57) /*!< Number of HASH HW context Registers:
|
||||||
|
CR + STR + IMR + CSR[54] */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief MD5 context structure
|
* \brief MD5 context structure
|
||||||
* \note HAL_HASH_MD5_Accumulate will accumulate 512 bits packets, unless it is the last call to the function
|
*
|
||||||
* A ST_MD5_BLOCK_SIZE bytes buffer is used to save values and handle the processing
|
* STMicroelectronics edition
|
||||||
* ST_MD5_BLOCK_SIZE bytes per ST_MD5_BLOCK_SIZE bytes
|
|
||||||
* If MD5_finish is called and sbuf_len>0, the remaining bytes are accumulated prior to the call to HAL_HASH_MD5_Finish
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct mbedtls_md5_context {
|
||||||
HASH_HandleTypeDef hhash_md5;/*!< ST HAL HASH struct */
|
HASH_HandleTypeDef hhash; /*!< Handle of HASH HAL */
|
||||||
unsigned char sbuf[ST_MD5_BLOCK_SIZE]; /*!< MBEDTLS_MD5_BLOCK_SIZE buffer to store values so that algorithm is caled once the buffer is filled */
|
uint8_t sbuf[ST_MD5_BLOCK_SIZE]; /*!< Buffer to store input data until ST_MD5_BLOCK_SIZE
|
||||||
unsigned char sbuf_len; /*!< number of bytes to be processed in sbuf */
|
is reached, or until last input data is reached */
|
||||||
uint32_t ctx_save_cr;
|
uint8_t sbuf_len; /*!< Number of bytes stored in sbuf */
|
||||||
uint32_t ctx_save_str;
|
uint32_t ctx_save_regs[ST_MD5_NB_HASH_REG];
|
||||||
uint32_t ctx_save_csr[38];
|
|
||||||
}
|
}
|
||||||
mbedtls_md5_context;
|
mbedtls_md5_context;
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Initialize MD5 context
|
|
||||||
*
|
|
||||||
* \param ctx MD5 context to be initialized
|
|
||||||
*/
|
|
||||||
void mbedtls_md5_init(mbedtls_md5_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clear MD5 context
|
|
||||||
*
|
|
||||||
* \param ctx MD5 context to be cleared
|
|
||||||
*/
|
|
||||||
void mbedtls_md5_free(mbedtls_md5_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clone (the state of) an MD5 context
|
|
||||||
*
|
|
||||||
* \param dst The destination context
|
|
||||||
* \param src The context to be cloned
|
|
||||||
*/
|
|
||||||
void mbedtls_md5_clone(mbedtls_md5_context *dst,
|
|
||||||
const mbedtls_md5_context *src);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief MD5 context setup
|
|
||||||
*
|
|
||||||
* \param ctx context to be initialized
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_md5_starts_ret(mbedtls_md5_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief MD5 process buffer
|
|
||||||
*
|
|
||||||
* \param ctx MD5 context
|
|
||||||
* \param input buffer holding the data
|
|
||||||
* \param ilen length of the input data
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_md5_update_ret(mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief MD5 final digest
|
|
||||||
*
|
|
||||||
* \param ctx MD5 context
|
|
||||||
* \param output MD5 checksum result
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_md5_finish_ret(mbedtls_md5_context *ctx, unsigned char output[16]);
|
|
||||||
|
|
||||||
/* Internal use */
|
|
||||||
int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, const unsigned char data[ST_MD5_BLOCK_SIZE]);
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
|
||||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
|
||||||
#else
|
|
||||||
#define MBEDTLS_DEPRECATED
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* \brief MD5 context setup
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_md5_starts_ret() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx context to be initialized
|
|
||||||
*
|
|
||||||
* \warning MD5 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_starts(mbedtls_md5_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief MD5 process buffer
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_md5_update_ret() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx MD5 context
|
|
||||||
* \param input buffer holding the data
|
|
||||||
* \param ilen length of the input data
|
|
||||||
*
|
|
||||||
* \warning MD5 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_update(mbedtls_md5_context *ctx,
|
|
||||||
const unsigned char *input,
|
|
||||||
size_t ilen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief MD5 final digest
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_md5_finish_ret() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx MD5 context
|
|
||||||
* \param output MD5 checksum result
|
|
||||||
*
|
|
||||||
* \warning MD5 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_finish(mbedtls_md5_context *ctx,
|
|
||||||
unsigned char output[16]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief MD5 process data block (internal use only)
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_internal_md5_process() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx MD5 context
|
|
||||||
* \param data buffer holding one block of data
|
|
||||||
*
|
|
||||||
* \warning MD5 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_md5_process(mbedtls_md5_context *ctx,
|
|
||||||
const unsigned char data[64]);
|
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_MD5_ALT */
|
#endif /* MBEDTLS_MD5_ALT */
|
||||||
|
|
||||||
#endif /* md5_alt.h */
|
#endif /* MBEDTLS_MD5_ALT_H */
|
||||||
|
|
|
@ -1,207 +0,0 @@
|
||||||
/*
|
|
||||||
* sha1_alt.c for SHA1 HASH
|
|
||||||
*******************************************************************************
|
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "mbedtls/sha1.h"
|
|
||||||
#if defined(MBEDTLS_SHA1_ALT)
|
|
||||||
#include "mbedtls/platform.h"
|
|
||||||
|
|
||||||
/* Implementation that should never be optimized out by the compiler */
|
|
||||||
static void mbedtls_zeroize(void *v, size_t n)
|
|
||||||
{
|
|
||||||
volatile unsigned char *p = (unsigned char *)v;
|
|
||||||
while (n--) {
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int st_sha1_restore_hw_context(mbedtls_sha1_context *ctx)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t tickstart;
|
|
||||||
/* allow multi-instance of HASH use: save context for HASH HW module CR */
|
|
||||||
/* Check that there is no HASH activity on going */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_SHA1_TIMEOUT) {
|
|
||||||
return 0; // timeout: HASH processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HASH->STR = ctx->ctx_save_str;
|
|
||||||
HASH->CR = (ctx->ctx_save_cr | HASH_CR_INIT);
|
|
||||||
for (i = 0; i < 38; i++) {
|
|
||||||
HASH->CSR[i] = ctx->ctx_save_csr[i];
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int st_sha1_save_hw_context(mbedtls_sha1_context *ctx)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t tickstart;
|
|
||||||
/* Check that there is no HASH activity on going */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_SHA1_TIMEOUT) {
|
|
||||||
return 0; // timeout: HASH processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* allow multi-instance of HASH use: restore context for HASH HW module CR */
|
|
||||||
ctx->ctx_save_cr = HASH->CR;
|
|
||||||
ctx->ctx_save_str = HASH->STR;
|
|
||||||
for (i = 0; i < 38; i++) {
|
|
||||||
ctx->ctx_save_csr[i] = HASH->CSR[i];
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
|
|
||||||
{
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
|
|
||||||
|
|
||||||
/* Enable HASH clock */
|
|
||||||
__HAL_RCC_HASH_CLK_ENABLE();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
|
|
||||||
{
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
|
|
||||||
const mbedtls_sha1_context *src)
|
|
||||||
{
|
|
||||||
*dst = *src;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
|
|
||||||
{
|
|
||||||
/* Deinitializes the HASH peripheral */
|
|
||||||
if (HAL_HASH_DeInit(&ctx->hhash_sha1) == HAL_ERROR) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* HASH Configuration */
|
|
||||||
ctx->hhash_sha1.Init.DataType = HASH_DATATYPE_8B;
|
|
||||||
/* clear CR ALGO value */
|
|
||||||
HASH->CR &= ~HASH_CR_ALGO_Msk;
|
|
||||||
if (HAL_HASH_Init(&ctx->hhash_sha1) == HAL_ERROR) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (st_sha1_save_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[ST_SHA1_BLOCK_SIZE])
|
|
||||||
{
|
|
||||||
if (st_sha1_restore_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *) data, ST_SHA1_BLOCK_SIZE) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st_sha1_save_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
size_t currentlen = ilen;
|
|
||||||
if (st_sha1_restore_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store mechanism to accumulate ST_SHA1_BLOCK_SIZE bytes (512 bits) in the HW
|
|
||||||
if (currentlen == 0) { // only change HW status is size if 0
|
|
||||||
if (ctx->hhash_sha1.Phase == HAL_HASH_PHASE_READY) {
|
|
||||||
/* Select the SHA1 mode and reset the HASH processor core, so that the HASH will be ready to compute
|
|
||||||
the message digest of a new message */
|
|
||||||
HASH->CR |= HASH_ALGOSELECTION_SHA1 | HASH_CR_INIT;
|
|
||||||
}
|
|
||||||
ctx->hhash_sha1.Phase = HAL_HASH_PHASE_PROCESS;
|
|
||||||
} else if (currentlen < (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len)) {
|
|
||||||
// only buffurize
|
|
||||||
memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
|
|
||||||
ctx->sbuf_len += currentlen;
|
|
||||||
} else {
|
|
||||||
// fill buffer and process it
|
|
||||||
memcpy(ctx->sbuf + ctx->sbuf_len, input, (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len));
|
|
||||||
currentlen -= (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len);
|
|
||||||
err = mbedtls_internal_sha1_process(ctx, ctx->sbuf);
|
|
||||||
if (err != 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
// Process every input as long as it is %64 bytes, ie 512 bits
|
|
||||||
size_t iter = currentlen / ST_SHA1_BLOCK_SIZE;
|
|
||||||
if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, (uint8_t *)(input + ST_SHA1_BLOCK_SIZE - ctx->sbuf_len), (iter * ST_SHA1_BLOCK_SIZE)) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
// sbuf is completely accumulated, now copy up to 63 remaining bytes
|
|
||||||
ctx->sbuf_len = currentlen % ST_SHA1_BLOCK_SIZE;
|
|
||||||
if (ctx->sbuf_len != 0) {
|
|
||||||
memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (st_sha1_save_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20])
|
|
||||||
{
|
|
||||||
if (st_sha1_restore_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last accumulation for extra bytes in sbuf_len */
|
|
||||||
/* This allows the HW flags to be in place in case mbedtls_sha256_update has not been called yet */
|
|
||||||
if (HAL_HASH_SHA1_Accumulate(&ctx->hhash_sha1, ctx->sbuf, ctx->sbuf_len) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
mbedtls_zeroize(ctx->sbuf, ST_SHA1_BLOCK_SIZE);
|
|
||||||
ctx->sbuf_len = 0;
|
|
||||||
__HAL_HASH_START_DIGEST();
|
|
||||||
|
|
||||||
if (HAL_HASH_SHA1_Finish(&ctx->hhash_sha1, output, 10) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (st_sha1_save_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*MBEDTLS_SHA1_ALT*/
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements STMicroelectronics SHA1 with HW services based on API
|
||||||
|
* from mbed TLS
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The SHA-1 standard was published by NIST in 1993.
|
||||||
|
*
|
||||||
|
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "mbedtls/sha1.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA1_C)
|
||||||
|
#if defined(MBEDTLS_SHA1_ALT)
|
||||||
|
#include <string.h>
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
|
#include "platform/PlatformMutex.h"
|
||||||
|
#include "platform/SingletonPtr.h"
|
||||||
|
|
||||||
|
static SingletonPtr<PlatformMutex> sha1_mutex;
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
#define SHA1_VALIDATE_RET(cond) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA )
|
||||||
|
#define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
|
||||||
|
{
|
||||||
|
SHA1_VALIDATE(ctx != NULL);
|
||||||
|
|
||||||
|
sha1_mutex->lock();
|
||||||
|
hash_context_count++;
|
||||||
|
sha1_mutex->unlock();
|
||||||
|
|
||||||
|
hash_zeroize(ctx, sizeof(mbedtls_sha1_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1_mutex->lock();
|
||||||
|
if (hash_context_count > 0) {
|
||||||
|
hash_context_count--;
|
||||||
|
|
||||||
|
/* Shut down HASH on last context */
|
||||||
|
if (hash_context_count == 0) {
|
||||||
|
HAL_HASH_DeInit(&ctx->hhash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sha1_mutex->unlock();
|
||||||
|
|
||||||
|
hash_zeroize(ctx, sizeof(mbedtls_sha1_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
|
||||||
|
const mbedtls_sha1_context *src)
|
||||||
|
{
|
||||||
|
SHA1_VALIDATE(dst != NULL);
|
||||||
|
SHA1_VALIDATE(src != NULL);
|
||||||
|
|
||||||
|
*dst = *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
SHA1_VALIDATE_RET(ctx != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* HASH Configuration */
|
||||||
|
if (HAL_HASH_DeInit(&ctx->hhash) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
|
||||||
|
if (HAL_HASH_Init(&ctx->hhash) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx,
|
||||||
|
const unsigned char data[ST_SHA1_BLOCK_SIZE])
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
SHA1_VALIDATE_RET(ctx != NULL);
|
||||||
|
SHA1_VALIDATE_RET((const unsigned char *)data != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
if (HAL_HASH_SHA1_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *) data,
|
||||||
|
ST_SHA1_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
size_t ilen)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
size_t currentlen = ilen;
|
||||||
|
|
||||||
|
SHA1_VALIDATE_RET(ctx != NULL);
|
||||||
|
SHA1_VALIDATE_RET(ilen == 0 || input != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
if (currentlen < (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len)) {
|
||||||
|
/* only store input data in context buffer */
|
||||||
|
memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
|
||||||
|
ctx->sbuf_len += currentlen;
|
||||||
|
} else {
|
||||||
|
/* fill context buffer until ST_SHA1_BLOCK_SIZE bytes, and process it */
|
||||||
|
memcpy(ctx->sbuf + ctx->sbuf_len,
|
||||||
|
input,
|
||||||
|
(ST_SHA1_BLOCK_SIZE - ctx->sbuf_len));
|
||||||
|
currentlen -= (ST_SHA1_BLOCK_SIZE - ctx->sbuf_len);
|
||||||
|
|
||||||
|
if (HAL_HASH_SHA1_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(ctx->sbuf),
|
||||||
|
ST_SHA1_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process following input data
|
||||||
|
with size multiple of ST_SHA1_BLOCK_SIZE bytes */
|
||||||
|
size_t iter = currentlen / ST_SHA1_BLOCK_SIZE;
|
||||||
|
if (iter != 0) {
|
||||||
|
if (HAL_HASH_SHA1_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(input + ST_SHA1_BLOCK_SIZE - ctx->sbuf_len),
|
||||||
|
(iter * ST_SHA1_BLOCK_SIZE)) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store only the remaining input data
|
||||||
|
up to (ST_SHA1_BLOCK_SIZE - 1) bytes */
|
||||||
|
ctx->sbuf_len = currentlen % ST_SHA1_BLOCK_SIZE;
|
||||||
|
if (ctx->sbuf_len != 0) {
|
||||||
|
memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx,
|
||||||
|
unsigned char output[32])
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
SHA1_VALIDATE_RET(ctx != NULL);
|
||||||
|
SHA1_VALIDATE_RET((unsigned char *)output != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
/* Last accumulation for pending bytes in sbuf_len,
|
||||||
|
then trig processing and get digest */
|
||||||
|
if (HAL_HASH_SHA1_Accmlt_End(&ctx->hhash,
|
||||||
|
ctx->sbuf,
|
||||||
|
ctx->sbuf_len,
|
||||||
|
output,
|
||||||
|
ST_HASH_TIMEOUT) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->sbuf_len = 0;
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SHA1_ALT*/
|
||||||
|
#endif /* MBEDTLS_SHA1_C */
|
|
@ -1,9 +1,18 @@
|
||||||
|
/**
|
||||||
|
* \file sha1.h
|
||||||
|
*
|
||||||
|
* \brief This file contains SHA-1 definitions and functions.
|
||||||
|
*
|
||||||
|
* The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in
|
||||||
|
* <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
|
||||||
|
*
|
||||||
|
* \warning SHA-1 is considered a weak message digest and its use constitutes
|
||||||
|
* a security risk. We recommend considering stronger message
|
||||||
|
* digests instead.
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
* \file sha1_alt.h
|
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||||
*
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
* \brief SHA1 hw acceleration (hash function)
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017, STMicroelectronics
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -18,172 +27,34 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
|
* This file implements STMicroelectronics SHA1 API with HW services based
|
||||||
|
* on mbed TLS API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_SHA1_ALT_H
|
#ifndef MBEDTLS_SHA1_ALT_H
|
||||||
#define MBEDTLS_SHA1_ALT_H
|
#define MBEDTLS_SHA1_ALT_H
|
||||||
|
|
||||||
#if defined (MBEDTLS_SHA1_ALT)
|
#if defined (MBEDTLS_SHA1_ALT)
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "hash_stm32.h"
|
||||||
|
|
||||||
|
#define ST_SHA1_BLOCK_SIZE ((size_t) 64) /*!< HW handles 512 bits, ie 64 bytes */
|
||||||
|
#define ST_SHA1_NB_HASH_REG ((uint32_t)57) /*!< Number of HASH HW context Registers:
|
||||||
|
CR + STR + IMR + CSR[54] */
|
||||||
|
|
||||||
#include "cmsis.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ST_SHA1_BLOCK_SIZE ((size_t) 64) // HW handles 512 bits, ie 64 bytes
|
|
||||||
#define ST_SHA1_TIMEOUT ((uint32_t) 3)
|
|
||||||
/**
|
/**
|
||||||
* \brief SHA-1 context structure
|
* \brief SHA-1 context structure
|
||||||
* \note HAL_HASH_SHA1_Accumulate will accumulate 512 bits packets, unless it is the last call to the function
|
|
||||||
* A ST_SHA1_BLOCK_SIZE bytes buffer is used to save values and handle the processing
|
|
||||||
* multiples of ST_SHA1_BLOCK_SIZE bytes
|
|
||||||
* If SHA1_finish is called and sbuf_len>0, the remaining bytes are accumulated prior to the call to HAL_HASH_SHA1_Finish
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct mbedtls_sha1_context {
|
||||||
unsigned char sbuf[ST_SHA1_BLOCK_SIZE]; /*!< MBEDTLS_SHA1_BLOCK_SIZE buffer to store values so that algorithm is caled once the buffer is filled */
|
HASH_HandleTypeDef hhash; /*!< Handle of HASH HAL */
|
||||||
unsigned char sbuf_len; /*!< number of bytes remaining in sbuf to be processed */
|
uint8_t sbuf[ST_SHA1_BLOCK_SIZE]; /*!< Buffer to store input data until ST_SHA1_BLOCK_SIZE
|
||||||
HASH_HandleTypeDef hhash_sha1; /*!< ST HAL HASH struct */
|
is reached, or until last input data is reached */
|
||||||
uint32_t ctx_save_cr;
|
uint8_t sbuf_len; /*!< Number of bytes stored in sbuf */
|
||||||
uint32_t ctx_save_str;
|
uint32_t ctx_save_regs[ST_SHA1_NB_HASH_REG];
|
||||||
uint32_t ctx_save_csr[38];
|
|
||||||
}
|
}
|
||||||
mbedtls_sha1_context;
|
mbedtls_sha1_context;
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Initialize SHA-1 context
|
|
||||||
*
|
|
||||||
* \param ctx SHA-1 context to be initialized
|
|
||||||
*/
|
|
||||||
void mbedtls_sha1_init(mbedtls_sha1_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clear SHA-1 context
|
|
||||||
*
|
|
||||||
* \param ctx SHA-1 context to be cleared
|
|
||||||
*/
|
|
||||||
void mbedtls_sha1_free(mbedtls_sha1_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clone (the state of) a SHA-1 context
|
|
||||||
*
|
|
||||||
* \param dst The destination context
|
|
||||||
* \param src The context to be cloned
|
|
||||||
*/
|
|
||||||
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
|
|
||||||
const mbedtls_sha1_context *src);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-1 context setup
|
|
||||||
*
|
|
||||||
* \param ctx context to be initialized
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_sha1_starts_ret(mbedtls_sha1_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-1 process buffer
|
|
||||||
*
|
|
||||||
* \param ctx SHA-1 context
|
|
||||||
* \param input buffer holding the data
|
|
||||||
* \param ilen length of the input data
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_sha1_update_ret(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-1 final digest
|
|
||||||
*
|
|
||||||
* \param ctx SHA-1 context
|
|
||||||
* \param output SHA-1 checksum result
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_sha1_finish_ret(mbedtls_sha1_context *ctx, unsigned char output[20]);
|
|
||||||
|
|
||||||
/* Internal use */
|
|
||||||
int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[ST_SHA1_BLOCK_SIZE]);
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
|
||||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
|
||||||
#else
|
|
||||||
#define MBEDTLS_DEPRECATED
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* \brief SHA-1 context setup
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-1 context to be initialized.
|
|
||||||
*
|
|
||||||
* \warning SHA-1 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha1_starts(mbedtls_sha1_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-1 process buffer
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-1 context.
|
|
||||||
* \param input The buffer holding the input data.
|
|
||||||
* \param ilen The length of the input data.
|
|
||||||
*
|
|
||||||
* \warning SHA-1 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha1_update(mbedtls_sha1_context *ctx,
|
|
||||||
const unsigned char *input,
|
|
||||||
size_t ilen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-1 final digest
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-1 context.
|
|
||||||
* \param output The SHA-1 checksum result.
|
|
||||||
*
|
|
||||||
* \warning SHA-1 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha1_finish(mbedtls_sha1_context *ctx,
|
|
||||||
unsigned char output[20]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-1 process data block (internal use only)
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-1 context.
|
|
||||||
* \param data The data block being processed.
|
|
||||||
*
|
|
||||||
* \warning SHA-1 is considered a weak message digest and its use
|
|
||||||
* constitutes a security risk. We recommend considering
|
|
||||||
* stronger message digests instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha1_process(mbedtls_sha1_context *ctx,
|
|
||||||
const unsigned char data[64]);
|
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_SHA1_ALT */
|
#endif /* MBEDTLS_SHA1_ALT */
|
||||||
|
|
||||||
#endif /* sha1_alt.h */
|
#endif /* MBEDTLS_SHA1_ALT_H */
|
||||||
|
|
|
@ -1,239 +0,0 @@
|
||||||
/*
|
|
||||||
* sha256_alt.c for SHA256 HASH
|
|
||||||
*******************************************************************************
|
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "mbedtls/sha256.h"
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_SHA256_ALT)
|
|
||||||
#include "mbedtls/platform.h"
|
|
||||||
|
|
||||||
/* Implementation that should never be optimized out by the compiler */
|
|
||||||
static void mbedtls_zeroize(void *v, size_t n)
|
|
||||||
{
|
|
||||||
volatile unsigned char *p = v;
|
|
||||||
while (n--) {
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int st_sha256_restore_hw_context(mbedtls_sha256_context *ctx)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t tickstart;
|
|
||||||
/* allow multi-instance of HASH use: save context for HASH HW module CR */
|
|
||||||
/* Check that there is no HASH activity on going */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_SHA256_TIMEOUT) {
|
|
||||||
return 0; // timeout: HASH processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HASH->STR = ctx->ctx_save_str;
|
|
||||||
HASH->CR = (ctx->ctx_save_cr | HASH_CR_INIT);
|
|
||||||
for (i = 0; i < 38; i++) {
|
|
||||||
HASH->CSR[i] = ctx->ctx_save_csr[i];
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int st_sha256_save_hw_context(mbedtls_sha256_context *ctx)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t tickstart;
|
|
||||||
/* Check that there is no HASH activity on going */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
|
|
||||||
if ((HAL_GetTick() - tickstart) > ST_SHA256_TIMEOUT) {
|
|
||||||
return 0; // timeout: HASH processor is busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* allow multi-instance of HASH use: restore context for HASH HW module CR */
|
|
||||||
ctx->ctx_save_cr = HASH->CR;
|
|
||||||
ctx->ctx_save_str = HASH->STR;
|
|
||||||
for (i = 0; i < 38; i++) {
|
|
||||||
ctx->ctx_save_csr[i] = HASH->CSR[i];
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
|
|
||||||
{
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
|
|
||||||
|
|
||||||
/* Enable HASH clock */
|
|
||||||
__HAL_RCC_HASH_CLK_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
|
|
||||||
{
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
|
|
||||||
const mbedtls_sha256_context *src)
|
|
||||||
{
|
|
||||||
*dst = *src;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
|
|
||||||
{
|
|
||||||
/* HASH IP initialization */
|
|
||||||
if (HAL_HASH_DeInit(&ctx->hhash_sha256) == HAL_ERROR) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->is224 = is224;
|
|
||||||
/* HASH Configuration */
|
|
||||||
ctx->hhash_sha256.Init.DataType = HASH_DATATYPE_8B;
|
|
||||||
/* clear CR ALGO value */
|
|
||||||
HASH->CR &= ~HASH_CR_ALGO_Msk;
|
|
||||||
if (HAL_HASH_Init(&ctx->hhash_sha256) == HAL_ERROR) {
|
|
||||||
// error found to be returned
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (st_sha256_save_hw_context(ctx) != 1) {
|
|
||||||
// return HASH_BUSY timeout Error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[ST_SHA256_BLOCK_SIZE])
|
|
||||||
{
|
|
||||||
if (st_sha256_restore_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
if (ctx->is224 == 0) {
|
|
||||||
if (HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *) data, ST_SHA256_BLOCK_SIZE) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (HAL_HASHEx_SHA224_Accumulate(&ctx->hhash_sha256, (uint8_t *) data, ST_SHA256_BLOCK_SIZE) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st_sha256_save_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
size_t currentlen = ilen;
|
|
||||||
if (st_sha256_restore_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store mechanism to accumulate ST_SHA256_BLOCK_SIZE bytes (512 bits) in the HW
|
|
||||||
if (currentlen == 0) { // only change HW status is size if 0
|
|
||||||
if (ctx->hhash_sha256.Phase == HAL_HASH_PHASE_READY) {
|
|
||||||
/* Select the SHA256 or SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
|
|
||||||
the message digest of a new message */
|
|
||||||
if (ctx->is224 == 0) {
|
|
||||||
HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
|
|
||||||
} else {
|
|
||||||
HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx->hhash_sha256.Phase = HAL_HASH_PHASE_PROCESS;
|
|
||||||
} else if (currentlen < (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len)) {
|
|
||||||
// only buffurize
|
|
||||||
memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
|
|
||||||
ctx->sbuf_len += currentlen;
|
|
||||||
} else {
|
|
||||||
// fill buffer and process it
|
|
||||||
memcpy(ctx->sbuf + ctx->sbuf_len, input, (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len));
|
|
||||||
currentlen -= (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len);
|
|
||||||
err = mbedtls_internal_sha256_process(ctx, ctx->sbuf);
|
|
||||||
if (err != 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
// Process every input as long as it is %64 bytes, ie 512 bits
|
|
||||||
size_t iter = currentlen / ST_SHA256_BLOCK_SIZE;
|
|
||||||
if (iter != 0) {
|
|
||||||
if (ctx->is224 == 0) {
|
|
||||||
if (HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len), (iter * ST_SHA256_BLOCK_SIZE)) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (HAL_HASHEx_SHA224_Accumulate(&ctx->hhash_sha256, (uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len), (iter * ST_SHA256_BLOCK_SIZE)) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sbuf is completely accumulated, now copy up to 63 remaining bytes
|
|
||||||
ctx->sbuf_len = currentlen % ST_SHA256_BLOCK_SIZE;
|
|
||||||
if (ctx->sbuf_len != 0) {
|
|
||||||
memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (st_sha256_save_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32])
|
|
||||||
{
|
|
||||||
if (st_sha256_restore_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
/* Last accumulation for extra bytes in sbuf_len */
|
|
||||||
/* This allows the HW flags to be in place in case mbedtls_sha256_update has not been called yet */
|
|
||||||
if (ctx->is224 == 0) {
|
|
||||||
if (HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, ctx->sbuf, ctx->sbuf_len) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (HAL_HASHEx_SHA224_Accumulate(&ctx->hhash_sha256, ctx->sbuf, ctx->sbuf_len) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_zeroize(ctx->sbuf, ST_SHA256_BLOCK_SIZE);
|
|
||||||
ctx->sbuf_len = 0;
|
|
||||||
__HAL_HASH_START_DIGEST();
|
|
||||||
|
|
||||||
if (ctx->is224 == 0) {
|
|
||||||
if (HAL_HASHEx_SHA256_Finish(&ctx->hhash_sha256, output, 10) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (HAL_HASHEx_SHA224_Finish(&ctx->hhash_sha256, output, 10) != 0) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (st_sha256_save_hw_context(ctx) != 1) {
|
|
||||||
// Return HASH_BUSY timeout error here
|
|
||||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*MBEDTLS_SHA256_ALT*/
|
|
|
@ -0,0 +1,322 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements STMicroelectronics SHA256 with HW services based on API
|
||||||
|
* from mbed TLS
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||||
|
*
|
||||||
|
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "mbedtls/sha256.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SHA256_C)
|
||||||
|
#if defined(MBEDTLS_SHA256_ALT)
|
||||||
|
#include <string.h>
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#include "mbedtls/platform_util.h"
|
||||||
|
|
||||||
|
#include "platform/PlatformMutex.h"
|
||||||
|
#include "platform/SingletonPtr.h"
|
||||||
|
|
||||||
|
static SingletonPtr<PlatformMutex> sha256_mutex;
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
#define SHA256_VALIDATE_RET(cond) \
|
||||||
|
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
|
||||||
|
#define SHA256_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
|
||||||
|
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
|
||||||
|
{
|
||||||
|
SHA256_VALIDATE(ctx != NULL);
|
||||||
|
|
||||||
|
sha256_mutex->lock();
|
||||||
|
hash_context_count++;
|
||||||
|
sha256_mutex->unlock();
|
||||||
|
|
||||||
|
hash_zeroize(ctx, sizeof(mbedtls_sha256_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
|
||||||
|
{
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sha256_mutex->lock();
|
||||||
|
if (hash_context_count > 0) {
|
||||||
|
hash_context_count--;
|
||||||
|
|
||||||
|
/* Shut down HASH on last context */
|
||||||
|
if (hash_context_count == 0) {
|
||||||
|
HAL_HASH_DeInit(&ctx->hhash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sha256_mutex->unlock();
|
||||||
|
|
||||||
|
hash_zeroize(ctx, sizeof(mbedtls_sha256_context));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
|
||||||
|
const mbedtls_sha256_context *src)
|
||||||
|
{
|
||||||
|
SHA256_VALIDATE(dst != NULL);
|
||||||
|
SHA256_VALIDATE(src != NULL);
|
||||||
|
|
||||||
|
*dst = *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
SHA256_VALIDATE_RET(ctx != NULL);
|
||||||
|
SHA256_VALIDATE_RET(is224 == 0 || is224 == 1);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* HASH Configuration */
|
||||||
|
if (HAL_HASH_DeInit(&ctx->hhash) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
ctx->hhash.Init.DataType = HASH_DATATYPE_8B;
|
||||||
|
if (HAL_HASH_Init(&ctx->hhash) != HAL_OK) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->is224 = is224;
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx,
|
||||||
|
const unsigned char data[ST_SHA256_BLOCK_SIZE])
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
SHA256_VALIDATE_RET(ctx != NULL);
|
||||||
|
SHA256_VALIDATE_RET((const unsigned char *)data != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
if (ctx->is224 == 0) {
|
||||||
|
if (HAL_HASHEx_SHA256_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *) data,
|
||||||
|
ST_SHA256_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (HAL_HASHEx_SHA224_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *) data,
|
||||||
|
ST_SHA256_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
size_t ilen)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
size_t currentlen = ilen;
|
||||||
|
|
||||||
|
SHA256_VALIDATE_RET(ctx != NULL);
|
||||||
|
SHA256_VALIDATE_RET(ilen == 0 || input != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
if (currentlen < (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len)) {
|
||||||
|
/* only store input data in context buffer */
|
||||||
|
memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
|
||||||
|
ctx->sbuf_len += currentlen;
|
||||||
|
} else {
|
||||||
|
/* fill context buffer until ST_SHA256_BLOCK_SIZE bytes, and process it */
|
||||||
|
memcpy(ctx->sbuf + ctx->sbuf_len,
|
||||||
|
input,
|
||||||
|
(ST_SHA256_BLOCK_SIZE - ctx->sbuf_len));
|
||||||
|
currentlen -= (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len);
|
||||||
|
|
||||||
|
if (ctx->is224 == 0) {
|
||||||
|
if (HAL_HASHEx_SHA256_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(ctx->sbuf),
|
||||||
|
ST_SHA256_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (HAL_HASHEx_SHA224_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(ctx->sbuf),
|
||||||
|
ST_SHA256_BLOCK_SIZE) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process following input data
|
||||||
|
with size multiple of ST_SHA256_BLOCK_SIZE bytes */
|
||||||
|
size_t iter = currentlen / ST_SHA256_BLOCK_SIZE;
|
||||||
|
if (iter != 0) {
|
||||||
|
if (ctx->is224 == 0) {
|
||||||
|
if (HAL_HASHEx_SHA256_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len),
|
||||||
|
(iter * ST_SHA256_BLOCK_SIZE)) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (HAL_HASHEx_SHA224_Accmlt(&ctx->hhash,
|
||||||
|
(uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len),
|
||||||
|
(iter * ST_SHA256_BLOCK_SIZE)) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store only the remaining input data
|
||||||
|
up to (ST_SHA256_BLOCK_SIZE - 1) bytes */
|
||||||
|
ctx->sbuf_len = currentlen % ST_SHA256_BLOCK_SIZE;
|
||||||
|
if (ctx->sbuf_len != 0) {
|
||||||
|
memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save hw context */
|
||||||
|
HAL_HASH_ContextSaving(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx,
|
||||||
|
unsigned char output[32])
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
SHA256_VALIDATE_RET(ctx != NULL);
|
||||||
|
SHA256_VALIDATE_RET((unsigned char *)output != NULL);
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if ((ret = mbedtls_mutex_lock(&hash_mutex)) != 0) {
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
/* restore hw context */
|
||||||
|
HAL_HASH_ContextRestoring(&ctx->hhash, (uint8_t *)ctx->ctx_save_regs);
|
||||||
|
|
||||||
|
/* Last accumulation for pending bytes in sbuf_len,
|
||||||
|
then trig processing and get digest */
|
||||||
|
if (ctx->is224 == 0) {
|
||||||
|
if (HAL_HASHEx_SHA256_Accmlt_End(&ctx->hhash,
|
||||||
|
ctx->sbuf,
|
||||||
|
ctx->sbuf_len,
|
||||||
|
output,
|
||||||
|
ST_HASH_TIMEOUT) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (HAL_HASHEx_SHA224_Accmlt_End(&ctx->hhash,
|
||||||
|
ctx->sbuf,
|
||||||
|
ctx->sbuf_len,
|
||||||
|
output,
|
||||||
|
ST_HASH_TIMEOUT) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->sbuf_len = 0;
|
||||||
|
|
||||||
|
exit :
|
||||||
|
/* Free context access */
|
||||||
|
#if defined(MBEDTLS_THREADING_C)
|
||||||
|
if (mbedtls_mutex_unlock(&hash_mutex) != 0) {
|
||||||
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_THREADING_C */
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_SHA256_ALT*/
|
||||||
|
#endif /* MBEDTLS_SHA256_C */
|
|
@ -1,9 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* \file sha256_alt.h
|
* \file sha256.h
|
||||||
*
|
*
|
||||||
* \brief SHA256 hw acceleration (hash function)
|
* \brief This file contains SHA-224 and SHA-256 definitions and functions.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017, STMicroelectronics
|
* The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic
|
||||||
|
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
|
||||||
|
* Copyright (C) 2019-2020, STMicroelectronics, All Rights Reserved
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -18,163 +23,38 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
|
* This file implements STMicroelectronics SHA256 API with HW services based
|
||||||
|
* on mbed TLS API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MBEDTLS_SHA256_ALT_H
|
#ifndef MBEDTLS_SHA256_ALT_H
|
||||||
#define MBEDTLS_SHA256_ALT_H
|
#define MBEDTLS_SHA256_ALT_H
|
||||||
|
|
||||||
#if defined (MBEDTLS_SHA256_ALT)
|
#if defined (MBEDTLS_SHA256_ALT)
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "hash_stm32.h"
|
||||||
|
|
||||||
#include "cmsis.h"
|
#define ST_SHA256_BLOCK_SIZE ((size_t) 64) /*!< HW handles 512 bits, ie 64 bytes */
|
||||||
#include <string.h>
|
#define ST_SHA256_NB_HASH_REG ((uint32_t)57) /*!< Number of HASH HW context Registers:
|
||||||
|
CR + STR + IMR + CSR[54] */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ST_SHA256_BLOCK_SIZE ((size_t) 64) // HW handles 512 bits, ie 64 bytes
|
|
||||||
#define ST_SHA256_TIMEOUT ((uint32_t) 3)
|
|
||||||
/**
|
/**
|
||||||
* \brief SHA-256 context structure
|
* \brief SHA-256 context structure
|
||||||
* \note HAL_HASH_SHA256_Accumulate will accumulate 512 bits packets, unless it is the last call to the function
|
*
|
||||||
* A ST_SHA256_BLOCK_SIZE bytes buffer is used to save values and handle the processing
|
* The structure is used both for SHA-256 and for SHA-224
|
||||||
* ST_SHA256_BLOCK_SIZE bytes per ST_SHA256_BLOCK_SIZE bytes
|
* checksum calculations. The choice between these two is
|
||||||
* If sha256_finish is called and sbuf_len>0, the remaining bytes are accumulated prior to the call to HAL_HASH_SHA256_Finish
|
* made in the call to mbedtls_sha256_starts_ret().
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct mbedtls_sha256_context {
|
||||||
int is224; /*!< 0 => SHA-256, else SHA-224 */
|
int is224; /*!< 0 = use SHA256, 1 = use SHA224 */
|
||||||
HASH_HandleTypeDef hhash_sha256;
|
HASH_HandleTypeDef hhash; /*!< Handle of HASH HAL */
|
||||||
unsigned char sbuf[ST_SHA256_BLOCK_SIZE]; /*!< ST_SHA256_BLOCK_SIZE buffer to store values so that algorithm is called once the buffer is filled */
|
uint8_t sbuf[ST_SHA256_BLOCK_SIZE]; /*!< Buffer to store input data until ST_SHA256_BLOCK_SIZE
|
||||||
unsigned char sbuf_len; /*!< number of bytes to be processed in sbuf */
|
is reached, or until last input data is reached */
|
||||||
uint32_t ctx_save_cr;
|
uint8_t sbuf_len; /*!< Number of bytes stored in sbuf */
|
||||||
uint32_t ctx_save_str;
|
uint32_t ctx_save_regs[ST_SHA256_NB_HASH_REG];
|
||||||
uint32_t ctx_save_csr[38];
|
|
||||||
}
|
}
|
||||||
mbedtls_sha256_context;
|
mbedtls_sha256_context;
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Initialize SHA-256 context
|
|
||||||
*
|
|
||||||
* \param ctx SHA-256 context to be initialized
|
|
||||||
*/
|
|
||||||
void mbedtls_sha256_init(mbedtls_sha256_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clear SHA-256 context
|
|
||||||
*
|
|
||||||
* \param ctx SHA-256 context to be cleared
|
|
||||||
*/
|
|
||||||
void mbedtls_sha256_free(mbedtls_sha256_context *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Clone (the state of) a SHA-256 context
|
|
||||||
*
|
|
||||||
* \param dst The destination context
|
|
||||||
* \param src The context to be cloned
|
|
||||||
*/
|
|
||||||
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
|
|
||||||
const mbedtls_sha256_context *src);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-256 context setup
|
|
||||||
*
|
|
||||||
* \param ctx context to be initialized
|
|
||||||
* \param is224 0 = use SHA256, 1 = use SHA224
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_sha256_starts_ret(mbedtls_sha256_context *ctx, int is224);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-256 process buffer
|
|
||||||
*
|
|
||||||
* \param ctx SHA-256 context
|
|
||||||
* \param input buffer holding the data
|
|
||||||
* \param ilen length of the input data
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_sha256_update_ret(mbedtls_sha256_context *ctx,
|
|
||||||
const unsigned char *input,
|
|
||||||
size_t ilen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief SHA-256 final digest
|
|
||||||
*
|
|
||||||
* \param ctx SHA-256 context
|
|
||||||
* \param output SHA-224/256 checksum result
|
|
||||||
*
|
|
||||||
* \returns error code
|
|
||||||
*/
|
|
||||||
int mbedtls_sha256_finish_ret(mbedtls_sha256_context *ctx, unsigned char output[32]);
|
|
||||||
|
|
||||||
/* Internal use */
|
|
||||||
int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[ST_SHA256_BLOCK_SIZE]);
|
|
||||||
|
|
||||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
|
||||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
|
||||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
|
||||||
#else
|
|
||||||
#define MBEDTLS_DEPRECATED
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* \brief This function starts a SHA-256 checksum calculation.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0.
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-256 context to initialize.
|
|
||||||
* \param is224 Determines which function to use.
|
|
||||||
* <ul><li>0: Use SHA-256.</li>
|
|
||||||
* <li>1: Use SHA-224.</li></ul>
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha256_starts(mbedtls_sha256_context *ctx,
|
|
||||||
int is224);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief This function feeds an input buffer into an ongoing
|
|
||||||
* SHA-256 checksum calculation.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0.
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-256 context to initialize.
|
|
||||||
* \param input The buffer holding the data.
|
|
||||||
* \param ilen The length of the input data.
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha256_update(mbedtls_sha256_context *ctx,
|
|
||||||
const unsigned char *input,
|
|
||||||
size_t ilen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief This function finishes the SHA-256 operation, and writes
|
|
||||||
* the result to the output buffer.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0.
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-256 context.
|
|
||||||
* \param output The SHA-224or SHA-256 checksum result.
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
|
|
||||||
unsigned char output[32]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief This function processes a single data block within
|
|
||||||
* the ongoing SHA-256 computation. This function is for
|
|
||||||
* internal use only.
|
|
||||||
*
|
|
||||||
* \deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0.
|
|
||||||
*
|
|
||||||
* \param ctx The SHA-256 context.
|
|
||||||
* \param data The buffer holding one block of data.
|
|
||||||
*/
|
|
||||||
MBEDTLS_DEPRECATED void mbedtls_sha256_process(mbedtls_sha256_context *ctx,
|
|
||||||
const unsigned char data[64]);
|
|
||||||
|
|
||||||
#undef MBEDTLS_DEPRECATED
|
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MBEDTLS_SHA256_ALT */
|
#endif /* MBEDTLS_SHA256_ALT */
|
||||||
|
#endif /* MBEDTLS_SHA256_ALT_H */
|
||||||
#endif /* sha256_alt.h */
|
|
||||||
|
|
|
@ -4074,6 +4074,7 @@
|
||||||
],
|
],
|
||||||
"macros_add": [
|
"macros_add": [
|
||||||
"STM32L562xx",
|
"STM32L562xx",
|
||||||
|
"MBEDTLS_CONFIG_HW_SUPPORT",
|
||||||
"MBED_TICKLESS",
|
"MBED_TICKLESS",
|
||||||
"EXTRA_IDLE_STACK_REQUIRED"
|
"EXTRA_IDLE_STACK_REQUIRED"
|
||||||
],
|
],
|
||||||
|
@ -4134,6 +4135,7 @@
|
||||||
},
|
},
|
||||||
"macros_add": [
|
"macros_add": [
|
||||||
"STM32WB55xx",
|
"STM32WB55xx",
|
||||||
|
"MBEDTLS_CONFIG_HW_SUPPORT",
|
||||||
"MBED_TICKLESS",
|
"MBED_TICKLESS",
|
||||||
"EXTRA_IDLE_STACK_REQUIRED"
|
"EXTRA_IDLE_STACK_REQUIRED"
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue