Browse Source

[components][drivers] add hardware crypto device

tangyuxin 6 years ago
parent
commit
1cb3c89bce

+ 168 - 0
components/drivers/Kconfig

@@ -269,6 +269,174 @@ if RT_USING_SENSOR
         default y
 endif
 
+menu "Using Hardware Crypto drivers"
+    config RT_USING_HWCRYPTO
+        bool "Using Hardware Crypto"
+        default n
+
+    if RT_USING_HWCRYPTO
+        config RT_HWCRYPTO_DEFAULT_NAME
+            string "Hardware crypto device name"
+            default "hwcryto"
+
+        config RT_HWCRYPTO_IV_MAX_SIZE
+            int "IV max size"
+            default "16"
+
+        config HWCRYPTO_KEYBIT_MAX_SIZE
+            int "Key max bit length"
+            default 256
+
+        config RT_HWCRYPTO_USING_GCM
+            bool "Using Hardware GCM"
+            default n
+
+        config RT_HWCRYPTO_USING_AES
+            bool "Using Hardware AES"
+            default n
+
+        if RT_HWCRYPTO_USING_AES
+            config RT_HWCRYPTO_USING_AES_ECB
+                bool "Using Hardware AES ECB mode"
+                default y
+
+            config RT_HWCRYPTO_USING_AES_CBC
+                bool "Using Hardware AES CBC mode"
+                default n
+
+            config RT_HWCRYPTO_USING_AES_CFB
+                bool "Using Hardware AES CFB mode"
+                default n
+
+            config RT_HWCRYPTO_USING_AES_CTR
+                bool "Using Hardware AES CTR mode"
+                default n
+
+            config RT_HWCRYPTO_USING_AES_OFB
+                bool "Using Hardware AES OFB mode"
+                default n
+        endif
+
+        config RT_HWCRYPTO_USING_DES
+            bool "Using Hardware DES"
+            default n
+
+        if RT_HWCRYPTO_USING_DES
+            config RT_HWCRYPTO_USING_DES_ECB
+                bool "Using Hardware DES ECB mode"
+                default y
+
+            config RT_HWCRYPTO_USING_DES_CBC
+                bool "Using Hardware DES CBC mode"
+                default n
+        endif
+
+        config RT_HWCRYPTO_USING_3DES
+            bool "Using Hardware 3DES"
+            default n
+
+        if RT_HWCRYPTO_USING_3DES
+            config RT_HWCRYPTO_USING_3DES_ECB
+                bool "Using Hardware 3DES ECB mode"
+                default y
+
+            config RT_HWCRYPTO_USING_3DES_CBC
+                bool "Using Hardware 3DES CBC mode"
+                default n
+        endif
+
+        config RT_HWCRYPTO_USING_RC4
+            bool "Using Hardware RC4"
+            default n
+
+        config RT_HWCRYPTO_USING_MD5
+            bool "Using Hardware MD5"
+            default n
+
+        config RT_HWCRYPTO_USING_SHA1
+            bool "Using Hardware SHA1"
+            default n
+
+        config RT_HWCRYPTO_USING_SHA2
+            bool "Using Hardware SHA2"
+            default n
+
+        if RT_HWCRYPTO_USING_SHA2
+            config RT_HWCRYPTO_USING_SHA2_224
+                bool "Using Hardware SHA2_224 mode"
+                default n
+
+            config RT_HWCRYPTO_USING_SHA2_256
+                bool "Using Hardware SHA2_256 mode"
+                default y
+
+            config RT_HWCRYPTO_USING_SHA2_384
+                bool "Using Hardware SHA2_384 mode"
+                default n
+
+            config RT_HWCRYPTO_USING_SHA2_512
+                bool "Using Hardware SHA2_512 mode"
+                default n
+        endif
+
+        config RT_HWCRYPTO_USING_RNG
+            bool "Using Hardware RNG"
+            default n
+
+        config RT_HWCRYPTO_USING_CRC
+            bool "Using Hardware CRC"
+            default n
+
+        if RT_HWCRYPTO_USING_CRC
+            config RT_HWCRYPTO_USING_CRC_07
+                bool "Using Hardware CRC-8 0x07 polynomial"
+                default n
+
+            config RT_HWCRYPTO_USING_CRC_8005
+                bool "Using Hardware CRC-16 0x8005 polynomial"
+                default n
+
+            config RT_HWCRYPTO_USING_CRC_1021
+                bool "Using Hardware CRC-16 0x1021 polynomial"
+                default n
+
+            config RT_HWCRYPTO_USING_CRC_3D65
+                bool "Using Hardware CRC-16 0x3D65 polynomial"
+                default n
+
+            config RT_HWCRYPTO_USING_CRC_04C11DB7
+                bool "Using Hardware CRC-32 0x04C11DB7 polynomial"
+                default n
+        endif
+
+        config RT_HWCRYPTO_USING_BIGNUM
+            bool "Using Hardware bignum"
+            default n
+
+        if RT_HWCRYPTO_USING_BIGNUM
+            config RT_HWCRYPTO_USING_BIGNUM_EXPTMOD
+                bool "Using Hardware bignum expt_mod operation"
+                default y
+
+            config RT_HWCRYPTO_USING_BIGNUM_MULMOD
+                bool "Using Hardware bignum mul_mod operation"
+                default y
+
+            config RT_HWCRYPTO_USING_BIGNUM_MUL
+                bool "Using Hardware bignum mul operation"
+                default n
+
+            config RT_HWCRYPTO_USING_BIGNUM_ADD
+                bool "Using Hardware bignum add operation"
+                default n
+
+            config RT_HWCRYPTO_USING_BIGNUM_SUB
+                bool "Using Hardware bignum sub operation"
+                default n
+        endif
+    endif
+endmenu
+
 menu "Using WiFi"
     config RT_USING_WIFI
         bool "Using Wi-Fi framework"

+ 34 - 0
components/drivers/hwcrypto/SConscript

@@ -0,0 +1,34 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd     = GetCurrentDir()
+CPPPATH = [cwd, str(Dir('#'))]
+
+src  = ['hwcrypto.c']
+
+if (GetDepend(['RT_HWCRYPTO_USING_AES'])  or
+    GetDepend(['RT_HWCRYPTO_USING_DES'])  or
+    GetDepend(['RT_HWCRYPTO_USING_3DES']) or
+    GetDepend(['RT_HWCRYPTO_USING_RC4'])):
+    src += ['hw_symmetric.c']
+    if GetDepend(['RT_HWCRYPTO_USING_GCM']):
+        src += ['hw_gcm.c']
+
+if (GetDepend(['RT_HWCRYPTO_USING_MD5'])  or
+    GetDepend(['RT_HWCRYPTO_USING_SHA1']) or
+    GetDepend(['RT_HWCRYPTO_USING_SHA2'])):
+    src += ['hw_hash.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_RNG']):
+    src += ['hw_rng.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_CRC']):
+    src += ['hw_crc.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_BIGNUM']):
+    src += ['hw_bignum.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_HWCRYPTO'], CPPPATH = CPPPATH)
+
+Return('group')

+ 353 - 0
components/drivers/hwcrypto/hw_bignum.c

