|
@@ -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);
|
|
|
+}
|