Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[drivers][crypto]add device CRC/RNG #2844

Merged
merged 8 commits into from
Jul 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions bsp/stm32/libraries/HAL_Drivers/Kconfig
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

5 changes: 4 additions & 1 deletion bsp/stm32/libraries/HAL_Drivers/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F7']):

if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32L4']):
src += ['drv_flash/drv_flash_l4.c']


if GetDepend('RT_USING_HWCRYPTO'):
src += ['drv_crypto.c']

if GetDepend(['BSP_USING_WDT']):
src += ['drv_wdt.c']

Expand Down
327 changes: 327 additions & 0 deletions bsp/stm32/libraries/HAL_Drivers/drv_crypto.c
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);
16 changes: 16 additions & 0 deletions bsp/stm32/libraries/HAL_Drivers/drv_crypto.h
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__ */
3 changes: 2 additions & 1 deletion bsp/stm32/libraries/templates/stm32f0xx/board/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ menu "On-chip Peripheral Drivers"
range 1 216
default 16
endif

source "../libraries/HAL_Drivers/Kconfig"

endmenu

menu "Board extended module Drivers"
Expand Down
Loading