@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_bignum.h>
+
+static struct rt_hwcrypto_ctx *bignum_default;
+
+rt_inline rt_err_t rt_hwcrypto_bignum_init(void)
+{
+    struct rt_hwcrypto_device *dev;
+
+    if (bignum_default)
+    {
+        return RT_EOK;
+    }
+    dev = rt_hwcrypto_dev_dufault();
+    if (dev == RT_NULL)
+    {
+        return -RT_ERROR;
+    }
+    return rt_hwcrypto_bignum_default(dev);
+}
+
+/**
+ * @brief           Setting bignum default devices
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device)
+{
+    if (bignum_default)
+    {
+        rt_hwcrypto_ctx_destroy(bignum_default);
+        bignum_default = RT_NULL;
+    }
+    if (device == RT_NULL)
+    {
+        return RT_EOK;
+    }
+    bignum_default = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_BIGNUM, sizeof(struct hwcrypto_bignum));
+    if (bignum_default == RT_NULL)
+    {
+        return -RT_ERROR;
+    }
+    return RT_EOK;
+}
+
+/**
+ * @brief           Allocate memory for bignum
+ *
+ * @return          Pointer to allocated bignum obj
+ */
+struct hw_bignum_mpi *rt_hwcrypto_bignum_alloc(void)
+{
+    struct hw_bignum_mpi *n;
+
+    n = rt_malloc(sizeof(struct hw_bignum_mpi));
+    if (n)
+    {
+        rt_memset(n, 0, sizeof(struct hw_bignum_mpi));
+    }
+    return n;
+}
+
+/**
+ * @brief           free a bignum obj
+ *
+ * @param           Pointer to bignum obj
+ */
+void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n)
+{
+    if (n)
+    {
+        rt_free(n->p);
+        rt_free(n);
+    }
+}
+
+/**
+ * @brief           Get length of bignum as an unsigned binary buffer
+ * 
+ * @param n         bignum obj
+ * 
+ * @return          binary buffer Length
+ */
+int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n)
+{
+    int tmp_len, total;
+
+    if (n == RT_NULL || n->p == RT_NULL)
+    {
+        return 0;
+    }
+    tmp_len = 0;
+    total = n->total;
+    while ((total > 0) && (n->p[total - 1] == 0))
+    {
+        tmp_len++;
+        total--;
+    }
+    return n->total - tmp_len;
+}
+
+/**
+ * @brief           Get length of bignum as an unsigned binary buffer
+ * 
+ * @param n         bignum obj
+ * @param buf       Buffer for the binary number
+ * @param len       Length of the buffer
+ * 
+ * @return          binary buffer Length
+ */
+int rt_hwcrypto_bignum_get_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
+{
+    int cp_len;
+
+    if (n == RT_NULL || n->p == RT_NULL || buf == RT_NULL)
+    {
+        return 0;
+    }
+    cp_len = n->total > len ? len : n->total;
+    rt_memcpy(n->p, buf, cp_len);
+    return cp_len;
+}
+
+/**
+ * @brief           Set binary buffer to unsigned bignum
+ * 
+ * @param n         bignum obj
+ * @param buf       Buffer for the binary number
+ * @param len       Length of the buffer
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_set_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
+{
+    void *temp_p;
+
+    if (n == RT_NULL)
+    {
+        return -RT_EINVAL;
+    }
+    if (n->p && n->total >= len)
+    {
+        rt_memcpy(n->p, buf, len);
+        return RT_EOK;
+    }
+    temp_p = rt_malloc(len);
+    if (temp_p == RT_NULL)
+    {
+        return -RT_ENOMEM;
+    }
+    if (n->p)
+    {
+        rt_free(n->p);
+        n->p = temp_p;
+        n->total = 0;
+    }
+    rt_memcpy(n->p, buf, len);
+    n->total = len;
+    return RT_EOK;
+}
+
+/**
+ * @brief           Unsigned comparison
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * 
+ * @return          0 is equal
+ */
+int rt_hwcrypto_bignum_cmp(const struct hw_bignum_mpi *a,
+                           const struct hw_bignum_mpi *b)
+{
+    int a_len, b_len;
+
+    if (a == RT_NULL || a->p == RT_NULL
+            || b == RT_NULL || b->p == RT_NULL)
+    {
+        return -1;
+    }
+    a_len = rt_hwcrypto_bignum_get_len(a);
+    b_len = rt_hwcrypto_bignum_get_len(b);
+    if (a_len != b_len)
+    {
+        return a_len - b_len;
+    }
+    return rt_memcmp(a->p, b->p, a_len);
+}
+
+/**
+ * @brief           Compare bignum to standard Unsigned integer
+ * 
+ * @param a         bignum obj
+ * @param b         Unsigned integer
+ * 
+ * @return          0 is equal
+ */
+int rt_hwcrypto_bignum_cmp_d(const struct hw_bignum_mpi *a, unsigned long b)
+{
+    struct hw_bignum_mpi tmp_b;
+
+    b = b <= 0 ? -b : b;
+    tmp_b.total = sizeof(unsigned long);
+    tmp_b.p = &b;
+    return rt_hwcrypto_bignum_cmp(a, &tmp_b);
+}
+
+/**
+ * @brief           a = b + c
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *a,
+                                const struct hw_bignum_mpi *b,
+                                const struct hw_bignum_mpi *c)
+{
+    struct hwcrypto_bignum *bignum_ctx;
+
+    if (rt_hwcrypto_bignum_init() != RT_EOK)
+    {
+        return -RT_ERROR;
+    }
+    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+    if (bignum_ctx->ops->add)
+    {
+        return bignum_ctx->ops->add(bignum_ctx, a, b, c);
+    }
+    return -RT_ERROR;
+}
+
+/**
+ * @brief           a = b - c
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *a,
+                                const struct hw_bignum_mpi *b,
+                                const struct hw_bignum_mpi *c)
+{
+    struct hwcrypto_bignum *bignum_ctx;
+
+    if (rt_hwcrypto_bignum_init() != RT_EOK)
+    {
+        return -RT_ERROR;
+    }
+    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+    if (bignum_ctx->ops->sub)
+    {
+        return bignum_ctx->ops->sub(bignum_ctx, a, b, c);
+    }
+    return -RT_ERROR;
+}
+
+/**
+ * @brief           a = b * c
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *a,
+                                const struct hw_bignum_mpi *b,
+                                const struct hw_bignum_mpi *c)
+{
+    struct hwcrypto_bignum *bignum_ctx;
+
+    if (rt_hwcrypto_bignum_init() != RT_EOK)
+    {
+        return -RT_ERROR;
+    }
+    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+    if (bignum_ctx->ops->mul)
+    {
+        return bignum_ctx->ops->mul(bignum_ctx, a, b, c);
+    }
+    return -RT_ERROR;
+}
+
+/**
+ * @brief           a = b * c (mod d)
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *a,
+                                   const struct hw_bignum_mpi *b,
+                                   const struct hw_bignum_mpi *c,
+                                   const struct hw_bignum_mpi *d)
+{
+    struct hwcrypto_bignum *bignum_ctx;
+
+    if (rt_hwcrypto_bignum_init() != RT_EOK)
+    {
+        return -RT_ERROR;
+    }
+    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+    if (bignum_ctx->ops->mulmod)
+    {
+        return bignum_ctx->ops->mulmod(bignum_ctx, a, b, c, d);
+    }
+    return -RT_ERROR;
+}
+
+/**
+ * @brief           a = b ^ c (mod d)
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t bignum_exptmod(struct hw_bignum_mpi *a,
+                        const struct hw_bignum_mpi *b,
+                        const struct hw_bignum_mpi *c,
+                        const struct hw_bignum_mpi *d)
+{
+    struct hwcrypto_bignum *bignum_ctx;
+
+    if (rt_hwcrypto_bignum_init() != RT_EOK)
+    {
+        return -RT_ERROR;
+    }
+    bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+    if (bignum_ctx->ops->exptmod)
+    {
+        return bignum_ctx->ops->exptmod(bignum_ctx, a, b, c, d);
+    }
+    return -RT_ERROR;
+}

+ 208 - 0
components/drivers/hwcrypto/hw_bignum.h

@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#ifndef __HW_BIGNUM_H__
+#define __HW_BIGNUM_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_bignum;
+
+/* bignum obj */
+struct hw_bignum_mpi
+{
+    rt_size_t total;            /**< Total length of data  */
+    rt_ubase_t *p;              /**< pointer to data  */
+};
+
+struct hwcrypto_bignum_ops
+{
+    rt_err_t (*add)(struct hwcrypto_bignum *bignum_ctx,
+                    struct hw_bignum_mpi *a,
+                    const struct hw_bignum_mpi *b,
+                    const struct hw_bignum_mpi *c);             /**< a = b + c */
+    rt_err_t (*sub)(struct hwcrypto_bignum *bignum_ctx,
+                    struct hw_bignum_mpi *a,
+                    const struct hw_bignum_mpi *b,
+                    const struct hw_bignum_mpi *c);             /**< a = b - c */
+    rt_err_t (*mul)(struct hwcrypto_bignum *bignum_ctx,
+                    struct hw_bignum_mpi *a,
+                    const struct hw_bignum_mpi *b,
+                    const struct hw_bignum_mpi *c);             /**< a = b * c */
+    rt_err_t (*mulmod)(struct hwcrypto_bignum *bignum_ctx,
+                       struct hw_bignum_mpi *a,
+                       const struct hw_bignum_mpi *b,
+                       const struct hw_bignum_mpi *c,
+                       const struct hw_bignum_mpi *d);          /**< a = b * c (mod d) */
+    rt_err_t (*exptmod)(struct hwcrypto_bignum *bignum_ctx,
+                        struct hw_bignum_mpi *a,
+                        const struct hw_bignum_mpi *b,
+                        const struct hw_bignum_mpi *c,
+                        const struct hw_bignum_mpi *d);         /**< a = b ^ c (mod d) */
+};
+
+/**
+ * @brief           bignum context. Hardware driver usage
+ */
+struct hwcrypto_bignum
+{
+    struct rt_hwcrypto_ctx parent;              /**< Inheritance from hardware crypto context */
+    const struct hwcrypto_bignum_ops *ops;      /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief           Setting bignum default devices
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief           Allocate memory for bignum
+ *
+ * @return          Pointer to allocated bignum obj
+ */
+struct hw_bignum_mpi *rt_hwcrypto_bignum_alloc(void);
+
+/**
+ * @brief           free a bignum obj
+ *
+ * @param           Pointer to bignum obj
+ */
+void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n);
+
+/**
+ * @brief           Get length of bignum as an unsigned binary buffer
+ * 
+ * @param n         bignum obj
+ * 
+ * @return          binary buffer Length
+ */
+int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n);
+
+/**
+ * @brief           Get length of bignum as an unsigned binary buffer
+ * 
+ * @param n         bignum obj
+ * @param buf       Buffer for the binary number
+ * @param len       Length of the buffer
+ * 
+ * @return          binary buffer Length
+ */
+int rt_hwcrypto_bignum_get_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);
+
+/**
+ * @brief           Set binary buffer to unsigned bignum
+ * 
+ * @param n         bignum obj
+ * @param buf       Buffer for the binary number
+ * @param len       Length of the buffer
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_set_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);
+
+/**
+ * @brief           Unsigned comparison
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * 
+ * @return          0 is equal
+ */
+int rt_hwcrypto_bignum_cmp(const struct hw_bignum_mpi *a,
+                           const struct hw_bignum_mpi *b);
+
+/**
+ * @brief           Compare bignum to standard Unsigned integer
+ * 
+ * @param a         bignum obj
+ * @param b         Unsigned integer
+ * 
+ * @return          0 is equal
+ */
+int rt_hwcrypto_bignum_cmp_d(const struct hw_bignum_mpi *a, unsigned long b);
+
+/**
+ * @brief           a = b + c
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *a,
+                                const struct hw_bignum_mpi *b,
+                                const struct hw_bignum_mpi *c);
+
+/**
+ * @brief           a = b - c
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *a,
+                                const struct hw_bignum_mpi *b,
+                                const struct hw_bignum_mpi *c);
+
+/**
+ * @brief           a = b * c
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *a,
+                                const struct hw_bignum_mpi *b,
+                                const struct hw_bignum_mpi *c);
+
+/**
+ * @brief           a = b * c (mod d)
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *a,
+                                   const struct hw_bignum_mpi *b,
+                                   const struct hw_bignum_mpi *c,
+                                   const struct hw_bignum_mpi *d);
+
+/**
+ * @brief           a = b ^ c (mod d)
+ * 
+ * @param a         bignum obj
+ * @param b         bignum obj
+ * @param c         bignum obj
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t bignum_exptmod(struct hw_bignum_mpi *a,
+                        const struct hw_bignum_mpi *b,
+                        const struct hw_bignum_mpi *c,
+                        const struct hw_bignum_mpi *d);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 117 - 0
components/drivers/hwcrypto/hw_crc.c

@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_crc.h>
+
+/**
+ * @brief           Creating CRC Context
+ *
+ * @param device    Hardware crypto device
+ * @param mode      Setting default mode or custom mode
+ *
+ * @return          CRC context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device, 
+                                               hwcrypto_crc_mode mode)
+{
+    struct hwcrypto_crc *crc_ctx;
+
+    crc_ctx = (struct hwcrypto_crc *)rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_CRC, sizeof(struct hwcrypto_crc));
+    if (crc_ctx == RT_NULL)
+    {
+        return RT_NULL;
+    }
+
+    switch (mode)
+    {
+    case HWCRYPTO_CRC_CRC8:
+    {
+        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC8_CFG;
+        crc_ctx->crc_cfg = temp;
+        break;
+    }
+    case HWCRYPTO_CRC_CRC16:
+    {
+        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC16_CFG;
+        crc_ctx->crc_cfg = temp;
+        break;
+    }
+    case HWCRYPTO_CRC_CRC32:
+    {
+        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC32_CFG;
+        crc_ctx->crc_cfg = temp;
+        break;
+    }
+    case HWCRYPTO_CRC_CCITT:
+    {
+        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_CCITT_CFG;
+        crc_ctx->crc_cfg = temp;
+        break;
+    }
+    case HWCRYPTO_CRC_DNP:
+    {
+        struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_DNP_CFG;
+        crc_ctx->crc_cfg = temp;
+        break;
+    }
+    default:
+        break;
+    }
+
+    return &crc_ctx->parent;
+}
+
+/**
+ * @brief           Destroy CRC Context
+ *
+ * @param ctx       CRC context
+ */
+void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief           Processing a packet of data
+ *
+ * @param ctx       CRC context
+ * @param input     Data buffer to be Processed
+ * @param length    Data Buffer length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx, 
+                                             const rt_uint8_t *input, 
+                                             rt_size_t length)
+{
+    struct hwcrypto_crc *crc_ctx = (struct hwcrypto_crc *)ctx;
+    if (ctx && crc_ctx->ops->update)
+    {
+        return crc_ctx->ops->update(crc_ctx, input, length);
+    }
+    return 0;
+}
+
+/**
+ * @brief           CRC context configuration
+ *
+ * @param ctx       CRC context
+ * @param cfg       CRC config
+ */
+void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx, 
+                                   struct hwcrypto_crc_cfg *cfg)
+{
+    if (cfg)
+    {
+        ((struct hwcrypto_crc *)ctx)->crc_cfg = *cfg;
+    }
+}

