|
|
@ -17,33 +17,24 @@
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <mpu.h>
|
|
|
|
#include <secure_aes.h>
|
|
|
|
#include <secure_aes.h>
|
|
|
|
#include STM32_HAL_H
|
|
|
|
#include STM32_HAL_H
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stm32u5xx_hal_cryp.h>
|
|
|
|
#include <stm32u5xx_hal_cryp.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "memzero.h"
|
|
|
|
#include "model.h"
|
|
|
|
|
|
|
|
#include "syscall.h"
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef KERNEL_MODE
|
|
|
|
#include "memzero.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define KERNEL_UNPRIVILEGED_SIZE 32
|
|
|
|
#define AES_BLOCK_SIZE 16
|
|
|
|
#define AES_BLOCK_SIZE 16
|
|
|
|
|
|
|
|
|
|
|
|
secbool secure_aes_init(void) {
|
|
|
|
#ifdef KERNEL_MODE
|
|
|
|
RCC_OscInitTypeDef osc_init_def = {0};
|
|
|
|
|
|
|
|
osc_init_def.OscillatorType = RCC_OSCILLATORTYPE_SHSI;
|
|
|
|
|
|
|
|
osc_init_def.SHSIState = RCC_SHSI_ON;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Enable SHSI clock
|
|
|
|
|
|
|
|
if (HAL_RCC_OscConfig(&osc_init_def) != HAL_OK) {
|
|
|
|
|
|
|
|
return secfalse;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Enable SAES peripheral clock
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_CLK_ENABLE();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sectrue;
|
|
|
|
#include "irq.h"
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void secure_aes_load_bhk(void) {
|
|
|
|
static void secure_aes_load_bhk(void) {
|
|
|
|
TAMP->BKP0R;
|
|
|
|
TAMP->BKP0R;
|
|
|
@ -58,19 +49,182 @@ static void secure_aes_load_bhk(void) {
|
|
|
|
|
|
|
|
|
|
|
|
static uint32_t get_keysel(secure_aes_keysel_t key) {
|
|
|
|
static uint32_t get_keysel(secure_aes_keysel_t key) {
|
|
|
|
switch (key) {
|
|
|
|
switch (key) {
|
|
|
|
case SECURE_AES_KEY_DHUK:
|
|
|
|
case SECURE_AES_KEY_DHUK_SP:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_DHUK_SN:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_DHUK_NP:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_DHUK_NN:
|
|
|
|
return CRYP_KEYSEL_HW;
|
|
|
|
return CRYP_KEYSEL_HW;
|
|
|
|
case SECURE_AES_KEY_BHK:
|
|
|
|
case SECURE_AES_KEY_BHK:
|
|
|
|
return CRYP_KEYSEL_SW;
|
|
|
|
return CRYP_KEYSEL_SW;
|
|
|
|
case SECURE_AES_KEY_XORK:
|
|
|
|
case SECURE_AES_KEY_XORK_SP:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_XORK_SN:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_XORK_NP:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_XORK_NN:
|
|
|
|
return CRYP_KEYSEL_HSW;
|
|
|
|
return CRYP_KEYSEL_HSW;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static secbool is_key_supported(secure_aes_keysel_t key) {
|
|
|
|
|
|
|
|
switch (key) {
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_DHUK_SP:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_BHK:
|
|
|
|
|
|
|
|
case SECURE_AES_KEY_XORK_SP:
|
|
|
|
|
|
|
|
return sectrue;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return secfalse;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SYSCALL_DISPATCH
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__attribute__((section(".udata")))
|
|
|
|
|
|
|
|
uint32_t saes_input[KERNEL_UNPRIVILEGED_SIZE / sizeof(uint32_t)];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__attribute__((section(".udata")))
|
|
|
|
|
|
|
|
uint32_t saes_output[KERNEL_UNPRIVILEGED_SIZE / sizeof(uint32_t)];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__attribute__((section(".uflash"), used, naked, no_stack_protector)) uint32_t
|
|
|
|
|
|
|
|
saes_invoke(void) {
|
|
|
|
|
|
|
|
// reset the key loaded in SAES
|
|
|
|
|
|
|
|
MODIFY_REG(SAES->CR, AES_CR_KEYSEL, CRYP_KEYSEL_NORMAL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (HAL_IS_BIT_SET(SAES->SR, CRYP_FLAG_BUSY)) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
while (HAL_IS_BIT_SET(SAES->ISR, CRYP_FLAG_RNGEIF)) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MODIFY_REG(SAES->CR,
|
|
|
|
|
|
|
|
AES_CR_KMOD | AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD |
|
|
|
|
|
|
|
|
AES_CR_KEYSEL | AES_CR_KEYPROT,
|
|
|
|
|
|
|
|
CRYP_KEYMODE_NORMAL | CRYP_NO_SWAP | CRYP_KEYSIZE_256B |
|
|
|
|
|
|
|
|
CRYP_AES_ECB | CRYP_KEYSEL_HSW | CRYP_KEYPROT_DISABLE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TAMP->BKP0R;
|
|
|
|
|
|
|
|
TAMP->BKP1R;
|
|
|
|
|
|
|
|
TAMP->BKP2R;
|
|
|
|
|
|
|
|
TAMP->BKP3R;
|
|
|
|
|
|
|
|
TAMP->BKP4R;
|
|
|
|
|
|
|
|
TAMP->BKP5R;
|
|
|
|
|
|
|
|
TAMP->BKP6R;
|
|
|
|
|
|
|
|
TAMP->BKP7R;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode(Mode 1) */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Set the operating mode and normal key selection */
|
|
|
|
|
|
|
|
MODIFY_REG(SAES->CR, AES_CR_MODE | AES_CR_KMOD,
|
|
|
|
|
|
|
|
CRYP_OPERATINGMODE_ENCRYPT | CRYP_KEYMODE_NORMAL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SAES->CR |= AES_CR_EN;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < KERNEL_UNPRIVILEGED_SIZE / AES_BLOCK_SIZE; j++) {
|
|
|
|
|
|
|
|
/* Write the input block in the IN FIFO */
|
|
|
|
|
|
|
|
SAES->DINR = saes_input[j * 4 + 0];
|
|
|
|
|
|
|
|
SAES->DINR = saes_input[j * 4 + 1];
|
|
|
|
|
|
|
|
SAES->DINR = saes_input[j * 4 + 2];
|
|
|
|
|
|
|
|
SAES->DINR = saes_input[j * 4 + 3];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (HAL_IS_BIT_CLR(SAES->ISR, AES_ISR_CCF)) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Clear CCF Flag */
|
|
|
|
|
|
|
|
SET_BIT(SAES->ICR, CRYP_CLEAR_CCF);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Read the output block from the output FIFO */
|
|
|
|
|
|
|
|
for (int i = 0U; i < 4U; i++) {
|
|
|
|
|
|
|
|
saes_output[j * 4 + i] = SAES->DOUTR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SAES->CR &= ~AES_CR_EN;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// reset the key loaded in SAES
|
|
|
|
|
|
|
|
MODIFY_REG(SAES->CR, AES_CR_KEYSEL, CRYP_KEYSEL_NORMAL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
register uint32_t r0 __asm__("r0") = sectrue;
|
|
|
|
|
|
|
|
__asm__ volatile("svc %[svid]\n"
|
|
|
|
|
|
|
|
:
|
|
|
|
|
|
|
|
: [svid] "i"(SVC_CALLBACK_RETURN), "r"(r0)
|
|
|
|
|
|
|
|
: "memory");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern uint32_t sram2_u_start;
|
|
|
|
|
|
|
|
extern uint32_t sram2_u_end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output,
|
|
|
|
|
|
|
|
secure_aes_keysel_t key) {
|
|
|
|
|
|
|
|
if (size != KERNEL_UNPRIVILEGED_SIZE) {
|
|
|
|
|
|
|
|
return secfalse;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (key != SECURE_AES_KEY_XORK_SN) {
|
|
|
|
|
|
|
|
return secfalse;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NVIC_SetPriority(SVCall_IRQn, IRQ_PRI_HIGHEST);
|
|
|
|
|
|
|
|
uint32_t basepri = __get_BASEPRI();
|
|
|
|
|
|
|
|
__set_BASEPRI(1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_SAES);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t* m = &sram2_u_start; m < &sram2_u_end; m++) {
|
|
|
|
|
|
|
|
*m = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < KERNEL_UNPRIVILEGED_SIZE; i++) {
|
|
|
|
|
|
|
|
((uint8_t*)saes_input)[i] = input[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SAES->CR |= AES_CR_KEYSEL_0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_CLK_DISABLE();
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_FORCE_RESET();
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_RELEASE_RESET();
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_CLK_ENABLE();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
secbool retval = invoke_unpriv(saes_invoke);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_CLK_DISABLE();
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_FORCE_RESET();
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_RELEASE_RESET();
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_CLK_ENABLE();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < KERNEL_UNPRIVILEGED_SIZE; i++) {
|
|
|
|
|
|
|
|
output[i] = ((uint8_t*)saes_output)[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < KERNEL_UNPRIVILEGED_SIZE; i++) {
|
|
|
|
|
|
|
|
((uint8_t*)saes_input)[i] = 0;
|
|
|
|
|
|
|
|
((uint8_t*)saes_output)[i] = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t* m = &sram2_u_start; m < &sram2_u_end; m++) {
|
|
|
|
|
|
|
|
*m = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mpu_reconfig(mpu_mode);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__set_BASEPRI(basepri);
|
|
|
|
|
|
|
|
NVIC_SetPriority(SVCall_IRQn, IRQ_PRI_LOWEST);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
secbool secure_aes_ecb_encrypt_hw(const uint8_t* input, size_t size,
|
|
|
|
secbool secure_aes_ecb_encrypt_hw(const uint8_t* input, size_t size,
|
|
|
|
uint8_t* output, secure_aes_keysel_t key) {
|
|
|
|
uint8_t* output, secure_aes_keysel_t key) {
|
|
|
|
|
|
|
|
#ifdef SYSCALL_DISPATCH
|
|
|
|
|
|
|
|
if (key == SECURE_AES_KEY_XORK_SN) {
|
|
|
|
|
|
|
|
return unpriv_encrypt(input, size, output, key);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sectrue != is_key_supported(key)) {
|
|
|
|
|
|
|
|
return secfalse;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CRYP_HandleTypeDef hcryp = {0};
|
|
|
|
CRYP_HandleTypeDef hcryp = {0};
|
|
|
|
uint32_t iv[] = {0, 0, 0, 0};
|
|
|
|
uint32_t iv[] = {0, 0, 0, 0};
|
|
|
|
|
|
|
|
|
|
|
@ -136,8 +290,28 @@ secbool secure_aes_ecb_encrypt_hw(const uint8_t* input, size_t size,
|
|
|
|
return sectrue;
|
|
|
|
return sectrue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
secbool secure_aes_init(void) {
|
|
|
|
|
|
|
|
RCC_OscInitTypeDef osc_init_def = {0};
|
|
|
|
|
|
|
|
osc_init_def.OscillatorType = RCC_OSCILLATORTYPE_SHSI;
|
|
|
|
|
|
|
|
osc_init_def.SHSIState = RCC_SHSI_ON;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Enable SHSI clock
|
|
|
|
|
|
|
|
if (HAL_RCC_OscConfig(&osc_init_def) != HAL_OK) {
|
|
|
|
|
|
|
|
return secfalse;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Enable SAES peripheral clock
|
|
|
|
|
|
|
|
__HAL_RCC_SAES_CLK_ENABLE();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sectrue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
secbool secure_aes_ecb_decrypt_hw(const uint8_t* input, size_t size,
|
|
|
|
secbool secure_aes_ecb_decrypt_hw(const uint8_t* input, size_t size,
|
|
|
|
uint8_t* output, secure_aes_keysel_t key) {
|
|
|
|
uint8_t* output, secure_aes_keysel_t key) {
|
|
|
|
|
|
|
|
if (sectrue != is_key_supported(key)) {
|
|
|
|
|
|
|
|
return secfalse;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CRYP_HandleTypeDef hcryp = {0};
|
|
|
|
CRYP_HandleTypeDef hcryp = {0};
|
|
|
|
uint32_t iv[] = {0, 0, 0, 0};
|
|
|
|
uint32_t iv[] = {0, 0, 0, 0};
|
|
|
|
|
|
|
|
|
|
|
@ -202,4 +376,4 @@ secbool secure_aes_ecb_decrypt_hw(const uint8_t* input, size_t size,
|
|
|
|
return sectrue;
|
|
|
|
return sectrue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif // KERNEL_MODE
|
|
|
|
#endif
|
|
|
|