mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
arch/arm/src/stm32h7: Add support for CRYP peripheral
Add STM32H7 support for AES-CBC/CTR HW encryption accelerator. Add nucleo-h753zi:crypt defconfig. Signed-off-by: Peter Barada <peter.barada@gmail.com>
This commit is contained in:
parent
304b8706cb
commit
6bba29a2ba
8 changed files with 1212 additions and 4 deletions
|
|
@ -233,42 +233,47 @@ config ARCH_CHIP_STM32H750VB
|
|||
select STM32H7_STM32H7X0XX
|
||||
select STM32H7_FLASH_CONFIG_B
|
||||
select STM32H7_IO_CONFIG_V
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7+M4, 128 Kb FLASH, 1024K Kb SRAM,
|
||||
LQFP100
|
||||
with cryptographic accelerator, LQFP100
|
||||
|
||||
config ARCH_CHIP_STM32H750ZB
|
||||
bool "STM32H750ZB"
|
||||
select STM32H7_STM32H7X0XX
|
||||
select STM32H7_FLASH_CONFIG_B
|
||||
select STM32H7_IO_CONFIG_Z
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7+M4, 128 Kb FLASH, 1024K Kb SRAM,
|
||||
LQFP144
|
||||
with cryptographic accelerator, LQFP144
|
||||
|
||||
config ARCH_CHIP_STM32H750IB
|
||||
bool "STM32H750IB"
|
||||
select STM32H7_STM32H7X0XX
|
||||
select STM32H7_FLASH_CONFIG_B
|
||||
select STM32H7_IO_CONFIG_I
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7+M4, 128 Kb FLASH, 1024K Kb SRAM,
|
||||
LQFP176 or UFBGA176+25
|
||||
with cryptographic accelerator, LQFP176 or UFBGA176+25
|
||||
|
||||
config ARCH_CHIP_STM32H750XB
|
||||
bool "STM32H750XB"
|
||||
select STM32H7_STM32H7X0XX
|
||||
select STM32H7_FLASH_CONFIG_B
|
||||
select STM32H7_IO_CONFIG_X
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7+M4, 128 Kb FLASH, 1024K Kb SRAM,
|
||||
TFBGA240+25
|
||||
with cryptographic accelerator, TFBGA240+25
|
||||
|
||||
config ARCH_CHIP_STM32H753AI
|
||||
bool "STM32H753AI"
|
||||
select STM32H7_STM32H7X3XX
|
||||
select STM32H7_FLASH_CONFIG_I
|
||||
select STM32H7_IO_CONFIG_A
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, UFBGA169
|
||||
|
|
@ -278,6 +283,7 @@ config ARCH_CHIP_STM32H753BI
|
|||
select STM32H7_STM32H7X3XX
|
||||
select STM32H7_FLASH_CONFIG_I
|
||||
select STM32H7_IO_CONFIG_B
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, LQFP208
|
||||
|
|
@ -287,6 +293,7 @@ config ARCH_CHIP_STM32H753II
|
|||
select STM32H7_STM32H7X3XX
|
||||
select STM32H7_FLASH_CONFIG_I
|
||||
select STM32H7_IO_CONFIG_I
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, LQFP176/UFBGA176
|
||||
|
|
@ -296,6 +303,7 @@ config ARCH_CHIP_STM32H753VI
|
|||
select STM32H7_STM32H7X3XX
|
||||
select STM32H7_FLASH_CONFIG_I
|
||||
select STM32H7_IO_CONFIG_V
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, LQFP100/TFBGA100
|
||||
|
|
@ -305,6 +313,7 @@ config ARCH_CHIP_STM32H753XI
|
|||
select STM32H7_STM32H7X3XX
|
||||
select STM32H7_FLASH_CONFIG_I
|
||||
select STM32H7_IO_CONFIG_X
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, TFBGA240
|
||||
|
|
@ -314,6 +323,7 @@ config ARCH_CHIP_STM32H753ZI
|
|||
select STM32H7_STM32H7X3XX
|
||||
select STM32H7_FLASH_CONFIG_I
|
||||
select STM32H7_IO_CONFIG_Z
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, LQFP144
|
||||
|
|
@ -324,6 +334,7 @@ config ARCH_CHIP_STM32H7B3LI
|
|||
select STM32H7_FLASH_CONFIG_I
|
||||
select STM32H7_IO_CONFIG_L
|
||||
select STM32H7_HAVE_SMPS
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1376 Kb SRAM,
|
||||
with cryptographic accelerator, TFBGA225
|
||||
|
|
@ -335,6 +346,7 @@ config ARCH_CHIP_STM32H755II
|
|||
select STM32H7_IO_CONFIG_I
|
||||
select STM32H7_HAVE_FDCAN1
|
||||
select STM32H7_HAVE_FDCAN2
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, LQFP176/UFBGA176
|
||||
|
|
@ -346,6 +358,7 @@ config ARCH_CHIP_STM32H755XI
|
|||
select STM32H7_IO_CONFIG_X
|
||||
select STM32H7_HAVE_FDCAN1
|
||||
select STM32H7_HAVE_FDCAN2
|
||||
select STM32H7_HAVE_CRYP
|
||||
---help---
|
||||
STM32 H7 Cortex M7, 2048 Kb FLASH, 1024K Kb SRAM,
|
||||
with cryptographic accelerator, TFBGA240
|
||||
|
|
@ -759,6 +772,10 @@ config STM32H7_HAVE_RNG
|
|||
bool
|
||||
default n
|
||||
|
||||
config STM32H7_HAVE_CRYP
|
||||
bool
|
||||
default n
|
||||
|
||||
# These "hidden" settings are the OR of individual peripheral selections
|
||||
# indicating that the general capability is required.
|
||||
|
||||
|
|
@ -865,6 +882,11 @@ config STM32H7_CRC
|
|||
bool "CRC"
|
||||
default n
|
||||
|
||||
config STM32H7_CRYP
|
||||
bool "CRYP"
|
||||
default n
|
||||
depends on STM32H7_HAVE_CRYP
|
||||
|
||||
config STM32H7_BKPSRAM
|
||||
bool "Enable BKP RAM Domain"
|
||||
select STM32H7_PWR
|
||||
|
|
|
|||
|
|
@ -213,3 +213,15 @@ endif
|
|||
ifeq ($(CONFIG_STM32H7_WWDG),y)
|
||||
CHIP_CSRCS += stm32_wwdg.c
|
||||
endif
|
||||
|
||||
#ifeq ($(CONFIG_STM32H7_HASH),y)
|
||||
#CHIP_CSRCS += stm32_hash.c
|
||||
#endif
|
||||
|
||||
ifeq ($(CONFIG_STM32H7_CRYP),y)
|
||||
CHIP_CSRCS += stm32_aes.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO_CRYPTODEV_HARDWARE),y)
|
||||
CHIP_CSRCS += stm32_crypto.c
|
||||
endif
|
||||
|
|
|
|||
186
arch/arm/src/stm32h7/hardware/stm32h7xxxx_cryp.h
Normal file
186
arch/arm/src/stm32h7/hardware/stm32h7xxxx_cryp.h
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/hardware/stm32h7xxxx_cryp.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you 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 __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_CRYP_H
|
||||
#define __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_CRYP_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/* The following STM32H7 devices have a cryptographic accelerator that
|
||||
* support AES, DES/TDES:
|
||||
*
|
||||
* STM32H735ZO, STM32H750XX, STM32H753XX, STM32H755XX, STM32H757XX,
|
||||
* STM32H7B0XX, STM32H7B3XX, STM32H7S3x8, STM32H7S7X8
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* CRYP register offsets ****************************************************/
|
||||
|
||||
#define STM32_CRYP_CR_OFFSET 0x0000 /* Control Register */
|
||||
#define STM32_CRYP_SR_OFFSET 0x0004 /* Status Register */
|
||||
#define STM32_CRYP_DIN_OFFSET 0x0008 /* Data Input Register */
|
||||
#define STM32_CRYP_DOUT_OFFSET 0x000C /* Data Output Register */
|
||||
#define STM32_CRYP_DMACR_OFFSET 0x0010 /* DMA Control Register */
|
||||
#define STM32_CRYP_IMSCR_OFFSET 0x0014 /* Interrupt Mask Register */
|
||||
#define STM32_CRYP_RISR_OFFSET 0x0018 /* Raw Interrupt Status Register */
|
||||
#define STM32_CRYP_MISR_OFFSET 0x001C /* Masked Interrupt Status Register */
|
||||
|
||||
#define STM32_CRYP_K0LR_OFFSET 0x0020 /* CRYP key 0L Register */
|
||||
#define STM32_CRYP_K0RR_OFFSET 0x0024 /* CRYP key 0R Register */
|
||||
#define STM32_CRYP_K1LR_OFFSET 0x0028 /* CRYP key 1L Register */
|
||||
#define STM32_CRYP_K1RR_OFFSET 0x002c /* CRYP key 1R Register */
|
||||
#define STM32_CRYP_K2LR_OFFSET 0x0030 /* CRYP key 2L Register */
|
||||
#define STM32_CRYP_K2RR_OFFSET 0x0034 /* CRYP key 2R Register */
|
||||
#define STM32_CRYP_K3LR_OFFSET 0x0038 /* CRYP key 3L Register */
|
||||
#define STM32_CRYP_K3RR_OFFSET 0x003c /* CRYP key 3R Register */
|
||||
|
||||
#define STM32_CRYP_IV0LR_OFFSET 0x0040 /* CRYP Init Vector 0L Register */
|
||||
#define STM32_CRYP_IV0RR_OFFSET 0x0044 /* CRYP Init Vector 0R Register */
|
||||
#define STM32_CRYP_IV1LR_OFFSET 0x0048 /* CRYP Init Vector 1L Register */
|
||||
#define STM32_CRYP_IV1RR_OFFSET 0x004C /* CRYP Init Vector 1R Register */
|
||||
|
||||
#define STM32_CRYP_CSGCMCCM0R_OFFSET 0x0050 /* CRYP Context Swap Register 0R */
|
||||
|
||||
/* CRYP register addresses **************************************************/
|
||||
|
||||
#define STM32_CRYP_CR (STM32_CRYPTO_BASE + STM32_CRYP_CR_OFFSET)
|
||||
#define STM32_CRYP_SR (STM32_CRYPTO_BASE + STM32_CRYP_SR_OFFSET)
|
||||
#define STM32_CRYP_DIN (STM32_CRYPTO_BASE + STM32_CRYP_DIN_OFFSET)
|
||||
#define STM32_CRYP_DOUT (STM32_CRYPTO_BASE + STM32_CRYP_DOUT_OFFSET)
|
||||
#define STM32_CRYP_DMACR (STM32_CRYPTO_BASE + STM32_CRYP_DMACR_OFFSET)
|
||||
#define STM32_CRYP_IMSCR (STM32_CRYPTO_BASE + STM32_CRYP_IMSCR_OFFSET)
|
||||
#define STM32_CRYP_RISR (STM32_CRYPTO_BASE + STM32_CRYP_RISR_OFFSET)
|
||||
#define STM32_CRYP_MISR (STM32_CRYPTO_BASE + STM32_CRYP_MISR_OFFSET)
|
||||
#define STM32_CRYP_K0LR (STM32_CRYPTO_BASE + STM32_CRYP_K0LR_OFFSET)
|
||||
#define STM32_CRYP_K0RR (STM32_CRYPTO_BASE + STM32_CRYP_K0RR_OFFSET)
|
||||
#define STM32_CRYP_K1LR (STM32_CRYPTO_BASE + STM32_CRYP_K1LR_OFFSET)
|
||||
#define STM32_CRYP_K1RR (STM32_CRYPTO_BASE + STM32_CRYP_K1RR_OFFSET)
|
||||
#define STM32_CRYP_K2LR (STM32_CRYPTO_BASE + STM32_CRYP_K2LR_OFFSET)
|
||||
#define STM32_CRYP_K2RR (STM32_CRYPTO_BASE + STM32_CRYP_K2RR_OFFSET)
|
||||
#define STM32_CRYP_K3LR (STM32_CRYPTO_BASE + STM32_CRYP_K3LR_OFFSET)
|
||||
#define STM32_CRYP_K3RR (STM32_CRYPTO_BASE + STM32_CRYP_K3RR_OFFSET)
|
||||
#define STM32_CRYP_IV0LR (STM32_CRYPTO_BASE + STM32_CRYP_IV0LR_OFFSET)
|
||||
#define STM32_CRYP_IV0RR (STM32_CRYPTO_BASE + STM32_CRYP_IV0RR_OFFSET)
|
||||
#define STM32_CRYP_IV1LR (STM32_CRYPTO_BASE + STM32_CRYP_IV1LR_OFFSET)
|
||||
#define STM32_CRYP_IV1RR (STM32_CRYPTO_BASE + STM32_CRYP_IV1RR_OFFSET)
|
||||
#define STM32_CRYP_CSGCMCCM0R (STM32_CRYPTO_BASE + STM32_CRYP_CSGCMCCM0R_OFFSET)
|
||||
|
||||
/* CRYP register bit definitions ********************************************/
|
||||
|
||||
/* CRYP CR register */
|
||||
|
||||
#define CRYP_CR_GCMPH_SHIFT 16
|
||||
#define CRYP_CR_GCMPH_MASK (0x3 << CRYP_CR_GCMPH_SHIFT)
|
||||
# define CRYP_CR_GCMPH_INIT (0 << CRYP_CR_GCMPH_SHIFT)
|
||||
# define CRYP_CR_GCMPH_HEADER (1 << CRYP_CR_GCMPH_SHIFT)
|
||||
# define CRYP_CR_GCMPH_PAYLOAD (2 << CRYP_CR_GCMPH_SHIFT)
|
||||
# define CRYP_CR_GCMPH_FINAL (3 << CRYP_CR_GCMPH_SHIFT)
|
||||
#define CRYP_CR_CRYPEN (1 << 15)
|
||||
#define CRYP_CR_FFLUSH (1 << 14)
|
||||
#define CRYP_CR_KEYSIZE_SHIFT 8
|
||||
#define CRYP_CR_KEYSIZE_MASK (0x3 << CRYP_CR_KEYSIZE_SHIFT)
|
||||
# define CRYP_CR_KEYSIZE_128 (0 << CRYP_CR_KEYSIZE_SHIFT)
|
||||
# define CRYP_CR_KEYSIZE_192 (1 << CRYP_CR_KEYSIZE_SHIFT)
|
||||
# define CRYP_CR_KEYSIZE_256 (2 << CRYP_CR_KEYSIZE_SHIFT)
|
||||
#define CRYP_CR_DATATYPE_SHIFT 6
|
||||
#define CRYP_CR_DATATYPE_MASK (0x3 << CRYP_CR_DATATYPE_SHIFT)
|
||||
# define CRYP_CR_DATATYPE_LE (0 << CRYP_CR_DATATYPE_SHIFT)
|
||||
# define CRYP_CR_DATATYPE_BE (2 << CRYP_CR_DATATYPE_SHIFT)
|
||||
/* ALGOMODE straddles bits [19, 5:3] of CRYP_CR */
|
||||
#define CRYP_CR_ALGOMODE3_SHIFT 19
|
||||
#define CRYP_CR_ALGOMODE3_MASK (0x1 << CRYP_CR_ALGOMODE3_SHIFT)
|
||||
#define CRYP_CR_ALGOMODE_SHIFT 3
|
||||
#define CRYP_CR_ALGOMODE_MASK ((0xf << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| CRYP_CR_ALGOMODE3_MASK)
|
||||
# define CRYP_CR_ALGOMODE_TDES_ECB ((0 << CRYP_CR_ALGOMODE3_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_TDES_CBC ((1 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_DES_ECB ((2 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_DES_CBC ((3 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_AES_ECB ((4 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_AES_CBC ((5 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_AES_CTR ((6 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_AES_KEY_PREP ((7 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (0 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_AES_GCM ((8 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (1 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
# define CRYP_CR_ALGOMODE_AES_CCM ((9 << CRYP_CR_ALGOMODE_SHIFT) \
|
||||
| (1 << CRYP_CR_ALGOMODE_SHIFT))
|
||||
#define CRYP_CR_ALGODIR_SHIFT 2
|
||||
#define CRYP_CR_ALGODIR_MASK (1 << CRYP_CR_ALGODIR_SHIFT)
|
||||
# define CRYP_CR_ALGODIR_ENCRYPT (0 << CRYP_CR_ALGODIR_SHIFT)
|
||||
# define CRYP_CR_ALGODIR_DECRYPT (1 << CRYP_CR_ALGODIR_SHIFT)
|
||||
|
||||
/* All non-defined bits in CRYP_CR have to be set
|
||||
* to the reset value (0x00000000). Following is mask for such
|
||||
*/
|
||||
#define CRYP_CR_RESET_MASK \
|
||||
(CRYP_CR_ALGOMODE3_MASK | CRYP_CR_GCMPH_MASK | CRYP_CR_CRYPEN \
|
||||
| CRYP_CR_FFLUSH | CRYP_CR_KEYSIZE_MASK | CRYP_CR_DATATYPE_MASK \
|
||||
| CRYP_CR_ALGOMODE_MASK | CRYP_CR_ALGODIR_MASK)
|
||||
|
||||
/* CRYP SR register */
|
||||
|
||||
#define CRYP_SR_BUSY (1 << 4) /* BUSY */
|
||||
#define CRYP_SR_OFFU (1 << 3) /* Output Fifo Full */
|
||||
#define CRYP_SR_OFNE (1 << 2) /* Output Fifo Not Empty */
|
||||
#define CRYP_SR_IFNF (1 << 1) /* Input Fifo Not Full */
|
||||
#define CRYP_SR_IFEM (1 << 0) /* Input Fifo Empty */
|
||||
|
||||
/* CRYP DMACR register */
|
||||
|
||||
#define CRYP_DMACR_DOEN (1 << 1) /* DMA Output Enable */
|
||||
#define CRYP_DMACR_DIEN (1 << 0) /* DMA Input Enable */
|
||||
|
||||
/* CRYP IMSCR register */
|
||||
|
||||
#define CRYP_IMSCR_OUTIM (1 << 1) /* Output Fifo Service Mask */
|
||||
#define CRYP_IMSCR_INIM (1 << 0) /* Input Fifo Service Mask */
|
||||
|
||||
/* CRYP RISR register */
|
||||
|
||||
#define CRYP_RISR_OUTRIS (1 << 1)
|
||||
#define CRYP_RISR_INRIS (1 << 0)
|
||||
|
||||
/* CRYP MISR register */
|
||||
|
||||
#define CRYP_MISR_OUTMIS (1 << 1)
|
||||
#define CRYP_MISR_INMIS (1 << 0)
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32H7X3XX_CRYP_H */
|
||||
705
arch/arm/src/stm32h7/stm32_aes.c
Normal file
705
arch/arm/src/stm32h7/stm32_aes.c
Normal file
|
|
@ -0,0 +1,705 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/stm32_aes.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <nuttx/debug.h>
|
||||
|
||||
#include <nuttx/crypto/crypto.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "chip.h"
|
||||
#include "stm32_rcc.h"
|
||||
#include "stm32_aes.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
/* Any reserved bits in CRYP_CR must be kept at reset value (0x0) */
|
||||
#define STM32AES_CLEAR_RESERVED_CR_BITS(regval) \
|
||||
(regval & CRYP_CR_RESET_MASK)
|
||||
|
||||
/* #define CONFIG_STM32_CRYP_DEBUG */
|
||||
|
||||
#ifdef CONFIG_STM32_CRYP_DEBUG
|
||||
#define cryp_getreg32(reg) stm32aes_getreg32(__FUNCTION__, __LINE__, reg)
|
||||
#define cryp_putreg32(val, reg) stm32aes_putreg32(__FUNCTION__, __LINE__, val, reg)
|
||||
#define crypinfo(func, line, format, ...) \
|
||||
__arch_syslog(LOG_INFO, "%s:%d" format, func, line, ##__VA_ARGS__)
|
||||
#else
|
||||
#define crypinfo(func, line, format, ...)
|
||||
#define cryp_getreg32(reg) getreg32(reg)
|
||||
#define cryp_putreg32(val, reg) putreg32(val, reg)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void stm32aes_enable(bool on);
|
||||
static int stm32aes_setkey(const void *key, size_t keysize);
|
||||
static void stm32aes_setiv(const void *iv);
|
||||
static void stm32aes_encryptblock(void *block_out,
|
||||
const void *block_in);
|
||||
static int stm32aes_setup_cr(int mode, int encrypt,
|
||||
const void *key, size_t keysize);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static mutex_t g_stm32aes_lock = NXMUTEX_INITIALIZER;
|
||||
static bool g_stm32aes_initdone = false;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef STM32_CRYP_DEBUG
|
||||
|
||||
struct rn
|
||||
{
|
||||
FAR const char *name;
|
||||
uint32_t regaddr;
|
||||
};
|
||||
|
||||
static struct rn stm32aes_regnames [] =
|
||||
{
|
||||
{
|
||||
"RCC_AHB2RSTR",
|
||||
STM32_RCC_AHB2RSTR,
|
||||
},
|
||||
|
||||
{
|
||||
"RCC_AHB2ENR",
|
||||
STM32_RCC_AHB2ENR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_CR",
|
||||
STM32_CRYP_CR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_SR",
|
||||
STM32_CRYP_SR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_DIN",
|
||||
STM32_CRYP_DIN,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_DOUT",
|
||||
STM32_CRYP_DOUT,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_DMACR",
|
||||
STM32_CRYP_DMACR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_IMSCR",
|
||||
STM32_CRYP_IMSCR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_RISR",
|
||||
STM32_CRYP_RISR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_MISR",
|
||||
STM32_CRYP_MISR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K0LR",
|
||||
STM32_CRYP_K0LR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K0RR",
|
||||
STM32_CRYP_K0RR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K1LR",
|
||||
STM32_CRYP_K1LR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K1RR",
|
||||
STM32_CRYP_K1RR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K2LR",
|
||||
STM32_CRYP_K2LR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K2RR",
|
||||
STM32_CRYP_K2RR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K3LR",
|
||||
STM32_CRYP_K3LR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_K3RR",
|
||||
STM32_CRYP_K3RR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_IV0LR",
|
||||
STM32_CRYP_IV0LR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_IV0RR",
|
||||
STM32_CRYP_IV0RR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_IV1LR",
|
||||
STM32_CRYP_IV1LR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_IV1RR",
|
||||
STM32_CRYP_IV1RR,
|
||||
},
|
||||
|
||||
{
|
||||
"CRYP_CSGCMCCM0R",
|
||||
STM32_CRYP_CSGCMCCM0R,
|
||||
},
|
||||
};
|
||||
|
||||
const char *stm32aes_regname(uint32_t regaddr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nitems(stm32aes_regnames); ++i)
|
||||
{
|
||||
if (stm32aes_regnames[i].regaddr == regaddr)
|
||||
{
|
||||
return stm32aes_regnames[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return "???";
|
||||
}
|
||||
|
||||
static uint32_t stm32aes_getreg32(const char *func, int line,
|
||||
uint32_t regaddr)
|
||||
{
|
||||
const char *regname = stm32aes_regname(regaddr);
|
||||
char buf[128];
|
||||
uint32_t val;
|
||||
|
||||
val = getreg32(regaddr);
|
||||
snprintf(buf, sizeof(buf), "%08" PRIx32 "(%s)<=%08" PRIx32 "",
|
||||
regaddr, regname, val);
|
||||
crypinfo(func, line, " %s", buf);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void stm32aes_putreg32(const char *func, int line,
|
||||
uint32_t val, uint32_t regaddr)
|
||||
{
|
||||
const char *regname = stm32aes_regname(regaddr);
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%08" PRIx32 "(%s)=>%08" PRIx32 "",
|
||||
regaddr, regname, val);
|
||||
putreg32(val, regaddr);
|
||||
crypinfo(func, line, " %s", buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void stm32aes_enable(bool on)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = cryp_getreg32(STM32_CRYP_CR);
|
||||
if (on)
|
||||
{
|
||||
if (regval & CRYP_CR_CRYPEN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
regval |= CRYP_CR_CRYPEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(regval & CRYP_CR_CRYPEN))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
regval &= ~CRYP_CR_CRYPEN;
|
||||
}
|
||||
|
||||
regval = STM32AES_CLEAR_RESERVED_CR_BITS(regval);
|
||||
cryp_putreg32(regval, STM32_CRYP_CR);
|
||||
}
|
||||
|
||||
static void stm32aes_wait_not_busy(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
do
|
||||
{
|
||||
regval = cryp_getreg32(STM32_CRYP_SR);
|
||||
}
|
||||
while (regval & CRYP_SR_BUSY);
|
||||
}
|
||||
|
||||
static int stm32aes_setkey(const void *key, size_t keysize)
|
||||
{
|
||||
uint32_t *in = (uint32_t *)key;
|
||||
|
||||
stm32aes_wait_not_busy();
|
||||
|
||||
if (keysize == 32)
|
||||
{
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K0LR); /* [255:224] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K0RR); /* [223:192] */
|
||||
in++;
|
||||
}
|
||||
|
||||
if (keysize >= 24)
|
||||
{
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K1LR); /* [191:160] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K1RR); /* [159:128] */
|
||||
in++;
|
||||
}
|
||||
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K2LR); /* [127:96] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K2RR); /* [95:64] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K3LR); /* [63:32] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_K3RR); /* [31:0] */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stm32aes_setiv(const void *iv)
|
||||
{
|
||||
uint32_t *in = (uint32_t *)iv;
|
||||
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_IV0LR); /* [127:96] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_IV0RR); /* [95:64] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_IV1LR); /* [63:32] */
|
||||
in++;
|
||||
cryp_putreg32(__builtin_bswap32(*in), STM32_CRYP_IV1RR); /* [31:0] */
|
||||
}
|
||||
|
||||
static void stm32aes_encryptblock(void *block_out,
|
||||
const void *block_in)
|
||||
{
|
||||
uint32_t *in = (uint32_t *)block_in;
|
||||
uint32_t *out = (uint32_t *)block_out;
|
||||
|
||||
cryp_putreg32(*in, STM32_CRYP_DIN);
|
||||
in++;
|
||||
cryp_putreg32(*in, STM32_CRYP_DIN);
|
||||
in++;
|
||||
cryp_putreg32(*in, STM32_CRYP_DIN);
|
||||
in++;
|
||||
cryp_putreg32(*in, STM32_CRYP_DIN);
|
||||
|
||||
stm32aes_wait_not_busy();
|
||||
|
||||
*out = cryp_getreg32(STM32_CRYP_DOUT);
|
||||
out++;
|
||||
*out = cryp_getreg32(STM32_CRYP_DOUT);
|
||||
out++;
|
||||
*out = cryp_getreg32(STM32_CRYP_DOUT);
|
||||
out++;
|
||||
*out = cryp_getreg32(STM32_CRYP_DOUT);
|
||||
}
|
||||
|
||||
static void stm32aes_set_datatype(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = cryp_getreg32(STM32_CRYP_CR);
|
||||
regval |= CRYP_CR_DATATYPE_BE;
|
||||
regval = STM32AES_CLEAR_RESERVED_CR_BITS(regval);
|
||||
cryp_putreg32(regval, STM32_CRYP_CR);
|
||||
}
|
||||
|
||||
static int stm32aes_setup_cr(int mode, int encrypt,
|
||||
const void *key, size_t keysize)
|
||||
{
|
||||
int ret;
|
||||
uint32_t regval = 0;
|
||||
|
||||
/** 1) Configure algorithm/chaining mode through ALGOMODE/AOGODIR
|
||||
* bits; also set KEYSIZE
|
||||
* - when decrypting and mode is AES-ECB or AES-CBC, an initial
|
||||
* key derivation must be performed (see section 35.4.7)
|
||||
*/
|
||||
|
||||
/* Set KEYSIZE field */
|
||||
|
||||
switch (keysize)
|
||||
{
|
||||
case 16:
|
||||
regval |= CRYP_CR_KEYSIZE_128;
|
||||
break;
|
||||
case 24:
|
||||
regval |= CRYP_CR_KEYSIZE_192;
|
||||
break;
|
||||
case 32:
|
||||
regval |= CRYP_CR_KEYSIZE_256;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set symmetric key */
|
||||
|
||||
ret = stm32aes_setkey(key, keysize);
|
||||
if (ret)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If decrypting and mode is AES-ECB or AES-CBC need to perform
|
||||
* key derivation first
|
||||
*/
|
||||
|
||||
if (!encrypt)
|
||||
{
|
||||
/* Set DECRYPT field */
|
||||
|
||||
regval |= CRYP_CR_ALGODIR_DECRYPT;
|
||||
if ((mode == AES_MODE_ECB) || (mode == AES_MODE_CBC))
|
||||
{
|
||||
regval |= CRYP_CR_ALGOMODE_AES_KEY_PREP;
|
||||
cryp_putreg32(regval, STM32_CRYP_CR);
|
||||
|
||||
/* Start key derivation and wait for not BUSY */
|
||||
|
||||
stm32aes_enable(true);
|
||||
stm32aes_wait_not_busy();
|
||||
/* CRYPEN is automatically cleared. Clear
|
||||
* ALGOMODE field to allow following code to set
|
||||
* to the proper mode
|
||||
*/
|
||||
|
||||
regval &= ~CRYP_CR_ALGOMODE_MASK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Encrypting, make sure DECRYPT flag is cleared */
|
||||
|
||||
regval &= ~CRYP_CR_ALGODIR_DECRYPT;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case AES_MODE_ECB:
|
||||
regval |= CRYP_CR_ALGOMODE_AES_ECB;
|
||||
break;
|
||||
|
||||
case AES_MODE_CBC:
|
||||
regval |= CRYP_CR_ALGOMODE_AES_CBC;
|
||||
break;
|
||||
|
||||
case AES_MODE_CTR:
|
||||
regval |= CRYP_CR_ALGOMODE_AES_CTR;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regval = STM32AES_CLEAR_RESERVED_CR_BITS(regval);
|
||||
cryp_putreg32(regval, STM32_CRYP_CR);
|
||||
|
||||
stm32aes_wait_not_busy();
|
||||
|
||||
stm32aes_set_datatype();
|
||||
|
||||
stm32aes_wait_not_busy();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int stm32_aesreset(void)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Clear/set AHB2RSTR to reset CRYP peripheral */
|
||||
|
||||
regval = cryp_getreg32(STM32_RCC_AHB2RSTR);
|
||||
regval |= RCC_AHB2RSTR_CRYPTRST;
|
||||
cryp_putreg32(regval, STM32_RCC_AHB2RSTR);
|
||||
regval &= ~RCC_AHB2RSTR_CRYPTRST;
|
||||
cryp_putreg32(regval, STM32_RCC_AHB2RSTR);
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int stm32_aesinitialize(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = cryp_getreg32(STM32_RCC_AHB2ENR);
|
||||
regval |= RCC_AHB2ENR_CRYPTEN;
|
||||
cryp_putreg32(regval, STM32_RCC_AHB2ENR);
|
||||
|
||||
stm32aes_enable(false);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void stm32aes_flush_fifos(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = cryp_getreg32(STM32_CRYP_CR);
|
||||
regval |= CRYP_CR_FFLUSH;
|
||||
regval = STM32AES_CLEAR_RESERVED_CR_BITS(regval);
|
||||
cryp_putreg32(regval, STM32_CRYP_CR);
|
||||
}
|
||||
|
||||
/* See section 35.4.5 CRYP procedure to perform a cipher operation:
|
||||
* 0) Clear CRYPEN bit
|
||||
* 1) Configure algorithm/chaining mode through ALGOMODE/AOGODIR
|
||||
* bits; also set KEYSIZE
|
||||
* - when decrypting and mode is AES-ECB or AES-CBC, an initial
|
||||
* key derivation must be performed (see section 35.4.7)
|
||||
* 2) When previous step is complete (and when applicable), write
|
||||
* key into CRYP_KxL/R registers (see section 35.4.17)
|
||||
* 3) Configure DATATYPE
|
||||
* 4) When required(eg for CBC or CTR chaining modes), write the
|
||||
* initialization vectors into CRYP_IVx(L/R)R.
|
||||
* 5) Flush the IN/OUT FIFOS by setting FFLUSH.
|
||||
*
|
||||
* Warning: If ECB/CBC mode is selected and data is not a multiple
|
||||
* of 64 bits (for DES) or 128 bits (for AES), the 2nd and last
|
||||
* block management is more comples; see Section 35.4.8
|
||||
*
|
||||
* Appending data using the CPU in Polling mode
|
||||
* 1) Enable the cryptographic processor by setting to 1 the CRYPEN
|
||||
* bit in the CRYP_CR register.
|
||||
* 2) Write data in the IN FIFO (one block or until the FIFO is full).
|
||||
* 3) Repeat the following sequence until the second last block of
|
||||
* data has been processed:
|
||||
* a) Wait until the not-empty-flag OFNE is set to 1, then read
|
||||
* the OUT FIFO (one block or until the FIFO is empty).
|
||||
* b) Wait until the not-full-flag IFNF is set to 1, then write
|
||||
* the IN FIFO (one block or until the FIFO is full) except
|
||||
* if it is the last block.
|
||||
* 4) The BUSY bit is set automatically by the cryptographic processor.
|
||||
* At the end of the processing, the BUSY bit returns to 0 and both
|
||||
* FIFOs are empty (IN FIFO empty flag IFEM = 1 and OUT FIFO not
|
||||
* empty flag OFNE = 0).
|
||||
* 5) If the next processing block is the last block, the CPU must pad
|
||||
* (when applicable) the data with zeroes to obtain a complete block
|
||||
* 6) When the operation is complete, the cryptographic processor can
|
||||
* be disabled by clearing the CRYPEN bit in CRYP_CR register.
|
||||
*
|
||||
* 35.4.7 Preparing the CRYP AES key for decryption:
|
||||
*
|
||||
* When performing an AES ECB or CBC decryption, the AES key
|
||||
* has to be prepared. Indeed, in AES encryption the round 0 key
|
||||
* is the one stored in the key registers, and AES decryption must
|
||||
* start using the last round key. Hence, as the encryption key
|
||||
* is stored in memory, a special key scheduling must be performed
|
||||
* to obtain the decryption key. This preparation is not required
|
||||
* in any other AES modes than ECB or CBC decryption.
|
||||
*
|
||||
* When the cryptographic processor is disabled (CRYPEN = 0),
|
||||
* the CRYP key preparation process is performed as follows:
|
||||
* 1) Program ALGOMODE bits to 0x7 and ALGODIR to 0x0 in CRYP_CR.
|
||||
* In addition, configure the key length with the KEYSIZE bits.
|
||||
* 2) Write the symmetric key to the CRYP_KxL/R registers, as
|
||||
* described in Section 35.4.17: CRYP key registers.
|
||||
* 3) Enable the cryptographic processor by setting the CRYPEN bit
|
||||
* in the CRYP_CR register. It immediately starts an AES round
|
||||
* for key preparation (BUSY = 1).
|
||||
* 4) Wait until the BUSY bit is cleared in the CRYP_SR register.
|
||||
* Then update ALGOMODE bits in the CRYP_CR register to select
|
||||
* the correct chaining mode, that is 0x4 for ECB or 0x5 for CBC.
|
||||
* 5) The AES key is available in the CRYP key registers, ready
|
||||
* to use for decryption.
|
||||
* Note: As the CRYPEN bitfield is reset by hardware at the end of
|
||||
* the key preparation, the application software must set it
|
||||
* again for the next operation.
|
||||
* The latency of the key preparation operation is 14, 16 or 18
|
||||
* clock cycles depending on the key size (128, 192 or 256 bits).
|
||||
*
|
||||
* 35.4.8 CRYP stealing and data padding
|
||||
*
|
||||
* When using DES or AES algorithm in ECB or CBC modes to manage
|
||||
* messages that are not multiple of the block size (64 bits for DES,
|
||||
* 128 bits for AES), use ciphertext stealing techniques such as those
|
||||
* described in NIST Special Publication 800-38A, Recommendation
|
||||
* for Block Cipher Modes of Operation: Three Variants of Ciphertext
|
||||
* Stealing for CBC Mode. Since the cryptographic processor does not
|
||||
* implement such techniques, the last two blocks must be handled in
|
||||
* a special way by the application.
|
||||
*
|
||||
* Note: Ciphertext stealing techniques are not documented in this
|
||||
* reference manual.
|
||||
*
|
||||
* Similarly, when the AES algorithm is used in other modes than ECB
|
||||
* or CBC, incomplete input data blocks (i.e. block shorter than 128
|
||||
* bits) have to be padded with zeroes by the application prior to
|
||||
* encryption (i.e. extra bits should be appended to the trailing end
|
||||
* of the data string). After decryption, the extra bits have to be
|
||||
* discarded. The cryptographic processor does not implement automatic
|
||||
* data padding operation to the last block, so the application should
|
||||
* follow the recommendation given in Section 35.4.5: CRYP procedure to
|
||||
* perform a cipher operation to manage messages that are not multiple
|
||||
* of 128 bits.
|
||||
*
|
||||
* Note: Padding data are swapped in a similar way as normal data,
|
||||
* according to the DATATYPE field in CRYP_CR register (see
|
||||
* Section 35.4.16: CRYP data registers and data swapping for
|
||||
* details).
|
||||
*/
|
||||
|
||||
int aes_cypher(void *out, const void *in, size_t size,
|
||||
const void *iv, const void *key, size_t keysize,
|
||||
int mode, int encrypt)
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
/* CRYP peripheral clock is already enabled;
|
||||
* make sure it gets reset (once)
|
||||
*/
|
||||
|
||||
if (!g_stm32aes_initdone)
|
||||
{
|
||||
ret = stm32_aesreset();
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret; /* AES init failed */
|
||||
}
|
||||
|
||||
g_stm32aes_initdone = true;
|
||||
}
|
||||
|
||||
if ((size & (AES_BLOCK_SIZE - 1)) != 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (keysize != 16 && keysize != 24 && keysize != 32)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = nxmutex_lock(&g_stm32aes_lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* AES must be disabled before changing mode, key or IV. */
|
||||
|
||||
stm32aes_enable(false);
|
||||
ret = stm32aes_setup_cr(mode, encrypt, key, keysize);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (iv != NULL)
|
||||
{
|
||||
stm32aes_setiv(iv);
|
||||
}
|
||||
|
||||
stm32aes_wait_not_busy();
|
||||
stm32aes_flush_fifos();
|
||||
stm32aes_wait_not_busy();
|
||||
|
||||
stm32aes_enable(true);
|
||||
|
||||
while (size)
|
||||
{
|
||||
stm32aes_encryptblock(out, in);
|
||||
out = (uint8_t *)out + AES_BLOCK_SIZE;
|
||||
in = (uint8_t *)in + AES_BLOCK_SIZE;
|
||||
size -= AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
stm32aes_enable(false);
|
||||
|
||||
out:
|
||||
nxmutex_unlock(&g_stm32aes_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
58
arch/arm/src/stm32h7/stm32_aes.h
Normal file
58
arch/arm/src/stm32h7/stm32_aes.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/stm32_aes.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you 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 __ARCH_ARM_SRC_STM32H7_STM32_AES_H
|
||||
#define __ARCH_ARM_SRC_STM32H7_STM32_AES_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/* For simplicity support STM32753ZI, not sure what other STM32H7
|
||||
* variants include CRYP
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_STM32H7_HAVE_CRYP
|
||||
# include "hardware/stm32h7xxxx_cryp.h"
|
||||
#else
|
||||
# error "Unknown chip for AES"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_STM32H7_STM32_AES_H */
|
||||
163
arch/arm/src/stm32h7/stm32_crypto.c
Normal file
163
arch/arm/src/stm32h7/stm32_crypto.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/stm32_crypto.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/debug.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <crypto/cryptodev.h>
|
||||
#include <crypto/xform.h>
|
||||
#include <nuttx/crypto/crypto.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t g_stm32_sesnum = 0;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_newsession
|
||||
*
|
||||
* Description:
|
||||
* create new session for crypto.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stm32_newsession(uint32_t *sid, struct cryptoini *cri)
|
||||
{
|
||||
int klen;
|
||||
|
||||
if (sid == NULL || cri == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (cri->cri_alg)
|
||||
{
|
||||
case CRYPTO_AES_CBC:
|
||||
*sid = g_stm32_sesnum++;
|
||||
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;
|
||||
}
|
||||
|
||||
*sid = g_stm32_sesnum++;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_freesession
|
||||
*
|
||||
* Description:
|
||||
* free session.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stm32_freesession(uint64_t tid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_process
|
||||
*
|
||||
* Description:
|
||||
* process session to use hardware algorithm.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stm32_process(struct cryptop *crp)
|
||||
{
|
||||
struct cryptodesc *crd;
|
||||
uint8_t iv[AESCTR_BLOCKSIZE];
|
||||
|
||||
for (crd = crp->crp_desc; crd; crd = crd->crd_next)
|
||||
{
|
||||
switch (crd->crd_alg)
|
||||
{
|
||||
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:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hwcr_init
|
||||
*
|
||||
* Description:
|
||||
* register the hardware crypto driver.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void hwcr_init(void)
|
||||
{
|
||||
int hwcr_id;
|
||||
int algs[CRYPTO_ALGORITHM_MAX + 1];
|
||||
|
||||
hwcr_id = crypto_get_driverid(0);
|
||||
DEBUGASSERT(hwcr_id >= 0);
|
||||
|
||||
memset(algs, 0, sizeof(algs));
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -326,6 +326,12 @@ static inline void rcc_enableahb2(void)
|
|||
regval |= RCC_AHB2ENR_RNGEN;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32H7_CRYP
|
||||
/* Cryptographic clock enable */
|
||||
|
||||
regval |= RCC_AHB2ENR_CRYPTEN;
|
||||
#endif
|
||||
|
||||
putreg32(regval, STM32_RCC_AHB2ENR); /* Enable peripherals */
|
||||
}
|
||||
|
||||
|
|
|
|||
56
boards/arm/stm32h7/nucleo-h753zi/configs/crypto/defconfig
Normal file
56
boards/arm/stm32h7/nucleo-h753zi/configs/crypto/defconfig
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_NSH_DISABLE_IFCONFIG is not set
|
||||
# CONFIG_NSH_DISABLE_PS is not set
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
# CONFIG_TESTING_CRYPTO_3DES_CBC is not set
|
||||
# CONFIG_TESTING_CRYPTO_AES_XTS is not set
|
||||
# CONFIG_TESTING_CRYPTO_HMAC is not set
|
||||
CONFIG_ALLOW_BSD_COMPONENTS=y
|
||||
CONFIG_ARCH="arm"
|
||||
CONFIG_ARCH_BOARD="nucleo-h753zi"
|
||||
CONFIG_ARCH_BOARD_NUCLEO_H753ZI=y
|
||||
CONFIG_ARCH_CHIP="stm32h7"
|
||||
CONFIG_ARCH_CHIP_STM32H753ZI=y
|
||||
CONFIG_ARCH_CHIP_STM32H7=y
|
||||
CONFIG_ARCH_CHIP_STM32H7_CORTEXM7=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARMV7M_DCACHE=y
|
||||
CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
|
||||
CONFIG_ARMV7M_DTCM=y
|
||||
CONFIG_ARMV7M_ICACHE=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=43103
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_CRYPTO=y
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_CRYPTODEV=y
|
||||
CONFIG_CRYPTO_CRYPTODEV_HARDWARE=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LINE_MAX=64
|
||||
CONFIG_MM_REGIONS=4
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_RAM_SIZE=245760
|
||||
CONFIG_RAM_START=0x20010000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_START_DAY=6
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2011
|
||||
CONFIG_STM32H7_CRYP=y
|
||||
CONFIG_STM32H7_USART3=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_TASK_NAME_SIZE=0
|
||||
CONFIG_TESTING_CRYPTO=y
|
||||
CONFIG_TESTING_CRYPTO_STACKSIZE=4096
|
||||
CONFIG_USART3_SERIAL_CONSOLE=y
|
||||
Loading…
Add table
Add a link
Reference in a new issue