+ 148 - 0
components/drivers/hwcrypto/hw_crc.h

@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#ifndef __HW_CRC_H__
+#define __HW_CRC_H__
+
+#include <hwcrypto.h>
+
+#define CRC_FLAG_REFIN    (0x1 << 0)
+#define CRC_FLAG_REFOUT   (0x1 << 1)
+
+#define HWCRYPTO_CRC8_CFG       \
+{                               \
+    .last_val = 0x00,           \
+    .poly = 0x07,               \
+    .width = 8,                 \
+    .xorout = 0x00,             \
+    .flags = 0,                 \
+}
+
+#define HWCRYPTO_CRC16_CFG      \
+{                               \
+    .last_val = 0x0000,           \
+    .poly = 0x8005,               \
+    .width = 16,                 \
+    .xorout = 0x0000,             \
+    .flags = 0,                 \
+}
+
+#define HWCRYPTO_CRC32_CFG   \
+{                           \
+    .last_val = 0x00000000, \
+    .poly = 0x04C11DB7,              \
+    .width = 32,             \
+    .xorout = 0x00000000,            \
+    .flags = 0,             \
+}
+
+#define HWCRYPTO_CRC_CCITT_CFG   \
+{                           \
+    .last_val = 0x0000,          \
+    .poly = 0x1021,              \
+    .width = 16,             \
+    .xorout = 0x0000,            \
+    .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
+}
+
+#define HWCRYPTO_CRC_DNP_CFG   \
+{                           \
+    .last_val = 0x0000,          \
+    .poly = 0x3D65,              \
+    .width = 16,             \
+    .xorout = 0xffff,            \
+    .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_crc;
+
+typedef enum
+{
+    HWCRYPTO_CRC_CUSTOM,        /**< Custom CRC mode */
+    HWCRYPTO_CRC_CRC8,          /**< poly : 0x07 */
+    HWCRYPTO_CRC_CRC16,         /**< poly : 0x8005 */
+    HWCRYPTO_CRC_CRC32,         /**< poly : 0x04C11DB7 */
+    HWCRYPTO_CRC_CCITT,         /**< poly : 0x1021 */
+    HWCRYPTO_CRC_DNP,           /**< poly : 0x3D65 */
+} hwcrypto_crc_mode;
+
+struct hwcrypto_crc_cfg
+{
+    rt_uint32_t last_val;       /**< Last CRC value cache */
+    rt_uint32_t poly;           /**< CRC polynomial */
+    rt_uint16_t width;          /**< CRC value width */
+    rt_uint32_t xorout;         /**< Result XOR Value */
+    rt_uint16_t flags;          /**< Input or output data reverse. CRC_FLAG_REFIN or CRC_FLAG_REFOUT */
+};
+
+struct hwcrypto_crc_ops
+{
+    rt_uint32_t (*update)(struct hwcrypto_crc *ctx,
+                          const rt_uint8_t *in, rt_size_t length);  /**< Perform a CRC calculation. return CRC value */
+};
+
+/**
+ * @brief           CRC context. Hardware driver usage
+ */
+struct hwcrypto_crc
+{
+    struct rt_hwcrypto_ctx parent;          /**< Inherited from the standard device */
+    struct hwcrypto_crc_cfg crc_cfg;        /**< CRC configure */
+    const struct hwcrypto_crc_ops *ops;     /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief           Creating CRC Context
+ *
+ * @param device    Hardware crypto device
+ * @param mode      Setting default mode or custom mode
+ *
+ * @return          CRC context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
+                                               hwcrypto_crc_mode mode);
+
+/**
+ * @brief           Destroy CRC Context
+ *
+ * @param ctx       CRC context
+ */
+void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Processing a packet of data
+ *
+ * @param ctx       CRC context
+ * @param input     Data buffer to be Processed
+ * @param length    Data Buffer length
+ *
+ * @return          CRC value
+ */
+rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx, 
+                                   const rt_uint8_t *input, rt_size_t length);
+
+/**
+ * @brief           CRC context configuration
+ *
+ * @param ctx       CRC context
+ * @param cfg       CRC config
+ */
+void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx, 
+                         struct hwcrypto_crc_cfg *cfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 218 - 0
components/drivers/hwcrypto/hw_gcm.c

