This change:

- Avoids the use of up_aesinitialize() entirely, which resolves dependency problems, because this function does not make sure that an actual hardware aes implementation was made available: each SoC is now responsible to ensure the AES hardware is initialized before first use. This applies to lpc43xx, stm32 and sam34.
    - Remove definitions of the NEVER used aes_init and aes_update operations. The new AES API will be more suitable.
    - Change the unusual naming in stm32 (avoiding possible naming clashes)
    - Change the unusual naming in sam34 (avoiding possible naming clashes)
    - Add some FAR to pointers and enforce the 80 col limit in stm32 and sam
This commit is contained in:
Sebastien Lorquet 2018-12-19 08:33:08 -06:00 committed by Gregory Nutt
parent 08b9b3e230
commit a7257eff52
6 changed files with 214 additions and 200 deletions

View File

@ -66,32 +66,11 @@
static struct lpc43_aes_s *g_aes;
/****************************************************************************
* Public Functions
* Private Functions
****************************************************************************/
int aes_cypher(void *out, const void *in, uint32_t size, const void *iv,
const void *key, uint32_t keysize, int mode, int encrypt)
{
unsigned int ret = 0;
uint32_t outl = size;
ret = aes_init(iv, key, keysize, mode, encrypt);
if (ret != OK)
{
return ret;
}
return aes_update(out, &outl, in, size);
}
int up_aesreset(void)
{
return OK;
}
int aes_init(FAR const void *iv, FAR const void *key, uint32_t keysize,
int mode, int encrypt)
static int aes_init(FAR const void *iv, FAR const void *key, uint32_t keysize,
int mode, int encrypt)
{
unsigned int cmd = 0;
unsigned int ret = 0;
@ -101,10 +80,10 @@ int aes_init(FAR const void *iv, FAR const void *key, uint32_t keysize,
return -ENOSYS;
}
/* The LPC43 aes engine can load two keys from otp and one random
* generated key. This behavior doesn't fit current api. So if
* key == NULL, we will usr keysize as identifier of the special key.
*/
/* The LPC43 aes engine can load two keys from otp and one random
* generated key. This behavior doesn't fit current api. So if
* key == NULL, we will usr keysize as identifier of the special key.
*/
if (keysize != 16 && key)
{
@ -134,19 +113,19 @@ int aes_init(FAR const void *iv, FAR const void *key, uint32_t keysize,
else
{
switch (keysize)
{
case 0:
g_aes->aes_LoadKey1();
break;
{
case 0:
g_aes->aes_LoadKey1();
break;
case 1:
g_aes->aes_LoadKey2();
break;
case 1:
g_aes->aes_LoadKey2();
break;
case 2:
g_aes->aes_LoadKeyRNG();
break;
}
case 2:
g_aes->aes_LoadKeyRNG();
break;
}
}
g_aes->aes_LoadIV_SW((const unsigned char*)iv);
@ -170,15 +149,15 @@ int aes_init(FAR const void *iv, FAR const void *key, uint32_t keysize,
return 0;
}
int aes_update(FAR const void *out, uint32_t *outl, FAR const void *in,
uint32_t inl)
static int aes_update(FAR const void *out, uint32_t *outl, FAR const void *in,
uint32_t inl)
{
if (g_aes == NULL)
{
return -ENOSYS;
}
if ((inl & (AES_BLOCK_SIZE-1)) != 0)
if ((inl & (AES_BLOCK_SIZE - 1)) != 0)
{
return -EINVAL;
}
@ -192,18 +171,24 @@ int aes_update(FAR const void *out, uint32_t *outl, FAR const void *in,
(unsigned char*)in, inl / 16);
}
int up_aesinitialize(void)
/****************************************************************************
* Public Functions
****************************************************************************/
int aes_cypher(void *out, const void *in, uint32_t size, const void *iv,
const void *key, uint32_t keysize, int mode, int encrypt)
{
unsigned int ret = 0;
uint32_t outl = size;
g_aes = (struct lpc43_g_aes*)*((uint32_t*)LPC43_ROM_AES_DRIVER_TABLE);
if (g_aes != NULL)
ret = aes_init(iv, key, keysize, mode, encrypt);
if (ret != OK)
{
return OK;
return ret;
}
return -ENOSYS;
}
int up_aesuninitialize(void)
{
return OK;
return aes_update(out, &outl, in, size);
}

View File

@ -76,7 +76,8 @@
* Private Data
****************************************************************************/
static sem_t lock;
static sem_t g_samaes_lock;
static bool g_samaes_initdone = false;
/****************************************************************************
* Public Data
@ -86,29 +87,31 @@ static sem_t lock;
* Private Functions
****************************************************************************/
static void aes_lock(void)
static void samaes_lock(void)
{
nxsem_wait(&lock);
nxsem_wait(&g_samaes_lock);
}
static void aes_unlock(void)
static void samaes_unlock(void)
{
nxsem_post(&lock);
nxsem_post(&g_samaes_lock);
}
static void aes_memcpy(void *out, const void *in, size_t size)
static void samaes_memcpy(FAR void *out, FAR const void *in, size_t size)
{
size_t i;
size_t wcount = size / 4;
for (i = 0; i < wcount; i++, out = (uint8_t *)out + 4, in = (uint8_t *)in + 4)
for (i = 0; i < wcount;
i++, out = (FAR uint8_t *)out + 4, in = (FAR uint8_t *)in + 4)
{
*(uint32_t *)out = *(uint32_t *)in;
*(FAR uint32_t *)out = *(FAR uint32_t *)in;
}
}
static void aes_encryptblock(void *out, const void *in)
static void samaes_encryptblock(FAR void *out, FAR const void *in)
{
aes_memcpy((void *)SAM_AES_IDATAR, in, AES_BLOCK_SIZE);
samaes_memcpy((void *)SAM_AES_IDATAR, in, AES_BLOCK_SIZE);
putreg32(AES_CR_START, SAM_AES_CR);
@ -116,11 +119,11 @@ static void aes_encryptblock(void *out, const void *in)
if (out)
{
aes_memcpy(out, (void *)SAM_AES_ODATAR, AES_BLOCK_SIZE);
samaes_memcpy(out, (void *)SAM_AES_ODATAR, AES_BLOCK_SIZE);
}
}
static int aes_setup_mr(uint32_t keysize, int mode, int encrypt)
static int samaes_setup_mr(uint32_t keysize, int mode, int encrypt)
{
uint32_t regval = AES_MR_SMOD_MANUAL_START | AES_MR_CKEY;
@ -138,12 +141,15 @@ static int aes_setup_mr(uint32_t keysize, int mode, int encrypt)
case 16:
regval |= AES_MR_KEYSIZE_AES128;
break;
case 24:
regval |= AES_MR_KEYSIZE_AES192;
break;
case 32:
regval |= AES_MR_KEYSIZE_AES256;
break;
default:
return -EINVAL;
}
@ -153,15 +159,19 @@ static int aes_setup_mr(uint32_t keysize, int mode, int encrypt)
case AES_MODE_ECB:
regval |= AES_MR_OPMOD_ECB;
break;
case AES_MODE_CBC:
regval |= AES_MR_OPMOD_CBC;
break;
case AES_MODE_CTR:
regval |= AES_MR_OPMOD_CTR;
break;
case AES_MODE_CFB:
regval |= AES_MR_OPMOD_CFB;
break;
default:
return -EINVAL;
}
@ -174,59 +184,71 @@ static int aes_setup_mr(uint32_t keysize, int mode, int encrypt)
* Public Functions
****************************************************************************/
int aes_cypher(void *out, const void *in, uint32_t size, const void *iv,
const void *key, uint32_t keysize, int mode, int encrypt)
static int samaes_initialize(void)
{
int res = OK;
nxsem_init(&g_samaes_lock, 0, 1);
sam_aes_enableclk();
putreg32(AES_CR_SWRST, SAM_AES_CR);
return OK;
}
int aes_cypher(FAR void *out, FAR const void *in, uint32_t size,
FAR const void *iv, FAR const void *key, uint32_t keysize,
int mode, int encrypt)
{
int ret = OK;
if (!g_samaes_initdone)
{
ret = samaes_initialize();
if (ret != OK)
{
return ret;
}
g_samaes_initdone = true;
}
if (size % 16)
{
return -EINVAL;
}
aes_lock();
samaes_lock();
res = aes_setup_mr(keysize, mode & AES_MODE_MASK, encrypt);
if (res)
ret = samaes_setup_mr(keysize, mode & AES_MODE_MASK, encrypt);
if (ret < 0)
{
aes_unlock();
return res;
samaes_unlock();
return ret;
}
aes_memcpy((void *)SAM_AES_KEYWR, key, keysize);
if (iv)
samaes_memcpy((FAR void *)SAM_AES_KEYWR, key, keysize);
if (iv != NULL)
{
aes_memcpy((void *)SAM_AES_IVR, iv, AES_BLOCK_SIZE);
samaes_memcpy((FAR void *)SAM_AES_IVR, iv, AES_BLOCK_SIZE);
}
while (size)
{
if ((mode & AES_MODE_MAC) == 0)
{
aes_encryptblock(out, in);
out = (char *)out + AES_BLOCK_SIZE;
samaes_encryptblock(out, in);
out = (FAR char *)out + AES_BLOCK_SIZE;
}
else if (size == AES_BLOCK_SIZE)
{
aes_encryptblock(out, in);
samaes_encryptblock(out, in);
}
else
{
aes_encryptblock(NULL, in);
samaes_encryptblock(NULL, in);
}
in = (char *)in + AES_BLOCK_SIZE;
in = (FAR char *)in + AES_BLOCK_SIZE;
size -= AES_BLOCK_SIZE;
}
aes_unlock();
return res;
}
int up_aesinitialize()
{
nxsem_init(&lock, 0, 1);
sam_aes_enableclk();
putreg32(AES_CR_SWRST, SAM_AES_CR);
return OK;
samaes_unlock();
return ret;
}

View File

@ -73,18 +73,20 @@
* Private Function Prototypes
****************************************************************************/
static void aes_enable(bool on);
static void aes_ccfc(void);
static void aes_setkey(const void *key, size_t key_len);
static void aes_setiv(const void *iv);
static void aes_encryptblock(void *block_out, const void *block_in);
static int aes_setup_cr(int mode, int encrypt);
static void stm32aes_enable(bool on);
static void stm32aes_ccfc(void);
static void stm32aes_setkey(FAR const void *key, size_t key_len);
static void stm32aes_setiv(FAR const void *iv);
static void stm32aes_encryptblock(FAR void *block_out,
FAR const void *block_in);
static int stm32aes_setup_cr(int mode, int encrypt);
/****************************************************************************
* Private Data
****************************************************************************/
static sem_t aes_lock;
static sem_t g_stm32aes_lock;
static bool g_stm32aes_initdone = false;
/****************************************************************************
* Public Data
@ -94,32 +96,39 @@ static sem_t aes_lock;
* Private Functions
****************************************************************************/
static void aes_enable(bool on)
static void stm32aes_enable(bool on)
{
uint32_t regval;
regval = getreg32(STM32_AES_CR);
if (on)
regval |= AES_CR_EN;
{
regval |= AES_CR_EN;
}
else
regval &= ~AES_CR_EN;
{
regval &= ~AES_CR_EN;
}
putreg32(regval, STM32_AES_CR);
}
/* Clear AES_SR_CCF status register bit */
static void aes_ccfc(void)
static void stm32aes_ccfc(void)
{
uint32_t regval;
regval = getreg32(STM32_AES_CR);
regval = getreg32(STM32_AES_CR);
regval |= AES_CR_CCFC;
putreg32(regval, STM32_AES_CR);
}
static void aes_setkey(const void *key, size_t key_len)
/* TODO: Handle other AES key lengths or fail if length is not valid */
static void stm32aes_setkey(FAR const void *key, size_t key_len)
{
uint32_t *in = (uint32_t *)key;
FAR uint32_t *in = (FAR uint32_t *)key;
(void)key_len;
@ -132,9 +141,9 @@ static void aes_setkey(const void *key, size_t key_len)
putreg32(__builtin_bswap32(*in), STM32_AES_KEYR0);
}
static void aes_setiv(const void *iv)
static void stm32aes_setiv(FAR const void *iv)
{
uint32_t *in = (uint32_t *)iv;
FAR uint32_t *in = (FAR uint32_t *)iv;
putreg32(__builtin_bswap32(*in), STM32_AES_IVR3);
in++;
@ -145,10 +154,10 @@ static void aes_setiv(const void *iv)
putreg32(__builtin_bswap32(*in), STM32_AES_IVR0);
}
static void aes_encryptblock(void *block_out, const void *block_in)
static void stm32aes_encryptblock(FAR void *block_out, FAR const void *block_in)
{
uint32_t *in = (uint32_t *)block_in;
uint32_t *out = (uint32_t *)block_out;
FAR uint32_t *in = (FAR uint32_t *)block_in;
FAR uint32_t *out = (FAR uint32_t *)block_out;
putreg32(*in, STM32_AES_DINR);
in++;
@ -160,7 +169,7 @@ static void aes_encryptblock(void *block_out, const void *block_in)
while (!(getreg32(STM32_AES_SR) & AES_SR_CCF))
;
aes_ccfc();
stm32aes_ccfc();
*out = getreg32(STM32_AES_DOUTR);
out++;
@ -171,7 +180,7 @@ static void aes_encryptblock(void *block_out, const void *block_in)
*out = getreg32(STM32_AES_DOUTR);
}
static int aes_setup_cr(int mode, int encrypt)
static int stm32aes_setup_cr(int mode, int encrypt)
{
uint32_t regval = 0;
@ -219,11 +228,73 @@ static int aes_setup_cr(int mode, int encrypt)
* Public Functions
****************************************************************************/
int aes_cypher(void *out, const void *in, uint32_t size, const void *iv,
const void *key, uint32_t keysize, int mode, int encrypt)
int stm32_aesreset(void)
{
irqstate_t flags;
uint32_t regval;
flags = enter_critical_section();
regval = getreg32(STM32_RCC_AHBRSTR);
regval |= RCC_AHBRSTR_AESRST;
putreg32(regval, STM32_RCC_AHBRSTR);
regval &= ~RCC_AHBRSTR_AESRST;
putreg32(regval, STM32_RCC_AHBRSTR);
leave_critical_section(flags);
return OK;
}
int stm32_aesinitialize(void)
{
uint32_t regval;
nxsem_init(&g_stm32aes_lock, 0, 1);
regval = getreg32(STM32_RCC_AHBENR);
regval |= RCC_AHBENR_AESEN;
putreg32(regval, STM32_RCC_AHBENR);
stm32aes_enable(false);
return OK;
}
int stm32_aesuninitialize(void)
{
uint32_t regval;
stm32aes_enable(false);
regval = getreg32(STM32_RCC_AHBENR);
regval &= ~RCC_AHBENR_AESEN;
putreg32(regval, STM32_RCC_AHBENR);
nxsem_destroy(&g_stm32aes_lock);
return OK;
}
int aes_cypher(FAR void *out, FAR const void *in, uint32_t size,
FAR const void *iv, FAR const void *key, uint32_t keysize,
int mode, int encrypt)
{
int ret = OK;
/* Ensure initialization was done */
if (!g_stm32aes_initdone)
{
ret = stm32_aesinitialize();
if (ret < 0)
{
return ret; /* AES init failed */
}
g_stm32aes_initdone = true;
}
if ((size & (AES_BLOCK_SIZE-1)) != 0)
{
return -EINVAL;
@ -234,7 +305,7 @@ int aes_cypher(void *out, const void *in, uint32_t size, const void *iv,
return -EINVAL;
}
ret = nxsem_wait(&aes_lock);
ret = nxsem_wait(&g_stm32aes_lock);
if (ret < 0)
{
return ret;
@ -242,79 +313,31 @@ int aes_cypher(void *out, const void *in, uint32_t size, const void *iv,
/* AES must be disabled before changing mode, key or IV. */
aes_enable(false);
ret = aes_setup_cr(mode, encrypt);
stm32aes_enable(false);
ret = stm32aes_setup_cr(mode, encrypt);
if (ret < 0)
{
goto out;
}
aes_setkey(key, keysize);
if (iv)
stm32aes_setkey(key, keysize);
if (iv != NULL)
{
aes_setiv(iv);
stm32aes_setiv(iv);
}
aes_enable(true);
stm32aes_enable(true);
while (size)
{
aes_encryptblock(out, in);
out = (uint8_t *)out + AES_BLOCK_SIZE;
in = (uint8_t *)in + AES_BLOCK_SIZE;
stm32aes_encryptblock(out, in);
out = (FAR uint8_t *)out + AES_BLOCK_SIZE;
in = (FAR uint8_t *)in + AES_BLOCK_SIZE;
size -= AES_BLOCK_SIZE;
}
aes_enable(false);
stm32aes_enable(false);
out:
nxsem_post(&aes_lock);
nxsem_post(&g_stm32aes_lock);
return ret;
}
int up_aesreset(void)
{
irqstate_t flags;
uint32_t regval;
flags = enter_critical_section();
regval = getreg32(STM32_RCC_AHBRSTR);
regval |= RCC_AHBRSTR_AESRST;
putreg32(regval, STM32_RCC_AHBRSTR);
regval &= ~RCC_AHBRSTR_AESRST;
putreg32(regval, STM32_RCC_AHBRSTR);
leave_critical_section(flags);
return OK;
}
int up_aesinitialize(void)
{
uint32_t regval;
nxsem_init(&aes_lock, 0, 1);
regval = getreg32(STM32_RCC_AHBENR);
regval |= RCC_AHBENR_AESEN;
putreg32(regval, STM32_RCC_AHBENR);
aes_enable(false);
return OK;
}
int up_aesuninitialize(void)
{
uint32_t regval;
aes_enable(false);
regval = getreg32(STM32_RCC_AHBENR);
regval &= ~RCC_AHBENR_AESEN;
putreg32(regval, STM32_RCC_AHBENR);
nxsem_destroy(&aes_lock);
return OK;
}

View File

@ -34,11 +34,6 @@
*
****************************************************************************/
/* TODO: Adapt interfaces so that they are consistent with H/W AES
* implemenations. This needs to support up_aesinitialize() and
* aes_cypher() per include/nuttx/crypto/crypto.h.
*/
/****************************************************************************
* Included Files
****************************************************************************/

View File

@ -66,20 +66,12 @@
int up_cryptoinitialize(void)
{
#if defined(CONFIG_CRYPTO_AES) || defined(CONFIG_CRYPTO_ALGTEST)
int res;
#ifdef CONFIG_CRYPTO_AES
res = up_aesinitialize();
if (res)
{
return res;
}
#endif
#ifdef CONFIG_CRYPTO_ALGTEST
int ret;
#ifdef CONFIG_CRYPTO_ALGTEST
res = crypto_test();
if (res)
ret = crypto_test();
if (ret)
{
crypterr("ERROR: crypto test failed\n");
}
@ -89,7 +81,7 @@ int up_cryptoinitialize(void)
}
#endif
return res;
return ret;
#else
return OK;
#endif

View File

@ -65,9 +65,9 @@
#define CYPHER_ENCRYPT 1
#define CYPHER_DECRYPT 0
/************************************************************************************
/*******************************************************************************
* Public Data
************************************************************************************/
******************************************************************************/
#ifndef __ASSEMBLY__
@ -80,19 +80,16 @@ extern "C"
#define EXTERN extern
#endif
/************************************************************************************
/*******************************************************************************
* Public Function Prototypes
************************************************************************************/
******************************************************************************/
int up_cryptoinitialize(void);
#if defined(CONFIG_CRYPTO_AES)
int up_aesinitialize(void);
int aes_cypher(FAR void *out, FAR const void *in, uint32_t size, FAR const void *iv,
FAR const void *key, uint32_t keysize, int mode, int encrypt);
int aes_init(FAR const void *iv, FAR const void *key, uint32_t keysize, int mode,
int encrypt);
int aes_update(FAR const void *out, uint32_t *outl, FAR const void *in, uint32_t inl);
int aes_cypher(FAR void *out, FAR const void *in, uint32_t size,
FAR const void *iv, FAR const void *key, uint32_t keysize,
int mode, int encrypt);
#endif
#if defined(CONFIG_CRYPTO_ALGTEST)