-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2844 from ErnestChen1/drv_crypto
[drivers][crypto]add device CRC/RNG
- Loading branch information
Showing
48 changed files
with
475 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
|
||
config BSP_USING_CRC | ||
bool "Enable CRC (CRC-32 0x04C11DB7 Polynomial)" | ||
select RT_USING_HWCRYPTO | ||
select RT_HWCRYPTO_USING_CRC | ||
# "Crypto device frame dose not support above 8-bits granularity" | ||
# "Reserve progress, running well, about 32-bits granularity, such as stm32f1, stm32f4" | ||
depends on (SOC_SERIES_STM32L4 || SOC_SERIES_STM32F0 || SOC_SERIES_STM32F7 || SOC_SERIES_STM32H7) | ||
default n | ||
|
||
config BSP_USING_RNG | ||
bool "Enable RNG (Random Number Generator)" | ||
select RT_USING_HWCRYPTO | ||
select RT_HWCRYPTO_USING_RNG | ||
depends on (SOC_SERIES_STM32L4 || SOC_SERIES_STM32F4 || SOC_SERIES_STM32F7 || \ | ||
SOC_SERIES_STM32H7) | ||
default n | ||
|
||
config BSP_USING_UDID | ||
bool "Enable UDID (Unique Device Identifier)" | ||
select RT_USING_HWCRYPTO | ||
default n | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,327 @@ | ||
/* | ||
* Copyright (c) 2019 Winner Microelectronics Co., Ltd. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2019-07-10 Ernest 1st version | ||
*/ | ||
|
||
#include <rtthread.h> | ||
#include <rtdevice.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include "drv_crypto.h" | ||
#include "board.h" | ||
|
||
struct stm32_hwcrypto_device | ||
{ | ||
struct rt_hwcrypto_device dev; | ||
struct rt_mutex mutex; | ||
}; | ||
|
||
#if defined(BSP_USING_CRC) | ||
|
||
struct hash_ctx_des | ||
{ | ||
CRC_HandleTypeDef contex; | ||
}; | ||
|
||
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) | ||
static struct hwcrypto_crc_cfg crc_backup_cfg; | ||
|
||
static int reverse_bit(rt_uint32_t n) | ||
{ | ||
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); | ||
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); | ||
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); | ||
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); | ||
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000); | ||
|
||
return n; | ||
} | ||
#endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */ | ||
|
||
static rt_uint32_t _crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length) | ||
{ | ||
rt_uint32_t result = 0; | ||
struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data; | ||
|
||
#if defined(SOC_SERIES_STM32L4)|| defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) | ||
CRC_HandleTypeDef *HW_TypeDef = (CRC_HandleTypeDef *)(ctx->parent.contex); | ||
#endif | ||
|
||
rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER); | ||
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) | ||
if (memcmp(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0) | ||
{ | ||
if (HW_TypeDef->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_DISABLE) | ||
{ | ||
HW_TypeDef->Init.GeneratingPolynomial = ctx ->crc_cfg.poly; | ||
} | ||
else | ||
{ | ||
HW_TypeDef->Init.GeneratingPolynomial = DEFAULT_CRC32_POLY; | ||
} | ||
|
||
switch (ctx ->crc_cfg.flags) | ||
{ | ||
case 0: | ||
HW_TypeDef->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; | ||
HW_TypeDef->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; | ||
break; | ||
case CRC_FLAG_REFIN: | ||
HW_TypeDef->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; | ||
break; | ||
case CRC_FLAG_REFOUT: | ||
HW_TypeDef->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; | ||
break; | ||
case CRC_FLAG_REFIN|CRC_FLAG_REFOUT: | ||
HW_TypeDef->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; | ||
HW_TypeDef->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; | ||
break; | ||
default : | ||
goto _exit; | ||
} | ||
|
||
HW_TypeDef->Init.CRCLength = ctx ->crc_cfg.width; | ||
if (HW_TypeDef->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_DISABLE) | ||
{ | ||
HW_TypeDef->Init.InitValue = ctx ->crc_cfg.last_val; | ||
} | ||
|
||
if (HAL_CRC_Init(HW_TypeDef) != HAL_OK) | ||
{ | ||
goto _exit; | ||
} | ||
memcpy(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)); | ||
} | ||
|
||
if (HAL_CRC_STATE_READY != HAL_CRC_GetState(HW_TypeDef)) | ||
{ | ||
goto _exit; | ||
} | ||
#else | ||
if (ctx->crc_cfg.flags != 0 || ctx->crc_cfg.last_val != 0xFFFFFFFF || ctx->crc_cfg.xorout != 0 || length % 4 != 0) | ||
{ | ||
goto _exit; | ||
} | ||
length /= 4; | ||
#endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */ | ||
|
||
result = HAL_CRC_Accumulate(ctx->parent.contex, (rt_uint32_t *)in, length); | ||
|
||
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) | ||
if (HW_TypeDef->Init.OutputDataInversionMode) | ||
{ | ||
ctx ->crc_cfg.last_val = reverse_bit(result); | ||
} | ||
else | ||
{ | ||
ctx ->crc_cfg.last_val = result; | ||
} | ||
crc_backup_cfg.last_val = ctx ->crc_cfg.last_val; | ||
result = (result ? result ^ (ctx ->crc_cfg.xorout) : result); | ||
#endif /* defined(SOC_SERIES_STM32L4)|| defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */ | ||
|
||
_exit: | ||
rt_mutex_release(&stm32_hw_dev->mutex); | ||
|
||
return result; | ||
} | ||
|
||
static const struct hwcrypto_crc_ops crc_ops = | ||
{ | ||
.update = _crc_update, | ||
}; | ||
#endif /* BSP_USING_CRC */ | ||
|
||
#if defined(BSP_USING_RNG) | ||
static rt_uint32_t _rng_rand(struct hwcrypto_rng *ctx) | ||
{ | ||
rt_uint32_t gen_random = 0; | ||
|
||
RNG_HandleTypeDef *HW_TypeDef = (RNG_HandleTypeDef *)(ctx->parent.contex); | ||
|
||
if (HAL_OK == HAL_RNG_GenerateRandomNumber(HW_TypeDef, &gen_random)) | ||
{ | ||
return gen_random ; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static const struct hwcrypto_rng_ops rng_ops = | ||
{ | ||
.update = _rng_rand, | ||
}; | ||
#endif /* BSP_USING_RNG */ | ||
|
||
static rt_err_t _crypto_create(struct rt_hwcrypto_ctx *ctx) | ||
{ | ||
rt_err_t res = RT_EOK; | ||
|
||
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK) | ||
{ | ||
#if defined(BSP_USING_RNG) | ||
case HWCRYPTO_TYPE_RNG: | ||
{ | ||
RNG_HandleTypeDef *hrng = rt_calloc(1, sizeof(RNG_HandleTypeDef)); | ||
|
||
hrng->Instance = RNG; | ||
HAL_RNG_Init(hrng); | ||
ctx->contex = hrng; | ||
((struct hwcrypto_rng *)ctx)->ops = &rng_ops; | ||
|
||
break; | ||
} | ||
#endif /* BSP_USING_RNG */ | ||
|
||
#if defined(BSP_USING_CRC) | ||
case HWCRYPTO_TYPE_CRC: | ||
{ | ||
CRC_HandleTypeDef *hcrc = rt_calloc(1, sizeof(CRC_HandleTypeDef)); | ||
if (RT_NULL == hcrc) | ||
{ | ||
res = -RT_ERROR; | ||
break; | ||
} | ||
|
||
hcrc->Instance = CRC; | ||
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) | ||
hcrc->Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; | ||
hcrc->Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; | ||
hcrc->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; | ||
hcrc->Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; | ||
hcrc->InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; | ||
#else | ||
if (HAL_CRC_Init(hcrc) != HAL_OK) | ||
{ | ||
res = -RT_ERROR; | ||
} | ||
#endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */ | ||
ctx->contex = hcrc; | ||
((struct hwcrypto_crc *)ctx)->ops = &crc_ops; | ||
break; | ||
} | ||
#endif /* BSP_USING_CRC */ | ||
default: | ||
res = -RT_ERROR; | ||
break; | ||
} | ||
return res; | ||
} | ||
|
||
static void _crypto_destroy(struct rt_hwcrypto_ctx *ctx) | ||
{ | ||
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK) | ||
{ | ||
#if defined(BSP_USING_RNG) | ||
case HWCRYPTO_TYPE_RNG: | ||
break; | ||
#endif /* BSP_USING_RNG */ | ||
|
||
#if defined(BSP_USING_CRC) | ||
case HWCRYPTO_TYPE_CRC: | ||
__HAL_CRC_DR_RESET((CRC_HandleTypeDef *)ctx-> contex); | ||
HAL_CRC_DeInit((CRC_HandleTypeDef *)(ctx->contex)); | ||
break; | ||
#endif /* BSP_USING_CRC */ | ||
default: | ||
break; | ||
} | ||
|
||
rt_free(ctx->contex); | ||
} | ||
|
||
static rt_err_t _crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src) | ||
{ | ||
rt_err_t res = RT_EOK; | ||
|
||
switch (src->type & HWCRYPTO_MAIN_TYPE_MASK) | ||
{ | ||
#if defined(BSP_USING_RNG) | ||
case HWCRYPTO_TYPE_RNG: | ||
if (des->contex && src->contex) | ||
{ | ||
rt_memcpy(des->contex, src->contex, sizeof(struct hash_ctx_des)); | ||
} | ||
break; | ||
#endif /* BSP_USING_RNG */ | ||
|
||
#if defined(BSP_USING_CRC) | ||
case HWCRYPTO_TYPE_CRC: | ||
if (des->contex && src->contex) | ||
{ | ||
rt_memcpy(des->contex, src->contex, sizeof(struct hash_ctx_des)); | ||
} | ||
break; | ||
#endif /* BSP_USING_CRC */ | ||
default: | ||
res = -RT_ERROR; | ||
break; | ||
} | ||
return res; | ||
} | ||
|
||
static void _crypto_reset(struct rt_hwcrypto_ctx *ctx) | ||
{ | ||
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK) | ||
{ | ||
#if defined(BSP_USING_RNG) | ||
case HWCRYPTO_TYPE_RNG: | ||
break; | ||
#endif /* BSP_USING_RNG */ | ||
|
||
#if defined(BSP_USING_CRC) | ||
case HWCRYPTO_TYPE_CRC: | ||
__HAL_CRC_DR_RESET((CRC_HandleTypeDef *)ctx-> contex); | ||
break; | ||
#endif /* BSP_USING_CRC */ | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
static const struct rt_hwcrypto_ops _ops = | ||
{ | ||
.create = _crypto_create, | ||
.destroy = _crypto_destroy, | ||
.copy = _crypto_clone, | ||
.reset = _crypto_reset, | ||
}; | ||
|
||
int stm32_hw_crypto_device_init(void) | ||
{ | ||
static struct stm32_hwcrypto_device _crypto_dev; | ||
rt_uint32_t cpuid[3] = {0}; | ||
|
||
_crypto_dev.dev.ops = &_ops; | ||
#if defined(BSP_USING_UDID) | ||
|
||
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F7) | ||
cpuid[0] = HAL_GetUIDw0(); | ||
cpuid[1] = HAL_GetUIDw1(); | ||
#elif defined(SOC_SERIES_STM32F1) | ||
HAL_GetUID(cpuid); | ||
#elif defined(SOC_SERIES_STM32H7) | ||
cpuid[0] = HAL_GetREVID(); | ||
cpuid[1] = HAL_GetDEVID(); | ||
#endif | ||
|
||
#endif /* BSP_USING_UDID */ | ||
|
||
_crypto_dev.dev.id = 0; | ||
rt_memcpy(&_crypto_dev.dev.id, cpuid, 8); | ||
|
||
_crypto_dev.dev.user_data = &_crypto_dev; | ||
|
||
if (rt_hwcrypto_register(&_crypto_dev.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK) | ||
{ | ||
return -1; | ||
} | ||
rt_mutex_init(&_crypto_dev.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_FIFO); | ||
return 0; | ||
} | ||
INIT_DEVICE_EXPORT(stm32_hw_crypto_device_init); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* Copyright (c) 2019 Winner Microelectronics Co., Ltd. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2019-07-10 Ernest 1st version | ||
*/ | ||
|
||
#ifndef __DRV_CRYPTO_H__ | ||
#define __DRV_CRYPTO_H__ | ||
|
||
int l4_hw_crypto_device_init(void); | ||
|
||
#endif /* __DRV_CRYPTO_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.