@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-05-14     tyx          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_gcm.h>
+
+/**
+ * @brief           Creating GCM Context
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of symmetric crypto context
+ *
+ * @return          GCM context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
+                                               hwcrypto_type crypt_type)
+{
+    struct rt_hwcrypto_ctx *ctx;
+
+    ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_GCM, sizeof(struct hwcrypto_gcm));
+    if (ctx)
+    {
+        ((struct hwcrypto_gcm *)ctx)->crypt_type = crypt_type;
+    }
+    return ctx;
+}
+
+/**
+ * @brief           Destroy GCM Context
+ *
+ * @param ctx       GCM context
+ */
+void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief           This function starts a GCM encryption or decryption operation
+ *
+ * @param ctx       GCM context
+ * @param add       The buffer holding the additional data
+ * @param add_len   The length of the additional data
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
+                               rt_size_t add_len)
+{
+    struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
+
+    if (gcm_ctx && gcm_ctx->ops->start)
+    {
+        return gcm_ctx->ops->start(gcm_ctx, add, add_len);
+    }
+    return -RT_EINVAL;
+}
+
+/**
+ * @brief           This function finishes the GCM operation and generates the authentication tag
+ *
+ * @param ctx       GCM context
+ * @param tag       The buffer for holding the tag
+ * @param tag_len   The length of the tag to generate
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag,
+                                rt_size_t tag_len)
+{
+    struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
+
+    if (gcm_ctx && gcm_ctx->ops->finish)
+    {
+        return gcm_ctx->ops->finish(gcm_ctx, tag, tag_len);
+    }
+    return -RT_EINVAL;
+}
+
+/**
+ * @brief           This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx       GCM context
+ * @param mode      Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length    The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in        The buffer holding the input data
+ * @param out       The buffer holding the output data
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+                               rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
+{
+    return rt_hwcrypto_symmetric_crypt(ctx, mode, length, in, out);
+}
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       GCM context
+ * @param key       The crypto key
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
+                                const rt_uint8_t *key, rt_uint32_t bitlen)
+{
+    return rt_hwcrypto_symmetric_setkey(ctx, key, bitlen);
+}
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       GCM context
+ * @param key       The crypto key buffer
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          Key length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
+                                rt_uint8_t *key, rt_uint32_t bitlen)
+{
+    return rt_hwcrypto_symmetric_getkey(ctx, key, bitlen);
+}
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv        The crypto initialization vector
+ * @param len       The crypto initialization vector length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
+                               const rt_uint8_t *iv, rt_size_t len)
+{
+    return rt_hwcrypto_symmetric_setiv(ctx, iv, len);
+}
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv        The crypto initialization vector buffer
+ * @param len       The crypto initialization vector buffer length
+ *
+ * @return          IV length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
+                               rt_uint8_t *iv, rt_size_t len)
+{
+    return rt_hwcrypto_symmetric_getiv(ctx, iv, len);
+}
+
+/**
+ * @brief           Set offset in initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv_off    The offset in IV
+ */
+void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
+{
+    rt_hwcrypto_symmetric_set_ivoff(ctx, iv_off);
+}
+
+/**
+ * @brief           Get offset in initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv_off    It must point to a valid memory
+ */
+void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
+{
+    rt_hwcrypto_symmetric_get_ivoff(ctx, iv_off);
+}
+
+/**
+ * @brief           This function copy GCM context
+ *
+ * @param des       The destination GCM context
+ * @param src       The GCM context to be copy
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
+                             const struct rt_hwcrypto_ctx *src)
+{
+    struct hwcrypto_gcm *gcm_des = (struct hwcrypto_gcm *)des;
+    struct hwcrypto_gcm *gcm_src = (struct hwcrypto_gcm *)src;
+
+    if (des != RT_NULL && src != RT_NULL)
+    {
+        gcm_des->crypt_type = gcm_src->crypt_type;
+        /* symmetric crypto context copy */
+        return rt_hwcrypto_symmetric_cpy(des, src);
+    }
+    return -RT_EINVAL;
+}
+
+/**
+ * @brief           Reset GCM context
+ *
+ * @param ctx       GCM context
+ */
+void rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_hwcrypto_symmetric_reset(ctx);
+}

+ 182 - 0
components/drivers/hwcrypto/hw_gcm.h

@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-05-14     tyx          the first version
+ */
+
+#ifndef __HW_GCM_H__
+#define __HW_GCM_H__
+
+#include "hw_symmetric.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_gcm;
+
+struct hwcrypto_gcm_ops
+{
+    rt_err_t (*start)(struct hwcrypto_gcm *gcm_ctx,
+                      const unsigned char *add, size_t add_len);    /**< Set additional data. start GCM operation */
+    rt_err_t (*finish)(struct hwcrypto_gcm *gcm_ctx,
+                       const unsigned char *tag, size_t tag_len);   /**< finish GCM operation. get tag */
+};
+
+/**
+ * @brief           GCM context. Hardware driver usage
+ */
+struct hwcrypto_gcm
+{
+    struct hwcrypto_symmetric parent;       /**< Inheritance from hardware symmetric crypto context */
+    hwcrypto_type crypt_type;               /**< symmetric crypto type. eg: AES/DES */
+    const struct hwcrypto_gcm_ops *ops;     /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief           Creating GCM Context
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of symmetric crypto context
+ *
+ * @return          GCM context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
+                                               hwcrypto_type crypt_type);
+
+/**
+ * @brief           Destroy GCM Context
+ *
+ * @param ctx       GCM context
+ */
+void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           This function starts a GCM encryption or decryption operation
+ *
+ * @param ctx       GCM context
+ * @param add       The buffer holding the additional data
+ * @param add_len   The length of the additional data
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
+                               rt_size_t add_len);
+
+/**
+ * @brief           This function finishes the GCM operation and generates the authentication tag
+ *
+ * @param ctx       GCM context
+ * @param tag       The buffer for holding the tag
+ * @param tag_len   The length of the tag to generate
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag,
+                                rt_size_t tag_len);
+
+/**
+ * @brief           This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx       GCM context
+ * @param mode      Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length    The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in        The buffer holding the input data
+ * @param out       The buffer holding the output data
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+                               rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       GCM context
+ * @param key       The crypto key
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
+                                const rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       GCM context
+ * @param key       The crypto key buffer
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          Key length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
+                                rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv        The crypto initialization vector
+ * @param len       The crypto initialization vector length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
+                               const rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv        The crypto initialization vector buffer
+ * @param len       The crypto initialization vector buffer length
+ *
+ * @return          IV length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
+                               rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief           Set offset in initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv_off    The offset in IV
+ */
+void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);
+
+/**
+ * @brief           Get offset in initialization vector
+ *
+ * @param ctx       GCM context
+ * @param iv_off    It must point to a valid memory
+ */
+void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off);
+
+/**
+ * @brief           This function copy GCM context
+ *
+ * @param des       The destination GCM context
+ * @param src       The GCM context to be copy
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
+                             const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief           Reset GCM context
+ *
+ * @param ctx       GCM context
+ */
+void rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 111 - 0
components/drivers/hwcrypto/hw_hash.c

