1
0
Эх сурвалжийг харах

[drivers][crypto]add device CRC/RNG

Ernest 5 жил өмнө
parent
commit
2aaa7d066d

+ 4 - 1
bsp/stm32/libraries/HAL_Drivers/SConscript

@@ -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']
 

+ 306 - 0
bsp/stm32/libraries/HAL_Drivers/drv_crypto.c

@@ -0,0 +1,306 @@
+/*
+ * 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"
+
+#if !defined(SOC_SERIES_STM32F0)&& !defined(SOC_SERIES_STM32F1) && !defined(SOC_SERIES_STM32F4) \
+    && !defined(SOC_SERIES_STM32F7)&& !defined(SOC_SERIES_STM32L4)  && !defined(SOC_SERIES_STM32H7)
+    #error "Please define at least one SOC_SERIES"
+#endif
+
+#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;
+#endif
+
+struct stm32_hwcrypto_device
+{
+    struct rt_hwcrypto_device dev;
+    struct rt_mutex mutex;
+};
+
+struct hash_ctx_des
+{
+    CRC_HandleTypeDef contex;
+};
+
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
+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;
+}
+#endif
+
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
+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
+
+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 (0 != memcmp(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)))
+    {
+        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;
+    }
+#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F1)
+    if (length % 4 != 0)
+    {
+        goto _exit;
+    }
+    length >>= 2;
+#endif
+
+    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
+_exit:
+    rt_mutex_release(&stm32_hw_dev->mutex);
+
+    return result;
+}
+
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
+static const struct hwcrypto_rng_ops rng_ops =
+{
+    .update = _rng_rand,
+};
+#endif
+
+static const struct hwcrypto_crc_ops crc_ops =
+{
+    .update = _crc_update,
+};
+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(SOC_SERIES_STM32L4)	|| defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7)
+    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
+    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;
+#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F1)
+        if (HAL_CRC_Init(hcrc) != HAL_OK)
+        {
+            res = -RT_ERROR;
+        }
+#endif
+        ctx->contex = hcrc;
+        ((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
+        break;
+    }
+    default:
+        res = -RT_ERROR;
+        break;
+    }
+
+    return res;
+}
+
+static void _crypto_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
+    {
+    case HWCRYPTO_TYPE_RNG:
+        break;
+    case HWCRYPTO_TYPE_CRC:
+        HAL_CRC_DeInit((CRC_HandleTypeDef *)(ctx->contex));
+        break;
+    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)
+    {
+    case HWCRYPTO_TYPE_RNG:
+        break;
+    case HWCRYPTO_TYPE_CRC:
+        if (des->contex && src->contex)
+        {
+            rt_memcpy(des->contex, src->contex, sizeof(struct hash_ctx_des));
+        }
+        break;
+    default:
+        res = -RT_ERROR;
+        break;
+    }
+    return res;
+}
+
+static void _crypto_reset(struct rt_hwcrypto_ctx *ctx)
+{
+    switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
+    {
+    case HWCRYPTO_TYPE_RNG:
+        break;
+    case HWCRYPTO_TYPE_CRC:
+        __HAL_CRC_DR_RESET((CRC_HandleTypeDef *)ctx-> contex);
+        break;
+    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};
+
+#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
+    _crypto_dev.dev.ops = &_ops;
+    _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 - 0
bsp/stm32/libraries/HAL_Drivers/drv_crypto.h

@@ -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__ */