mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp32 hwcrypto: Use AES registers directly
This commit is contained in:
parent
e256fb6d96
commit
2624e10055
@ -3,7 +3,7 @@
|
|||||||
* Based on mbedTLS FIPS-197 compliant version.
|
* Based on mbedTLS FIPS-197 compliant version.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
* Additions Copyright (C) 2016-2017, Espressif Systems (Shanghai) PTE Ltd
|
||||||
* 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
|
||||||
@ -26,9 +26,10 @@
|
|||||||
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
#include "hwcrypto/aes.h"
|
#include "hwcrypto/aes.h"
|
||||||
#include "rom/aes.h"
|
|
||||||
#include "soc/dport_reg.h"
|
#include "soc/dport_reg.h"
|
||||||
|
#include "soc/hwcrypto_reg.h"
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
|
|
||||||
static _lock_t aes_lock;
|
static _lock_t aes_lock;
|
||||||
@ -81,55 +82,18 @@ void esp_aes_free( esp_aes_context *ctx )
|
|||||||
bzero( ctx, sizeof( esp_aes_context ) );
|
bzero( ctx, sizeof( esp_aes_context ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translate number of bits to an AES_BITS enum */
|
|
||||||
static int keybits_to_aesbits(unsigned int keybits)
|
|
||||||
{
|
|
||||||
switch (keybits) {
|
|
||||||
case 128:
|
|
||||||
return AES128;
|
|
||||||
case 192:
|
|
||||||
return AES192;
|
|
||||||
break;
|
|
||||||
case 256:
|
|
||||||
return AES256;
|
|
||||||
default:
|
|
||||||
return ( ERR_ESP_AES_INVALID_KEY_LENGTH );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AES key schedule (encryption)
|
* AES key schedule (same for encryption or decryption, as hardware handles schedule)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int esp_aes_setkey_enc( esp_aes_context *ctx, const unsigned char *key,
|
int esp_aes_setkey( esp_aes_context *ctx, const unsigned char *key,
|
||||||
unsigned int keybits )
|
unsigned int keybits )
|
||||||
{
|
{
|
||||||
uint16_t keybytes = keybits / 8;
|
if (keybits != 128 && keybits != 192 && keybits != 256) {
|
||||||
int aesbits = keybits_to_aesbits(keybits);
|
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||||
if (aesbits < 0) {
|
|
||||||
return aesbits;
|
|
||||||
}
|
}
|
||||||
ctx->enc.aesbits = aesbits;
|
ctx->key_bytes = keybits / 8;
|
||||||
bzero(ctx->enc.key, sizeof(ctx->enc.key));
|
memcpy(ctx->key, key, ctx->key_bytes);
|
||||||
memcpy(ctx->enc.key, key, keybytes);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AES key schedule (decryption)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int esp_aes_setkey_dec( esp_aes_context *ctx, const unsigned char *key,
|
|
||||||
unsigned int keybits )
|
|
||||||
{
|
|
||||||
uint16_t keybytes = keybits / 8;
|
|
||||||
int aesbits = keybits_to_aesbits(keybits);
|
|
||||||
if (aesbits < 0) {
|
|
||||||
return aesbits;
|
|
||||||
}
|
|
||||||
ctx->dec.aesbits = aesbits;
|
|
||||||
bzero(ctx->dec.key, sizeof(ctx->dec.key));
|
|
||||||
memcpy(ctx->dec.key, key, keybytes);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,27 +101,41 @@ int esp_aes_setkey_dec( esp_aes_context *ctx, const unsigned char *key,
|
|||||||
* Helper function to copy key from esp_aes_context buffer
|
* Helper function to copy key from esp_aes_context buffer
|
||||||
* to hardware key registers.
|
* to hardware key registers.
|
||||||
*
|
*
|
||||||
* Only call when protected by esp_aes_acquire_hardware().
|
* Call only while holding esp_aes_acquire_hardware().
|
||||||
*/
|
*/
|
||||||
static inline int esp_aes_setkey_hardware( esp_aes_context *ctx, int mode)
|
static inline void esp_aes_setkey_hardware( esp_aes_context *ctx, int mode)
|
||||||
{
|
{
|
||||||
DPORT_ACCESS_BLOCK() {
|
const uint32_t MODE_DECRYPT_BIT = 4;
|
||||||
// ROM AES functions access DPORT, so need to be protected as such
|
unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT;
|
||||||
if ( mode == ESP_AES_ENCRYPT ) {
|
|
||||||
ets_aes_setkey_enc(ctx->enc.key, ctx->enc.aesbits);
|
memcpy((uint32_t *)AES_KEY_BASE, ctx->key, ctx->key_bytes);
|
||||||
} else {
|
DPORT_REG_WRITE(AES_MODE_REG, mode_reg_base + ((ctx->key_bytes / 8) - 2));
|
||||||
ets_aes_setkey_dec(ctx->dec.key, ctx->dec.aesbits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void esp_aes_block(const uint8_t input[16], uint8_t output[16])
|
/* Run a single 16 byte block of AES, using the hardware engine.
|
||||||
|
*
|
||||||
|
* Call only while holding esp_aes_acquire_hardware().
|
||||||
|
*/
|
||||||
|
static inline void esp_aes_block(const void *input, void *output)
|
||||||
{
|
{
|
||||||
DPORT_ACCESS_BLOCK() {
|
const uint32_t *input_words = (const uint32_t *)input;
|
||||||
// ROM AES functions access DPORT, so need to be protected as such
|
uint32_t *output_words = (uint32_t *)output;
|
||||||
ets_aes_crypt(input, output);
|
uint32_t *mem_block = (uint32_t *)AES_TEXT_BASE;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
mem_block[i] = input_words[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPORT_REG_WRITE(AES_START_REG, 1);
|
||||||
|
|
||||||
|
DPORT_STALL_OTHER_CPU_START();
|
||||||
|
{
|
||||||
|
while (_DPORT_REG_READ(AES_IDLE_REG) != 1) { }
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
output_words[i] = mem_block[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DPORT_STALL_OTHER_CPU_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -215,6 +193,9 @@ int esp_aes_crypt_cbc( esp_aes_context *ctx,
|
|||||||
unsigned char *output )
|
unsigned char *output )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
uint32_t *output_words = (uint32_t *)output;
|
||||||
|
const uint32_t *input_words = (const uint32_t *)input;
|
||||||
|
uint32_t *iv_words = (uint32_t *)iv;
|
||||||
unsigned char temp[16];
|
unsigned char temp[16];
|
||||||
|
|
||||||
if ( length % 16 ) {
|
if ( length % 16 ) {
|
||||||
@ -222,34 +203,36 @@ int esp_aes_crypt_cbc( esp_aes_context *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
esp_aes_acquire_hardware();
|
esp_aes_acquire_hardware();
|
||||||
|
|
||||||
esp_aes_setkey_hardware(ctx, mode);
|
esp_aes_setkey_hardware(ctx, mode);
|
||||||
|
|
||||||
if ( mode == ESP_AES_DECRYPT ) {
|
if ( mode == ESP_AES_DECRYPT ) {
|
||||||
while ( length > 0 ) {
|
while ( length > 0 ) {
|
||||||
memcpy( temp, input, 16 );
|
memcpy(temp, input_words, 16);
|
||||||
esp_aes_block(input, output);
|
esp_aes_block(input_words, output_words);
|
||||||
|
|
||||||
for ( i = 0; i < 16; i++ ) {
|
for ( i = 0; i < 4; i++ ) {
|
||||||
output[i] = (unsigned char)( output[i] ^ iv[i] );
|
output_words[i] = output_words[i] ^ iv_words[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy( iv, temp, 16 );
|
memcpy( iv_words, temp, 16 );
|
||||||
|
|
||||||
input += 16;
|
input_words += 4;
|
||||||
output += 16;
|
output_words += 4;
|
||||||
length -= 16;
|
length -= 16;
|
||||||
}
|
}
|
||||||
} else { // ESP_AES_ENCRYPT
|
} else { // ESP_AES_ENCRYPT
|
||||||
while ( length > 0 ) {
|
while ( length > 0 ) {
|
||||||
for ( i = 0; i < 16; i++ ) {
|
|
||||||
output[i] = (unsigned char)( input[i] ^ iv[i] );
|
for ( i = 0; i < 4; i++ ) {
|
||||||
|
output_words[i] = input_words[i] ^ iv_words[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_aes_block(output, output);
|
esp_aes_block(output_words, output_words);
|
||||||
memcpy( iv, output, 16 );
|
memcpy( iv_words, output_words, 16 );
|
||||||
|
|
||||||
input += 16;
|
input_words += 4;
|
||||||
output += 16;
|
output_words += 4;
|
||||||
length -= 16;
|
length -= 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,6 +257,7 @@ int esp_aes_crypt_cfb128( esp_aes_context *ctx,
|
|||||||
size_t n = *iv_off;
|
size_t n = *iv_off;
|
||||||
|
|
||||||
esp_aes_acquire_hardware();
|
esp_aes_acquire_hardware();
|
||||||
|
|
||||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||||
|
|
||||||
if ( mode == ESP_AES_DECRYPT ) {
|
if ( mode == ESP_AES_DECRYPT ) {
|
||||||
@ -321,6 +305,7 @@ int esp_aes_crypt_cfb8( esp_aes_context *ctx,
|
|||||||
unsigned char ov[17];
|
unsigned char ov[17];
|
||||||
|
|
||||||
esp_aes_acquire_hardware();
|
esp_aes_acquire_hardware();
|
||||||
|
|
||||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||||
|
|
||||||
while ( length-- ) {
|
while ( length-- ) {
|
||||||
@ -360,6 +345,7 @@ int esp_aes_crypt_ctr( esp_aes_context *ctx,
|
|||||||
size_t n = *nc_off;
|
size_t n = *nc_off;
|
||||||
|
|
||||||
esp_aes_acquire_hardware();
|
esp_aes_acquire_hardware();
|
||||||
|
|
||||||
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
|
||||||
|
|
||||||
while ( length-- ) {
|
while ( length-- ) {
|
||||||
|
@ -38,11 +38,6 @@ extern "C" {
|
|||||||
#define ERR_ESP_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
#define ERR_ESP_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||||
#define ERR_ESP_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
#define ERR_ESP_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
enum AES_BITS aesbits;
|
|
||||||
uint8_t key[32];
|
|
||||||
} key_context, KEY_CTX;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief AES context structure
|
* \brief AES context structure
|
||||||
*
|
*
|
||||||
@ -52,10 +47,8 @@ typedef struct {
|
|||||||
* generating an extra round key
|
* generating an extra round key
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int nr; /*!< number of rounds */
|
uint8_t key_bytes;
|
||||||
uint32_t *rk; /*!< AES round keys */
|
uint8_t key[32];
|
||||||
KEY_CTX enc;
|
|
||||||
KEY_CTX dec;
|
|
||||||
} esp_aes_context;
|
} esp_aes_context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +87,7 @@ void esp_aes_init( esp_aes_context *ctx );
|
|||||||
void esp_aes_free( esp_aes_context *ctx );
|
void esp_aes_free( esp_aes_context *ctx );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief AES key schedule (encryption)
|
* \brief AES set key schedule (encryption or decryption)
|
||||||
*
|
*
|
||||||
* \param ctx AES context to be initialized
|
* \param ctx AES context to be initialized
|
||||||
* \param key encryption key
|
* \param key encryption key
|
||||||
@ -102,18 +95,7 @@ void esp_aes_free( esp_aes_context *ctx );
|
|||||||
*
|
*
|
||||||
* \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH
|
* \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH
|
||||||
*/
|
*/
|
||||||
int esp_aes_setkey_enc( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits );
|
int esp_aes_setkey( esp_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 ERR_AES_INVALID_KEY_LENGTH
|
|
||||||
*/
|
|
||||||
int esp_aes_setkey_dec( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief AES-ECB block encryption/decryption
|
* \brief AES-ECB block encryption/decryption
|
||||||
|
@ -34,8 +34,8 @@ typedef esp_aes_context mbedtls_aes_context;
|
|||||||
|
|
||||||
#define mbedtls_aes_init esp_aes_init
|
#define mbedtls_aes_init esp_aes_init
|
||||||
#define mbedtls_aes_free esp_aes_free
|
#define mbedtls_aes_free esp_aes_free
|
||||||
#define mbedtls_aes_setkey_enc esp_aes_setkey_enc
|
#define mbedtls_aes_setkey_enc esp_aes_setkey
|
||||||
#define mbedtls_aes_setkey_dec esp_aes_setkey_dec
|
#define mbedtls_aes_setkey_dec esp_aes_setkey
|
||||||
#define mbedtls_aes_crypt_ecb esp_aes_crypt_ecb
|
#define mbedtls_aes_crypt_ecb esp_aes_crypt_ecb
|
||||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||||
#define mbedtls_aes_crypt_cbc esp_aes_crypt_cbc
|
#define mbedtls_aes_crypt_cbc esp_aes_crypt_cbc
|
||||||
|
@ -57,4 +57,12 @@
|
|||||||
#define SHA_512_LOAD_REG ((DR_REG_SHA_BASE) + 0xb8)
|
#define SHA_512_LOAD_REG ((DR_REG_SHA_BASE) + 0xb8)
|
||||||
#define SHA_512_BUSY_REG ((DR_REG_SHA_BASE) + 0xbc)
|
#define SHA_512_BUSY_REG ((DR_REG_SHA_BASE) + 0xbc)
|
||||||
|
|
||||||
|
/* AES acceleration registers */
|
||||||
|
#define AES_START_REG ((DR_REG_AES_BASE) + 0x00)
|
||||||
|
#define AES_IDLE_REG ((DR_REG_AES_BASE) + 0x04)
|
||||||
|
#define AES_MODE_REG ((DR_REG_AES_BASE) + 0x08)
|
||||||
|
#define AES_KEY_BASE ((DR_REG_AES_BASE) + 0x10)
|
||||||
|
#define AES_TEXT_BASE ((DR_REG_AES_BASE) + 0x30)
|
||||||
|
#define AES_ENDIAN ((DR_REG_AES_BASE) + 0x40)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
#define SOC_RTC_DATA_HIGH 0x50002000
|
#define SOC_RTC_DATA_HIGH 0x50002000
|
||||||
|
|
||||||
#define DR_REG_DPORT_BASE 0x3ff00000
|
#define DR_REG_DPORT_BASE 0x3ff00000
|
||||||
|
#define DR_REG_AES_BASE 0x3ff01000
|
||||||
#define DR_REG_RSA_BASE 0x3ff02000
|
#define DR_REG_RSA_BASE 0x3ff02000
|
||||||
#define DR_REG_SHA_BASE 0x3ff03000
|
#define DR_REG_SHA_BASE 0x3ff03000
|
||||||
#define DR_REG_DPORT_END 0x3ff03FFC
|
#define DR_REG_DPORT_END 0x3ff03FFC
|
||||||
|
Loading…
Reference in New Issue
Block a user