@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-23     tyx          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_hash.h>
+
+/**
+ * @brief           Creating hash Context
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of hash context
+ *
+ * @return          Hash context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+    struct rt_hwcrypto_ctx *ctx;
+
+    ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_hash));
+    return ctx;
+}
+
+/**
+ * @brief           Destroy hash Context
+ *
+ * @param ctx       Hash context
+ */
+void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief           Get the final hash value
+ *
+ * @param ctx       Hash context
+ * @param output    Hash value buffer
+ * @param length    Hash value buffer length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length)
+{
+    if (ctx && ((struct hwcrypto_hash *)ctx)->ops->finish)
+    {
+        return ((struct hwcrypto_hash *)ctx)->ops->finish((struct hwcrypto_hash *)ctx, output, length);
+    }
+    return -RT_ERROR;
+}
+
+/**
+ * @brief           Processing a packet of data
+ *
+ * @param ctx       Hash context
+ * @param input     Data buffer to be Processed
+ * @param length    Data Buffer length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length)
+{
+    if (ctx && ((struct hwcrypto_hash *)ctx)->ops->update)
+    {
+        return ((struct hwcrypto_hash *)ctx)->ops->update((struct hwcrypto_hash *)ctx, input, length);
+    }
+    return -RT_ERROR;
+}
+
+/**
+ * @brief           This function copy hash context
+ *
+ * @param des       The destination hash context
+ * @param src       The hash context to be copy
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+    return rt_hwcrypto_ctx_cpy(des, src);
+}
+
+/**
+ * @brief           Reset hash context
+ *
+ * @param ctx       Hash context
+ */
+void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_hwcrypto_ctx_reset(ctx);
+}
+
+/**
+ * @brief           Setting hash context type
+ *
+ * @param ctx       Hash context
+ * @param type      Types of settings
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+    return rt_hwcrypto_set_type(ctx, type);
+}

+ 110 - 0
components/drivers/hwcrypto/hw_hash.h

@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-23     tyx          the first version
+ */
+
+#ifndef __HW_HASH_H__
+#define __HW_HASH_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_hash;
+
+struct hwcrypto_hash_ops
+{
+    rt_err_t (*update)(struct hwcrypto_hash *hash_ctx,
+                       const rt_uint8_t *in, rt_size_t length);     /**< Processing a packet of data */
+    rt_err_t (*finish)(struct hwcrypto_hash *hash_ctx,
+                       rt_uint8_t *out, rt_size_t length);          /**< Get the final hash value */
+};
+
+/**
+ * @brief           hash context. Hardware driver usage
+ */
+struct hwcrypto_hash
+{
+    struct rt_hwcrypto_ctx parent;              /**< Inheritance from hardware crypto context */
+    const struct hwcrypto_hash_ops *ops;        /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief           Creating hash Context
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of hash context
+ *
+ * @return          Hash context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device,
+                                                hwcrypto_type type);
+
+/**
+ * @brief           Destroy hash Context
+ *
+ * @param ctx       Hash context
+ */
+void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Get the final hash value
+ *
+ * @param ctx       Hash context
+ * @param output    Hash value buffer
+ * @param length    Hash value buffer length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length);
+
+/**
+ * @brief           Processing a packet of data
+ *
+ * @param ctx       Hash context
+ * @param input     Data buffer to be Processed
+ * @param length    Data Buffer length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length);
+
+/**
+ * @brief           This function copy hash context
+ *
+ * @param des       The destination hash context
+ * @param src       The hash context to be copy
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief           Reset hash context
+ *
+ * @param ctx       Hash context
+ */
+void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Setting hash context type
+ *
+ * @param ctx       Hash context
+ * @param type      Types of settings
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 110 - 0
components/drivers/hwcrypto/hw_rng.c

@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_rng.h>
+
+/* Used to save default RNG Context */
+static struct rt_hwcrypto_ctx *ctx_default;
+
+/**
+ * @brief           Creating RNG Context
+ *
+ * @param device    Hardware crypto device
+ *
+ * @return          RNG context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_rng_create(struct rt_hwcrypto_device *device)
+{
+    struct rt_hwcrypto_ctx *ctx;
+
+    ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_RNG, sizeof(struct hwcrypto_rng));
+    return ctx;
+}
+
+/**
+ * @brief           Destroy RNG Context
+ *
+ * @param ctx       RNG context
+ */
+void rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    /* Destroy the defaule RNG Context ? */
+    if (ctx == ctx_default)
+    {
+        ctx_default = RT_NULL;
+    }
+    rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief           Setting RNG default devices
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_rng_default(struct rt_hwcrypto_device *device)
+{
+    struct rt_hwcrypto_ctx *tmp_ctx;
+
+    /* if device is null, destroy default RNG Context */
+    if (device == RT_NULL)
+    {
+        if (ctx_default)
+        {
+            rt_hwcrypto_rng_destroy(ctx_default);
+            ctx_default = RT_NULL;
+        }
+        return RT_EOK;
+    }
+    /* Try create RNG Context */
+    tmp_ctx = rt_hwcrypto_rng_create(device);
+    if (tmp_ctx == RT_NULL)
+    {
+        return -RT_ERROR;
+    }
+    /* create RNG Context success, update default RNG Context */
+    rt_hwcrypto_rng_destroy(ctx_default);
+    ctx_default = tmp_ctx;
+
+    return RT_EOK;
+}
+
+/**
+ * @brief           Getting Random Numbers from RNG Context
+ *
+ * @param ctx       RNG context
+ * 
+ * @return          Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx *ctx)
+{
+    if (ctx)
+    {
+        return ((struct hwcrypto_rng *)ctx)->ops->update((struct hwcrypto_rng *)ctx);
+    }
+    return 0;
+}
+
+/**
+ * @brief           Return a random number
+ *
+ * @return          Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update(void)
+{
+    /* Default device does not exist ? */
+    if (ctx_default == RT_NULL)
+    {
+        /* try create Context from dufault device */
+        rt_hwcrypto_rng_default(rt_hwcrypto_dev_dufault());
+    }
+    return rt_hwcrypto_rng_update_ctx(ctx_default);
+}

