diff --git a/arch/arm/src/lpc43xx/lpc43_aes.c b/arch/arm/src/lpc43xx/lpc43_aes.c index 3f9af5ada3..da22ed2abd 100644 --- a/arch/arm/src/lpc43xx/lpc43_aes.c +++ b/arch/arm/src/lpc43xx/lpc43_aes.c @@ -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); } diff --git a/arch/arm/src/sam34/sam_aes.c b/arch/arm/src/sam34/sam_aes.c index c974667930..3eabf7f4b0 100644 --- a/arch/arm/src/sam34/sam_aes.c +++ b/arch/arm/src/sam34/sam_aes.c @@ -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; } diff --git a/arch/arm/src/stm32/stm32_aes.c b/arch/arm/src/stm32/stm32_aes.c index 5dcb9dc536..d72ab695af 100644 --- a/arch/arm/src/stm32/stm32_aes.c +++ b/arch/arm/src/stm32/stm32_aes.c @@ -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; -} diff --git a/crypto/aes.c b/crypto/aes.c index 371c0d2624..1933b5c005 100644 --- a/crypto/aes.c +++ b/crypto/aes.c @@ -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 ****************************************************************************/ diff --git a/crypto/crypto.c b/crypto/crypto.c index 57839fa0fe..66b2087394 100644 --- a/crypto/crypto.c +++ b/crypto/crypto.c @@ -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 diff --git a/include/nuttx/crypto/crypto.h b/include/nuttx/crypto/crypto.h index 3433a72c9e..8d155ffee3 100644 --- a/include/nuttx/crypto/crypto.h +++ b/include/nuttx/crypto/crypto.h @@ -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)