liam-geotab opened a new pull request, #19928:
URL: https://github.com/apache/nuttx/pull/19928
## Summary
Add CRC header based on arch/arm/src/common/stm32/hardware/stm32_crc.h and
select STM32_HAVE_CRC in Kconfig.
CRC_IDR_MASK widened from 0xFF to 0xFFFFFFFF.
## Impact
As usual, drivers must include this "hardware/" header explicitly and
manipulate the registers.
Now that stm32h5 defines STM32_HAVE_CRC, STM32_CRC can be enabled, which
causes the clock to be enabled in rcc_enableahb1().
## Testing
I validated by copying the H7 crypto driver implementation and removing
everything except crc32 so that the crypto crc32 test cases could run on H5
using the H5 CRC definitions.
`nucleo-h563zi:nsh` with:
```
CONFIG_ALLOW_BSD_COMPONENTS=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_CRYPTODEV=y
CONFIG_CRYPTO_CRYPTODEV_HARDWARE=y
CONFIG_STM32_CRC=y
CONFIG_TESTING_CRYPTO=y
CONFIG_TESTING_CRYPTO_CRC32=y
```
```
nsh> crc32
crc32 test case 1 success
crc32 test case 2 success
crc32 test case 3 success
crc32 test case 4 success
crc32 test case 5 success
crc32 test case 6 success
crc32 test case 7 success
crc32 test case 8 success
```
```diff
diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs
index 7d35a2b939..6ca3dfe323 100644
--- a/arch/arm/src/stm32h5/Make.defs
+++ b/arch/arm/src/stm32h5/Make.defs
@@ -116,6 +116,8 @@ ifeq ($(CONFIG_STM32_IWDG),y)
CHIP_CSRCS += stm32_iwdg.c
endif
+CHIP_CSRCS += stm32_crypto.c
+
# Required chip type specific files
ifeq ($(CONFIG_STM32_STM32H5XXXX),y)
```
```diff
diff --git a/arch/arm/src/stm32h7/stm32_crypto.c
b/arch/arm/src/stm32h5/stm32_crypto.c
index c0c7bfb55d..f20596aa02 100644
--- a/arch/arm/src/stm32h7/stm32_crypto.c
+++ b/arch/arm/src/stm32h5/stm32_crypto.c
@@ -35,9 +35,33 @@
#include <nuttx/crypto/crypto.h>
#include "arm_internal.h"
-#include "hardware/stm32h7x3xx_rcc.h"
-#include "hardware/stm32h7xxxx_crc.h"
-#include "hardware/stm32h7xxxx_hash.h"
+#include "hardware/stm32h5xxx_rcc.h"
+#include "hardware/stm32_crc.h"
+
+/* CRC register offsets
*****************************************************/
+
+/* CRC register addresses
***************************************************/
+
+/* CRC register bit definitions
*********************************************/
+
+/* CRC CR register */
+
+#define CRC_CR_REVOUT_SHIFT 7
+#define CRC_CR_REV_OUT_MASK CRC_CR_REVOUT
+#define CRC_CR_REV_OUT_NONE (0 << CRC_CR_REVOUT_SHIFT)
+#define CRC_CR_REV_OUT CRC_CR_REVOUT
+#define CRC_CR_REV_IN_SHIFT CRC_CR_REVIN_SHIFT
+#define CRC_CR_REV_IN_MASK CRC_CR_REVIN_MASK
+#define CRC_CR_REV_IN_NONE CRC_CR_REVIN_NONE
+#define CRC_CR_REV_IN_BYTE CRC_CR_REVIN_BYTE
+#define CRC_CR_REV_IN_HALFWORD CRC_CR_REVIN_HWORD
+#define CRC_CR_REV_IN_WORD CRC_CR_REVIN_WORD
+
+#define CRC_CR_POLYSIZE_32BIT CRC_CR_POLYSIZE_32
+#define CRC_CR_POLYSIZE_16BIT CRC_CR_POLYSIZE_16
+#define CRC_CR_POLYSIZE_8BIT CRC_CR_POLYSIZE_8
+#define CRC_CR_POLYSIZE_7BIT CRC_CR_POLYSIZE_7
+#define CRC_CR_RESET_SHIFT 0
/* Following constants used in reverse32() to reverse
* bit order of 32-bit value
@@ -413,11 +437,11 @@ static int crc32_init(struct stm32_crypto_data *sw)
/* Clear/set AHB4RSTR to reset CRC peripheral */
- regval = stm32crypto_getreg32(STM32_RCC_AHB4RSTR);
- regval |= RCC_AHB4RSTR_CRCRST;
- stm32crypto_putreg32(regval, STM32_RCC_AHB4RSTR);
- regval &= ~RCC_AHB4RSTR_CRCRST;
- stm32crypto_putreg32(regval, STM32_RCC_AHB4RSTR);
+ regval = stm32crypto_getreg32(STM32_RCC_AHB1RSTR);
+ regval |= RCC_AHB1RSTR_CRCRST;
+ stm32crypto_putreg32(regval, STM32_RCC_AHB1RSTR);
+ regval &= ~RCC_AHB1RSTR_CRCRST;
+ stm32crypto_putreg32(regval, STM32_RCC_AHB1RSTR);
leave_critical_section(flags);
}
@@ -504,250 +528,6 @@ static int crc32_final(struct stm32_crypto_data *sw,
caddr_t digest)
return 0;
}
-static int hash_init(struct stm32_crypto_data *sw)
-{
- irqstate_t flags;
- uint32_t regval;
-
- stm32cryptoinfo("");
-
- if (!g_stm32_hash_initialized)
- {
- g_stm32_hash_initialized = true;
-
- flags = enter_critical_section();
-
- /* Clear/set AHB2RSTR to reset CRYP peripheral */
-
- regval = stm32crypto_getreg32(STM32_RCC_AHB2RSTR);
- regval |= RCC_AHB2RSTR_HASHRST;
- stm32crypto_putreg32(regval, STM32_RCC_AHB2RSTR);
- regval &= ~RCC_AHB2RSTR_HASHRST;
- stm32crypto_putreg32(regval, STM32_RCC_AHB2RSTR);
-
- leave_critical_section(flags);
- }
-
- /* Set the algorithm and digest size */
-
- regval = 0;
- switch (sw->hw_alg)
- {
- case CRYPTO_SHA1:
- case CRYPTO_SHA1_HMAC:
- regval = HASH_CR_ALGO_SHA1;
- sw->u.hash.dsize = 20;
- break;
- case CRYPTO_MD5:
- case CRYPTO_MD5_HMAC:
- regval = HASH_CR_ALGO_MD5;
- sw->u.hash.dsize = 16;
- break;
- case CRYPTO_SHA2_224:
- case CRYPTO_SHA2_224_HMAC:
- regval = HASH_CR_ALGO_SHA2_224;
- sw->u.hash.dsize = 28;
- break;
- case CRYPTO_SHA2_256:
- case CRYPTO_SHA2_256_HMAC:
- regval = HASH_CR_ALGO_SHA2_256;
- sw->u.hash.dsize = 32;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* If HMAC set mode, and key is large set HASH_CR_LKEY bit */
-
- if (sw->u.hash.hmac)
- {
- regval |= HASH_CR_MODE_HMAC;
- stm32cryptoinfo("klen %" PRIx32 "", sw->u.hash.klen);
- if (sw->u.hash.klen > 64)
- {
- regval |= HASH_CR_LKEY_GT_64;
- }
- }
-
- regval |= HASH_CR_INIT; /* set init to configure HASH algorithm */
- regval |= HASH_CR_DATATYPE_8; /* 8-bit data... */
- stm32crypto_putreg32(regval, STM32_HASH_CR);
-
- sw->u.hash.rlen = 0;
- sw->u.hash.rdata = 0;
-
- return 0;
-}
-
-static int hash_update(struct stm32_crypto_data *sw,
- uint8_t *buf, uint32_t len)
-{
- const uint8_t *in_byte = buf;
- const uint32_t *in_block;
- int ret;
-
- stm32cryptoinfo("buf %" PRIxPTR " len %" PRIu32 "",
- (uintptr_t)buf, len);
-
- if (len == 0)
- {
- return 0;
- }
-
- /* If any remainder leftover from previous accumulation
- * then accumulate them into hash.rdata to
- * push into DIN
- */
-
- if (sw->u.hash.rlen)
- {
- while (sw->u.hash.rlen < sizeof(uint32_t))
- {
- if (!len)
- {
- break;
- }
-
- sw->u.hash.rdata |= (in_byte[0] << (8 * sw->u.hash.rlen));
- in_byte++;
- sw->u.hash.rlen++;
- len--;
- }
-
- /* If hash_rlen still not sizeof(uint32_t) then input buffer
- * doesn't hold enough bytes to write into DIN.
- */
-
- if (sw->u.hash.rlen < sizeof(uint32_t))
- {
- return 0;
- }
-
- stm32crypto_putreg32(sw->u.hash.rdata, STM32_HASH_DIN);
- sw->u.hash.rlen = 0;
- sw->u.hash.rdata = 0x0;
- }
-
- in_block = (uint32_t *)in_byte;
-
- /* Loop pushing uint32_t of hash data into HASH_DIN */
-
- while (len >= sizeof(uint32_t))
- {
- ret = stm32_wait_for_clr(STM32_HASH_SR, HASH_SR_BUSY,
- STM32H7_HASH_TIMEOUT);
- if (ret < 0)
- {
- return ret;
- }
-
- stm32crypto_putreg32(*in_block, STM32_HASH_DIN);
- in_block++;
- len -= sizeof(uint32_t);
- }
-
- /* Accumulate any remaining bytes into hash.rdata */
-
- if (len)
- {
- stm32cryptoinfo("len %" PRIu32 " hash.rlen: %" PRIu32 "",
- len, sw->u.hash.rlen);
- in_byte = (uint8_t *)in_block;
- while (len)
- {
- sw->u.hash.rdata |= (in_byte[0] << (8 * sw->u.hash.rlen));
- sw->u.hash.rlen++;
- in_byte++;
- len--;
- }
- }
-
- return 0;
-}
-
-static int hash_final(struct stm32_crypto_data *sw, caddr_t digest,
- uint32_t wait_flag)
-{
- uint32_t *out = (uint32_t *)digest;
- uint32_t regval;
- int ret;
-
- stm32cryptoinfo("digest %" PRIxPTR "", (uintptr_t)digest);
-
- /* If any data left in rdata, write it out */
-
- if (sw->u.hash.rlen)
- {
- stm32crypto_putreg32(sw->u.hash.rdata, STM32_HASH_DIN);
- }
-
- /* Start digest calculation. Set NBLW to number of
- * bits of valid data in last write to HASH_DIN, and
- * set DCAL to start the digest calculation.
- */
-
- regval = HASH_STR_NBLW_BYTES((uint32_t)sw->u.hash.rlen);
- stm32crypto_putreg32(regval, STM32_HASH_STR);
-
- /* Set DCAL _after_ setting NBLW; have seen incorrect HMAC hash
- * result if both done at same time.
- */
-
- regval |= HASH_STR_DCAL;
- stm32crypto_putreg32(regval, STM32_HASH_STR);
-
- sw->u.hash.rlen = 0;
- sw->u.hash.rdata = 0x0;
-
- /* Wait for the digest to compute
- * (for HMAC wait for data to be ready)
- */
-
- ret = stm32_wait_for_set(STM32_HASH_SR, wait_flag,
- STM32H7_HASH_TIMEOUT);
- if (ret < 0)
- {
- return ret;
- }
-
- /* Extract the resultant hash (if desired) */
-
- if (digest)
- {
- regval = stm32crypto_getreg32(STM32_HASH_HRA0);
- *out++ = __builtin_bswap32(regval);
- regval = stm32crypto_getreg32(STM32_HASH_HRA1);
- *out++ = __builtin_bswap32(regval);
- regval = stm32crypto_getreg32(STM32_HASH_HRA2);
- *out++ = __builtin_bswap32(regval);
- regval = stm32crypto_getreg32(STM32_HASH_HRA3);
- *out++ = __builtin_bswap32(regval);
-
- if (sw->u.hash.dsize >= 20)
- {
- regval = stm32crypto_getreg32(STM32_HASH_HRA4);
- *out++ = __builtin_bswap32(regval);
- }
-
- if (sw->u.hash.dsize >= 28)
- {
- regval = stm32crypto_getreg32(STM32_HASH_HR5);
- *out++ = __builtin_bswap32(regval);
- regval = stm32crypto_getreg32(STM32_HASH_HR6);
- *out++ = __builtin_bswap32(regval);
- }
-
- if (sw->u.hash.dsize == 32)
- {
- regval = stm32crypto_getreg32(STM32_HASH_HR7);
- *out++ = __builtin_bswap32(regval);
- }
- }
-
- return 0;
-}
-
/****************************************************************************
* Name: stm32_freesession
*
@@ -781,24 +561,7 @@ static int stm32_freesession(uint64_t tid)
switch (sw->hw_alg)
{
- case CRYPTO_SHA1_HMAC:
- case CRYPTO_MD5_HMAC:
- case CRYPTO_SHA2_224_HMAC:
- case CRYPTO_SHA2_256_HMAC:
- if (sw->u.hash.key)
- {
- explicit_bzero(sw->u.hash.key, sw->u.hash.klen);
- kmm_free(sw->u.hash.key);
- }
- break;
-
case CRYPTO_CRC32:
- case CRYPTO_SHA1:
- case CRYPTO_MD5:
- case CRYPTO_SHA2_224:
- case CRYPTO_SHA2_256:
- case CRYPTO_AES_CBC:
- case CRYPTO_AES_CTR:
break;
default:
@@ -903,75 +666,10 @@ static int stm32_newsession(uint32_t *sid, struct
cryptoini *cri)
sw->hw_alg = cri->cri_alg;
switch (cri->cri_alg)
{
- case CRYPTO_MD5_HMAC:
- case CRYPTO_SHA1_HMAC:
- case CRYPTO_SHA2_224_HMAC:
- case CRYPTO_SHA2_256_HMAC:
- sw->u.hash.hmac = true;
- sw->u.hash.klen = cri->cri_klen / 8;
- sw->u.hash.key = kmm_malloc(sw->u.hash.klen);
- if (sw->u.hash.key == NULL)
- {
- return -ENOBUFS;
- }
-
- bcopy(cri->cri_key, sw->u.hash.key, sw->u.hash.klen);
-
- /* Initialize HW, push the key into DIN, wait for DINIS */
-
- ret = hash_init(sw);
- if (ret < 0)
- {
- return ret;
- }
-
- stm32cryptoinfo("Push %" PRIu32 " bytes of outer hash into DIN",
- sw->u.hash.klen);
- ret = hash_update(sw, sw->u.hash.key, sw->u.hash.klen);
- if (ret < 0)
- {
- return ret;
- }
-
- stm32cryptoinfo("Wait for DINIS");
- ret = hash_final(sw, NULL, HASH_SR_DINIS);
- if (ret < 0)
- {
- return ret;
- }
-
- break;
-
- case CRYPTO_MD5:
- case CRYPTO_SHA1:
- case CRYPTO_SHA2_224:
- case CRYPTO_SHA2_256:
- sw->u.hash.hmac = false;
- ret = hash_init(sw);
- if (ret < 0)
- {
- return ret;
- }
- break;
-
case CRYPTO_CRC32:
crc32_init(sw);
break;
- case CRYPTO_AES_CBC:
- break;
-
- case CRYPTO_AES_CTR:
- klen = cri->cri_klen / 8 - 4;
- if ((klen != 16) && (klen != 24) && (klen != 32))
- {
- /* stm32h7 aes-ctr key bits support 128, 192, or 256 */
-
- return -EINVAL;
- }
-
- break;
-
default:
stm32_freesession(i);
return -EINVAL;
@@ -1054,58 +752,6 @@ static int stm32_process(struct cryptop *crp)
switch (crd->crd_alg)
{
- case CRYPTO_MD5:
- case CRYPTO_SHA1:
- case CRYPTO_SHA2_224:
- case CRYPTO_SHA2_256:
- if (crd->crd_flags & CRD_F_UPDATE)
- {
- return hash_update(sw, crp->crp_buf, crd->crd_len);
- }
- else
- {
- return hash_final(sw, crp->crp_mac, HASH_SR_DCIS);
- }
- break;
- case CRYPTO_MD5_HMAC:
- case CRYPTO_SHA1_HMAC:
- case CRYPTO_SHA2_224_HMAC:
- case CRYPTO_SHA2_256_HMAC:
- ret = hash_update(sw, crp->crp_buf, crd->crd_len);
- if (ret < 0 || (crd->crd_flags & CRD_F_UPDATE))
- {
- return ret;
- }
-
- /* All HMAC data has been hashed, next step is
- * 1) set DCAL and HBLW, wait for DINIS
- */
-
- ret = hash_final(sw, NULL, HASH_SR_DINIS);
- if (ret < 0)
- {
- stm32cryptoinfo("");
- return ret;
- }
-
- /* 2) Push outer hash (same as inner hash) into DIN */
-
- stm32cryptoinfo("Push %" PRIu32 " bytes of inner hash",
- sw->u.hash.klen);
-
- ret = hash_update(sw, sw->u.hash.key, sw->u.hash.klen);
- if (ret < 0)
- {
- stm32cryptoinfo("");
- return ret;
- }
-
- /* 3) normal finalization */
-
- return hash_final(sw, crp->crp_mac, HASH_SR_DCIS);
-
- break;
-
case CRYPTO_CRC32:
if (crd->crd_flags & CRD_F_UPDATE)
{
@@ -1116,22 +762,6 @@ static int stm32_process(struct cryptop *crp)
return crc32_final(sw, crp->crp_mac);
}
break;
- case CRYPTO_AES_CBC:
- return aes_cypher(crp->crp_dst, crp->crp_buf, crd->crd_len,
- crp->crp_iv, crd->crd_key, 16,
- AES_MODE_CBC, crd->crd_flags & CRD_F_ENCRYPT);
- case CRYPTO_AES_CTR:
-
- memcpy(iv, crd->crd_key + crd->crd_klen / 8 - AESCTR_NONCESIZE,
- AESCTR_NONCESIZE);
- memcpy(iv + AESCTR_NONCESIZE, crp->crp_iv, AESCTR_IVSIZE);
- memcpy(iv + AESCTR_NONCESIZE + AESCTR_IVSIZE,
- (uint8_t *)crp->crp_iv + AESCTR_IVSIZE, 4);
-
- return aes_cypher(crp->crp_dst, crp->crp_buf,
- crd->crd_len, iv, crd->crd_key,
- crd->crd_klen / 8 - AESCTR_NONCESIZE,
- AES_MODE_CTR, crd->crd_flags & CRD_F_ENCRYPT);
default:
stm32cryptoinfo("crc_alg %d", crd->crd_alg);
return -EINVAL;
@@ -1161,18 +791,6 @@ void hwcr_init(void)
memset(algs, 0, sizeof(algs));
algs[CRYPTO_CRC32] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_MD5] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_SHA2_224] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_SHA2_256] = CRYPTO_ALG_FLAG_SUPPORTED;
-
- algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_SHA2_224_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
-
- algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
- algs[CRYPTO_AES_CTR] = CRYPTO_ALG_FLAG_SUPPORTED;
crypto_register(hwcr_id, algs, stm32_newsession,
stm32_freesession, stm32_process);
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]