+ 79 - 0
components/drivers/hwcrypto/hw_rng.h

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#ifndef __HW_RNG_H__
+#define __HW_RNG_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_rng;
+
+struct hwcrypto_rng_ops
+{
+    rt_uint32_t (*update)(struct hwcrypto_rng *ctx);    /**< Return a random number */
+};
+
+/**
+ * @brief           random context. Hardware driver usage
+ */
+struct hwcrypto_rng
+{
+    struct rt_hwcrypto_ctx parent;          /**< Inheritance from hardware crypto context */
+    const struct hwcrypto_rng_ops *ops;     /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief           Creating RNG Context
+ *
+ * @param device    Hardware crypto device
+ *
+ * @return          RNG context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_rng_create(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief           Destroy RNG Context
+ *
+ * @param ctx       RNG context
+ */
+void rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Setting RNG default devices
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_rng_default(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief           Getting Random Numbers from RNG Context
+ *
+ * @param ctx       RNG context
+ * 
+ * @return          Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Return a random number
+ *
+ * @return          Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 276 - 0
components/drivers/hwcrypto/hw_symmetric.c

@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_symmetric.h>
+
+/**
+ * @brief           Creating Symmetric Encryption and Decryption Context
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of symmetric crypto context
+ *
+ * @return          Symmetric crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+    struct rt_hwcrypto_ctx *ctx;
+
+    ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_symmetric));
+    return ctx;
+}
+
+/**
+ * @brief           Destroy Symmetric Encryption and Decryption Context
+ *
+ * @param ctx       Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief           This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx       Symmetric crypto context
+ * @param mode      Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length    The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in        The buffer holding the input data
+ * @param out       The buffer holding the output data
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode, rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
+{
+    struct hwcrypto_symmetric *symmetric_ctx;
+    struct hwcrypto_symmetric_info symmetric_info;
+    rt_err_t err;
+
+    if (ctx == RT_NULL)
+    {
+        return -RT_EINVAL;
+    }
+    symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+    if (symmetric_ctx->ops->crypt == RT_NULL)
+    {
+        return -RT_ERROR;
+    }
+    if (mode != HWCRYPTO_MODE_ENCRYPT && mode != HWCRYPTO_MODE_DECRYPT)
+    {
+        return -EINVAL;
+    }
+
+    /* Input information packaging */
+    symmetric_info.mode = mode;
+    symmetric_info.in = in;
+    symmetric_info.out = out;
+    symmetric_info.length = length;
+
+    /* Calling Hardware Encryption and Decryption Function */
+    err = symmetric_ctx->ops->crypt(symmetric_ctx, &symmetric_info);
+
+    /* clean up flags */
+    symmetric_ctx->flags &= ~(SYMMTRIC_MODIFY_KEY | SYMMTRIC_MODIFY_IV | SYMMTRIC_MODIFY_IVOFF);
+    return err;
+}
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       Symmetric crypto context
+ * @param key       The crypto key
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen)
+{
+    struct hwcrypto_symmetric *symmetric_ctx;
+
+    if (ctx && bitlen <= RT_HWCRYPTO_KEYBIT_MAX_SIZE)
+    {
+        symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+        rt_memcpy(symmetric_ctx->key, key, bitlen >> 3);
+        /* Record key length */
+        symmetric_ctx->key_bitlen = bitlen;
+        /* Key change flag set up */
+        symmetric_ctx->flags |= SYMMTRIC_MODIFY_KEY;
+        return RT_EOK;
+    }
+
+    return -RT_EINVAL;
+}
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       Symmetric crypto context
+ * @param key       The crypto key buffer
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          Key length of copy
+ */
+int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen)
+{
+    struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+
+    if (ctx && bitlen >= symmetric_ctx->key_bitlen)
+    {
+        rt_memcpy(key, symmetric_ctx->key, symmetric_ctx->key_bitlen >> 3);
+        return symmetric_ctx->key_bitlen;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv        The crypto initialization vector
+ * @param len       The crypto initialization vector length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len)
+{
+    struct hwcrypto_symmetric *symmetric_ctx;
+
+    if (ctx && len <= RT_HWCRYPTO_IV_MAX_SIZE)
+    {
+        symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+        rt_memcpy(symmetric_ctx->iv, iv, len);
+        symmetric_ctx->iv_len = len;
+        /* IV change flag set up */
+        symmetric_ctx->flags |= SYMMTRIC_MODIFY_IV;
+        return RT_EOK;
+    }
+
+    return -RT_EINVAL;
+}
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv        The crypto initialization vector buffer
+ * @param len       The crypto initialization vector buffer length
+ *
+ * @return          IV length of copy
+ */
+int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len)
+{
+    struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;;
+
+    if (ctx && len >= symmetric_ctx->iv_len)
+    {
+        rt_memcpy(iv, symmetric_ctx->iv, symmetric_ctx->iv_len);
+        return symmetric_ctx->iv_len;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief           Set offset in initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv_off    The offset in IV
+ */
+void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
+{
+    if (ctx)
+    {
+        ((struct hwcrypto_symmetric *)ctx)->iv_off = iv_off;
+        /* iv_off change flag set up */
+        ((struct hwcrypto_symmetric *)ctx)->flags |= SYMMTRIC_MODIFY_IVOFF;
+    }
+}
+
+/**
+ * @brief           Get offset in initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv_off    It must point to a valid memory
+ */
+void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
+{
+    if (ctx && iv_off)
+    {
+        *iv_off = ((struct hwcrypto_symmetric *)ctx)->iv_off;
+    }
+}
+
+/**
+ * @brief           This function copy symmetric crypto context
+ *
+ * @param des       The destination symmetric crypto context
+ * @param src       The symmetric crypto context to be copy
+ * 
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+    struct hwcrypto_symmetric *symmetric_des = (struct hwcrypto_symmetric *)des;
+    struct hwcrypto_symmetric *symmetric_src = (struct hwcrypto_symmetric *)src;
+
+    if (des != RT_NULL && src != RT_NULL)
+    {
+        /* Copy Symmetric Encryption and Decryption Context Information */
+        symmetric_des->flags      = symmetric_src->flags     ;
+        symmetric_des->iv_len     = symmetric_src->iv_len    ;
+        symmetric_des->iv_off     = symmetric_src->iv_off    ;
+        symmetric_des->key_bitlen = symmetric_src->key_bitlen;
+        rt_memcpy(symmetric_des->iv, symmetric_src->iv, symmetric_src->iv_len);
+        rt_memcpy(symmetric_des->key, symmetric_src->key, symmetric_src->key_bitlen >> 3);
+
+        /* Hardware context copy */
+        return rt_hwcrypto_ctx_cpy(des, src);
+    }
+    return -RT_EINVAL;
+}
+
+/**
+ * @brief           Reset symmetric crypto context
+ *
+ * @param ctx       Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx)
+{
+    struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+    if (ctx != RT_NULL)
+    {
+        /* Copy Symmetric Encryption and Decryption Context Information */
+        symmetric_ctx->flags      = 0x00;
+        symmetric_ctx->iv_len     = 0x00;
+        symmetric_ctx->iv_off     = 0x00;
+        symmetric_ctx->key_bitlen = 0x00;
+        rt_memset(symmetric_ctx->iv, 0, RT_HWCRYPTO_IV_MAX_SIZE);
+        rt_memset(symmetric_ctx->key, 0, RT_HWCRYPTO_KEYBIT_MAX_SIZE >> 3);
+
+        /* Hardware context reset */
+        rt_hwcrypto_ctx_reset(ctx);
+    }
+}
+
+/**
+ * @brief           Setting symmetric crypto context type
+ *
+ * @param ctx       Symmetric crypto context
+ * @param type      Types of settings
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+    return rt_hwcrypto_set_type(ctx, type);
+}

+ 189 - 0
components/drivers/hwcrypto/hw_symmetric.h

@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-25     tyx          the first version
+ */
+
+#ifndef __HW_SYMMETRIC_H__
+#define __HW_SYMMETRIC_H__
+
+#include <hwcrypto.h>
+
+#ifndef RT_HWCRYPTO_IV_MAX_SIZE
+#define RT_HWCRYPTO_IV_MAX_SIZE  (16)
+#endif
+#ifndef RT_HWCRYPTO_KEYBIT_MAX_SIZE
+#define RT_HWCRYPTO_KEYBIT_MAX_SIZE  (256)
+#endif
+
+#define SYMMTRIC_MODIFY_KEY    (0x1 << 0)
+#define SYMMTRIC_MODIFY_IV     (0x1 << 1)
+#define SYMMTRIC_MODIFY_IVOFF  (0x1 << 2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_symmetric;
+struct hwcrypto_symmetric_info;
+
+struct hwcrypto_symmetric_ops
+{
+    rt_err_t (*crypt)(struct hwcrypto_symmetric *symmetric_ctx,
+                      struct hwcrypto_symmetric_info *symmetric_info);  /**< Hardware Symmetric Encryption and Decryption Callback */
+};
+
+/**
+ * @brief           Hardware driver usage, including input and output information
+ */
+struct hwcrypto_symmetric_info
+{
+    hwcrypto_mode mode;             /**< crypto mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT */
+    const rt_uint8_t *in;           /**< Input data */
+    rt_uint8_t *out;                /**< Output data will be written */
+    rt_size_t length;               /**< The length of the input data in Bytes. It's a multiple of block size. */
+};
+
+/**
+ * @brief           Symmetric crypto context. Hardware driver usage
+ */
+struct hwcrypto_symmetric
+{
+    struct rt_hwcrypto_ctx parent;                      /**< Inheritance from hardware crypto context */
+    rt_uint32_t flags;                                  /**< key or iv or ivoff has been changed. The flag will be set up */
+    rt_int32_t iv_len;                                  /**< initialization vector effective length */
+    rt_int32_t iv_off;                                  /**< The offset in IV */
+    rt_uint8_t iv[RT_HWCRYPTO_IV_MAX_SIZE];             /**< The initialization vector */
+    rt_uint8_t key[RT_HWCRYPTO_KEYBIT_MAX_SIZE >> 3];   /**< The crypto key */
+    rt_int32_t key_bitlen;                              /**< The crypto key bit length */
+    const struct hwcrypto_symmetric_ops *ops;           /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief           Creating Symmetric Encryption and Decryption Context
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of symmetric crypto context
+ *
+ * @return          Symmetric crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device,
+        hwcrypto_type type);
+
+/**
+ * @brief           Destroy Symmetric Encryption and Decryption Context
+ *
+ * @param ctx       Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx       Symmetric crypto context
+ * @param mode      Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length    The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in        The buffer holding the input data
+ * @param out       The buffer holding the output data
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+                                     rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       Symmetric crypto context
+ * @param key       The crypto key
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx       Symmetric crypto context
+ * @param key       The crypto key buffer
+ * @param bitlen    The crypto key bit length
+ *
+ * @return          Key length of copy
+ */
+int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief           Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv        The crypto initialization vector
+ * @param len       The crypto initialization vector length
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief           Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv        The crypto initialization vector buffer
+ * @param len       The crypto initialization vector buffer length
+ *
+ * @return          IV length of copy
+ */
+int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief           Set offset in initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv_off    The offset in IV
+ */
+void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);
+
+/**
+ * @brief           Get offset in initialization vector
+ *
+ * @param ctx       Symmetric crypto context
+ * @param iv_off    It must point to a valid memory
+ */
+void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off);
+
+/**
+ * @brief           This function copy symmetric crypto context
+ *
+ * @param des       The destination symmetric crypto context
+ * @param src       The symmetric crypto context to be copy
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief           Reset symmetric crypto context
+ *
+ * @param ctx       Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Setting symmetric crypto context type
+ *
+ * @param ctx       Symmetric crypto context
+ * @param type      Types of settings
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 255 - 0
components/drivers/hwcrypto/hwcrypto.c

@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-23     tyx          the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hwcrypto.h>
+
+/**
+ * @brief           Setting context type (Direct calls are not recommended)
+ *
+ * @param ctx       Crypto context
+ * @param type      Types of settings
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+    if (ctx)
+    {
+        /* Is it the same category? */
+        if ((ctx->type & HWCRYPTO_MAIN_TYPE_MASK) == (type & HWCRYPTO_MAIN_TYPE_MASK))
+        {
+            ctx->type = type;
+            return RT_EOK;
+        }
+        /* Context is empty type */
+        else if (ctx->type == HWCRYPTO_TYPE_NULL)
+        {
+            ctx->type = type;
+            return RT_EOK;
+        }
+        else
+        {
+            return -RT_ERROR;
+        }
+    }
+    return -RT_EINVAL;
+}
+
+/**
+ * @brief           Reset context type (Direct calls are not recommended)
+ *
+ * @param ctx       Crypto context
+ *
+ */
+void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx)
+{
+    if (ctx && ctx->device->ops->reset)
+    {
+        ctx->device->ops->reset(ctx);
+    }
+}
+
+/**
+ * @brief           Init crypto context
+ *
+ * @param ctx       The context to initialize
+ * @param device    Hardware crypto device
+ * @param type      Type of context
+ * @param obj_size  Size of context object
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx, struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+    rt_err_t err;
+
+    /* Setting context type */
+    rt_hwcrypto_set_type(ctx, type);
+    ctx->device = device;
+    /* Create hardware context */
+    err = ctx->device->ops->create(ctx);
+    if (err != RT_EOK)
+    {
+        return err;
+    }
+    return RT_EOK;
+}
+
+/**
+ * @brief           Create crypto context
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of context
+ * @param obj_size  Size of context object
+ *
+ * @return          Crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device, hwcrypto_type type, rt_uint32_t obj_size)
+{
+    struct rt_hwcrypto_ctx *ctx;
+    rt_err_t err;
+
+    /* Parameter checking */
+    if (device == RT_NULL || obj_size < sizeof(struct rt_hwcrypto_ctx))
+    {
+        return RT_NULL;
+    }
+    ctx = rt_malloc(obj_size);
+    if (ctx == RT_NULL)
+    {
+        return ctx;
+    }
+    rt_memset(ctx, 0, obj_size);
+    /* Init context */
+    err = rt_hwcrypto_ctx_init(ctx, device, type);
+    if (err != RT_EOK)
+    {
+        rt_free(ctx);
+        ctx = RT_NULL;
+    }
+    return ctx;
+}
+
+/**
+ * @brief           Destroy crypto context
+ *
+ * @param device    Crypto context
+ */
+void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    if (ctx == RT_NULL)
+    {
+        return;
+    }
+    /* Destroy hardware context */
+    if (ctx->device->ops->destroy)
+    {
+        ctx->device->ops->destroy(ctx);
+    }
+    /* Free the resources */
+    rt_free(ctx);
+}
+
+/**
+ * @brief           Copy crypto context
+ *
+ * @param des       The destination context
+ * @param src       The context to be copy
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+    if (des == RT_NULL || src == RT_NULL)
+    {
+        return -RT_EINVAL;
+    }
+
+    /* The equipment is different or of different types and cannot be copied */
+    if (des->device != src->device ||
+        (des->type & HWCRYPTO_MAIN_TYPE_MASK) != (src->type & HWCRYPTO_MAIN_TYPE_MASK))
+    {
+        return -RT_EINVAL;
+    }
+    des->type = src->type;
+    /* Calling Hardware Context Copy Function */
+    return src->device->ops->copy(des, src);
+}
+
+/**
+ * @brief           Get the default hardware crypto device
+ *
+ * @return          Hardware crypto device
+ *
+ */
+struct rt_hwcrypto_device *rt_hwcrypto_dev_dufault(void)
+{
+    static struct rt_hwcrypto_device *hwcrypto_dev;
+
+    /* If there is a default device, return the device */
+    if (hwcrypto_dev)
+    {
+        return hwcrypto_dev;
+    }
+    /* Find by default device name */
+    hwcrypto_dev = (struct rt_hwcrypto_device *)rt_device_find(RT_HWCRYPTO_DEFAULT_NAME);
+    return hwcrypto_dev;
+}
+
+/**
+ * @brief           Get the unique ID of the device
+ *
+ * @param device    Device object
+ *
+ * @return          Device unique ID
+ */
+rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device)
+{
+    if (device)
+    {
+        return device->id;
+    }
+    return 0;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops hwcrypto_ops =
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL
+};
+#endif
+
+/**
+ * @brief           Register hardware crypto device
+ *
+ * @param device    Hardware crypto device
+ * @param name      Name of device
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name)
+{
+    rt_err_t err;
+
+    RT_ASSERT(device != RT_NULL);
+    RT_ASSERT(name != RT_NULL);
+    RT_ASSERT(device->ops != RT_NULL);
+    RT_ASSERT(device->ops->create != RT_NULL);
+    RT_ASSERT(device->ops->destroy != RT_NULL);
+    RT_ASSERT(device->ops->copy != RT_NULL);
+    RT_ASSERT(device->ops->reset != RT_NULL);
+
+    rt_memset(&device->parent, 0, sizeof(struct rt_device));
+#ifdef RT_USING_DEVICE_OPS
+    device->parent.ops = &hwcrypto_ops;
+#else
+    device->parent.init       = RT_NULL;
+    device->parent.open       = RT_NULL;
+    device->parent.close      = RT_NULL;
+    device->parent.read       = RT_NULL;
+    device->parent.write      = RT_NULL;
+    device->parent.control    = RT_NULL;
+#endif
+
+    device->parent.user_data  = RT_NULL;
+    device->parent.type = RT_Device_Class_Miscellaneous;
+
+    /* Register device */
+    err = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
+
+    return err;
+}

+ 193 - 0
components/drivers/hwcrypto/hwcrypto.h

@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-23     tyx          the first version
+ */
+
+#ifndef __HWCRYPTO_H__
+#define __HWCRYPTO_H__
+
+#include <rtthread.h>
+
+#ifndef RT_HWCRYPTO_DEFAULT_NAME
+#define RT_HWCRYPTO_DEFAULT_NAME    ("hwcryto")
+#endif
+
+#define HWCRYPTO_MAIN_TYPE_MASK     (0xffffUL << 16)
+#define HWCRYPTO_SUB_TYPE_MASK      (0xffUL << 8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+    HWCRYPTO_TYPE_NULL = 0x00000000,
+
+    /* Main Type */
+    /* symmetric Type */
+    HWCRYPTO_TYPE_HEAD    = __LINE__,
+    HWCRYPTO_TYPE_AES     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< AES */
+    HWCRYPTO_TYPE_DES     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< DES */
+    HWCRYPTO_TYPE_3DES    = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< 3DES */
+    HWCRYPTO_TYPE_RC4     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< RC4 */
+    HWCRYPTO_TYPE_GCM     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< GCM */
+    /* HASH Type */
+    HWCRYPTO_TYPE_MD5     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< MD5 */
+    HWCRYPTO_TYPE_SHA1    = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< SHA1 */
+    HWCRYPTO_TYPE_SHA2    = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< SHA2 */
+    /* Other Type */
+    HWCRYPTO_TYPE_RNG     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< RNG */
+    HWCRYPTO_TYPE_CRC     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< CRC */
+    HWCRYPTO_TYPE_BIGNUM  = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< BIGNUM */
+
+    /* AES Subtype */
+    HWCRYPTO_TYPE_AES_ECB = HWCRYPTO_TYPE_AES | (0x01 << 8),
+    HWCRYPTO_TYPE_AES_CBC = HWCRYPTO_TYPE_AES | (0x02 << 8),
+    HWCRYPTO_TYPE_AES_CFB = HWCRYPTO_TYPE_AES | (0x03 << 8),
+    HWCRYPTO_TYPE_AES_CTR = HWCRYPTO_TYPE_AES | (0x04 << 8),
+    HWCRYPTO_TYPE_AES_OFB = HWCRYPTO_TYPE_AES | (0x05 << 8),
+
+    /* DES Subtype */
+    HWCRYPTO_TYPE_DES_ECB = HWCRYPTO_TYPE_DES | (0x01 << 8),
+    HWCRYPTO_TYPE_DES_CBC = HWCRYPTO_TYPE_DES | (0x02 << 8),
+
+    /* 3DES Subtype */
+    HWCRYPTO_TYPE_3DES_ECB = HWCRYPTO_TYPE_3DES | (0x01 << 8),
+    HWCRYPTO_TYPE_3DES_CBC = HWCRYPTO_TYPE_3DES | (0x02 << 8),
+
+    /* SHA2 Subtype */
+    HWCRYPTO_TYPE_SHA224 = HWCRYPTO_TYPE_SHA2 | (0x01 << 8),
+    HWCRYPTO_TYPE_SHA256 = HWCRYPTO_TYPE_SHA2 | (0x02 << 8),
+    HWCRYPTO_TYPE_SHA384 = HWCRYPTO_TYPE_SHA2 | (0x03 << 8),
+    HWCRYPTO_TYPE_SHA512 = HWCRYPTO_TYPE_SHA2 | (0x04 << 8),
+} hwcrypto_type;
+
+typedef enum
+{
+    HWCRYPTO_MODE_ENCRYPT = 0x1,        /**< Encryption operations */
+    HWCRYPTO_MODE_DECRYPT = 0x2,        /**< Decryption operations */
+    HWCRYPTO_MODE_UNKNOWN = 0x7fffffff, /**< Unknown */
+} hwcrypto_mode;
+
+struct rt_hwcrypto_ctx;
+
+struct rt_hwcrypto_ops
+{
+    rt_err_t (*create)(struct rt_hwcrypto_ctx *ctx);        /**< Creating hardware context */
+    void (*destroy)(struct rt_hwcrypto_ctx *ctx);           /**< Delete hardware context */
+    rt_err_t (*copy)(struct rt_hwcrypto_ctx *des,
+                     const struct rt_hwcrypto_ctx *src);    /**< Cpoy hardware context */
+    void (*reset)(struct rt_hwcrypto_ctx *ctx);             /**< Reset hardware context */
+};
+
+struct rt_hwcrypto_device
+{
+    struct rt_device parent;                            /**< Inherited from the standard device */
+    const struct rt_hwcrypto_ops *ops;                  /**< Hardware crypto ops */
+    rt_uint64_t id;                                     /**< Unique id */
+    void *user_data;                                    /**< Device user data */
+};
+
+struct rt_hwcrypto_ctx
+{
+    struct rt_hwcrypto_device *device;  /**< Binding device */
+    hwcrypto_type type;                 /**< Encryption and decryption types */
+    void *contex;                       /**< Hardware context */
+};
+
+/**
+ * @brief           Setting context type (Direct calls are not recommended)
+ *
+ * @param ctx       Crypto context
+ * @param type      Types of settings
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+/**
+ * @brief           Reset context type (Direct calls are not recommended)
+ *
+ * @param ctx       Crypto context
+ */
+void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Init crypto context (Direct calls are not recommended)
+ *
+ * @param ctx       The context to initialize
+ * @param device    Hardware crypto device
+ * @param type      Type of context
+ * @param obj_size  Size of context object
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx,
+                              struct rt_hwcrypto_device *device, hwcrypto_type type);
+
+/**
+ * @brief           Create crypto context (Direct calls are not recommended)
+ *
+ * @param device    Hardware crypto device
+ * @param type      Type of context
+ * @param obj_size  Size of context object
+ *
+ * @return          Crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device,
+                                               hwcrypto_type type, rt_uint32_t obj_size);
+
+/**
+ * @brief           Destroy crypto context (Direct calls are not recommended)
+ *
+ * @param device    Crypto context
+ */
+void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief           Copy crypto context (Direct calls are not recommended)
+ *
+ * @param des       The destination context
+ * @param src       The context to be copy
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief           Register hardware crypto device
+ *
+ * @param device    Hardware crypto device
+ * @param name      Name of device
+ *
+ * @return          RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name);
+
+/**
+ * @brief           Get the default hardware crypto device
+ *
+ * @return          Hardware crypto device
+ *
+ */
+struct rt_hwcrypto_device *rt_hwcrypto_dev_dufault(void);
+
+/**
+ * @brief           Get the unique ID of the device
+ *
+ * @param device    Device object
+ *
+ * @return          Device unique ID
+ */
+rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 23 - 0
components/drivers/include/drivers/crypto.h

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-05-17     tyx          the first version
+ */
+
+#ifndef __CRYPTO_H__
+#define __CRYPTO_H__
+
+#include <rtthread.h>
+#include <hwcrypto.h>
+#include <hw_symmetric.h>
+#include <hw_rng.h>
+#include <hw_hash.h>
+#include <hw_crc.h>
+#include <hw_gcm.h>
+#include <hw_bignum.h>
+
+#endif

+ 4 - 0
components/drivers/include/rtdevice.h

@@ -122,6 +122,10 @@ extern "C" {
 #include "drivers/mtdnand.h"
 #endif
 
+#ifdef RT_USING_HWCRYPTO
+#include "drivers/crypto.h"
+#endif
+
 #ifdef __cplusplus
 }
 #endif