open_source文件夹下新增HiTLS文件夹
authorluozheng <1732036298@qq.com>
Sat, 19 Jul 2025 06:20:27 +0000 (14:20 +0800)
committerluozheng <1732036298@qq.com>
Sat, 19 Jul 2025 06:20:27 +0000 (14:20 +0800)
62 files changed:
code/sdk/open_source/HiTLS/bsl/err/include/bsl_err_internal.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/err/src/avl.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/err/src/avl.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/err/src/err.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/include/bsl_binlog_id.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/include/bsl_bytes.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/include/bsl_list.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/log/include/bsl_log_internal.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/log/src/log.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/sal/include/sal_mem.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/sal/include/sal_threadlock.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/sal/src/sal_mem.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/bsl/sal/src/sal_threadlock.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/aes/include/crypt_aes.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/aes/src/crypt_aes.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/hkdf/include/crypt_hkdf.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/hkdf/src/hkdf.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/hmac/include/crypt_hmac.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/hmac/src/hmac.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/include/crypt_arm.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/include/crypt_binlog_id.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/include/crypt_encode.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/include/crypt_local_types.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/include/crypt_util_rand.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/include/crypt_utils.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_cbc.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ccm.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_cfb.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_chacha20poly1305.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ctr.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ecb.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_gcm.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ofb.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_xts.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/src/asm_aes_gcm.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/src/asm_sm4.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/src/modes_gcm.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/src/modes_local.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/src/noasm_ghash.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/modes/src/poly1305_core.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/sha2/include/crypt_sha2.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/sha2/src/noasm_sha256.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/sha2/src/sha2_256.c [new file with mode: 0644]
code/sdk/open_source/HiTLS/crypto/sha2/src/sha2_core.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/bsl/bsl_err.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/bsl/bsl_errno.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/bsl/bsl_log.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/bsl/bsl_sal.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/bsl/bsl_uio.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_algid.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_check_macro.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_eal_bn.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_eal_cipher.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_eal_kdf.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_eal_mac.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_eal_md.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_eal_pkey.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_eal_rand.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_errno.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_mpa_aead.h [new file with mode: 0644]
code/sdk/open_source/HiTLS/include/crypto/crypt_types.h [new file with mode: 0644]

diff --git a/code/sdk/open_source/HiTLS/bsl/err/include/bsl_err_internal.h b/code/sdk/open_source/HiTLS/bsl/err/include/bsl_err_internal.h
new file mode 100644 (file)
index 0000000..43ef6a8
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * @file bsl_err_internal.h
+ * Description: 错误码模块
+ * Author: zhanghui
+ * Create: 2023-05-30
+ */
+
+#ifndef BSL_ERR_INTERNAL_H
+#define BSL_ERR_INTERNAL_H
+
+#include <stdint.h>
+
+/**
+ * @ingroup BSL
+ * @brief 将错误信息存入错误信息栈中
+ *
+ * @par 描述:
+ * 将错误信息存入错误信息栈中
+ *
+ * @attention err不能为0
+ * @param err [IN] 错误码,高16位表示模块子模块id,低16位表示错误号
+ * @param file [IN] 文件名,不含目录路径
+ * @param lineNo [IN] 错误产生的行号
+ */
+void BSL_ERR_PushError(int32_t err, const char *file, uint32_t lineNo);
+
+/**
+ * @ingroup BSL
+ * @brief 将错误信息存入错误信息栈中
+ *
+ * @par 描述:
+ * 将错误信息存入错误信息栈中
+ *
+ * @attention err不能为0
+ */
+#define BSL_ERR_PUSH_ERROR(e) BSL_ERR_PushError((e), __FILENAME__, __LINE__)
+
+#endif // BSL_ERR_INTERNAL_H
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/bsl/err/src/avl.c b/code/sdk/open_source/HiTLS/bsl/err/src/avl.c
new file mode 100644 (file)
index 0000000..594ea96
--- /dev/null
@@ -0,0 +1,290 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * Description: 平衡二叉树的实现
+ * Author: guzhou
+ * Create: 2022-02-18
+ */
+
+#include <inttypes.h>
+#include "sal_mem.h"
+#include "bsl_log_internal.h"
+#include "bsl_binlog_id.h"
+#include "avl.h"
+
+// avl树的最大高度
+#define AVL_MAX_HEIGHT 64
+
+static uint32_t GetMaxHeight(uint32_t a, uint32_t b)
+{
+    if (a >= b) {
+        return a;
+    } else {
+        return b;
+    }
+}
+
+static uint32_t GetAvlTreeHeight(const BSL_AvlTree *node)
+{
+    if (node == NULL) {
+        return 0;
+    } else {
+        return node->height;
+    }
+}
+
+static void UpdateAvlTreeHeight(BSL_AvlTree *node)
+{
+    if (node != NULL) {
+        uint32_t leftHeight = GetAvlTreeHeight(node->leftNode);
+        uint32_t rightHeight = GetAvlTreeHeight(node->rightNode);
+        if (node->height >= AVL_MAX_HEIGHT) {
+            LOG_BINLOG_FIXLEN(BINLOG_ID05001, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+                "avl tree height exceed max limit", NULL, NULL, NULL, NULL);
+            return;
+        }
+        node->height = GetMaxHeight(leftHeight, rightHeight) + 1u;
+    }
+}
+
+/**
+ * @brief   创建avl节点
+ * @param   nodeId [IN]节点ID
+ *          data   [IN]节点存储的数据
+ * @return  curNode 申请成功返回节点
+ *          NULL    申请失败
+ */
+BSL_AvlTree *BSL_AVL_MakeLeafNode(BSL_ElementData data)
+{
+    BSL_AvlTree *curNode = (BSL_AvlTree *)SAL_MALLOC(sizeof(BSL_AvlTree));
+    if (curNode == NULL) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05002, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "MALLOC for avl tree node failed", NULL, NULL, NULL, NULL);
+        return NULL;
+    }
+
+    curNode->height = 1;
+    curNode->rightNode = NULL;
+    curNode->leftNode = NULL;
+    curNode->data = data;
+
+    return curNode;
+}
+
+/**
+ * @brief   AVL左旋转
+ * @param   root [IN] 待旋转的根节点
+ * @return  rNode 旋转后的根节点
+ */
+static BSL_AvlTree *AVL_RotateLeft(BSL_AvlTree *root)
+{
+    /* Rotate Left
+                        10                              20
+                      5    20    --Rotate Left--->    10  30
+                             30                      5      40
+                              40
+
+    此场景下输入根节点为10, 输出为20 */
+    BSL_AvlTree *rNode = root->rightNode;
+    BSL_AvlTree *lNode = rNode->leftNode;
+    root->rightNode = lNode;
+    rNode->leftNode = root;
+    UpdateAvlTreeHeight(root);
+    UpdateAvlTreeHeight(rNode);
+    return rNode;
+}
+
+/**
+ * @brief   AVL右旋转
+ * @param   root [IN] 待旋转的根节点
+ * @return  lNode 旋转后的根节点
+ */
+static BSL_AvlTree *AVL_RotateRight(BSL_AvlTree *root)
+{
+    /* Rotate Right
+                        40                              30
+                       /  \                            /  \
+                     30    50   --Rotate Right--->   20    40
+                   20  35                          10    35  50
+                 10
+    此场景下输入根节点为40, 输出为30 */
+    BSL_AvlTree *lNode = root->leftNode;
+    BSL_AvlTree *rNode = lNode->rightNode;
+    root->leftNode = rNode;
+    lNode->rightNode = root;
+    UpdateAvlTreeHeight(root);
+    UpdateAvlTreeHeight(lNode);
+    return lNode;
+}
+
+/**
+ * @brief   AVL右平衡
+ * @param   root [IN] 待平衡的根节点
+ * @return  root 平衡后的根节点
+ */
+static BSL_AvlTree *AVL_RebalanceRight(BSL_AvlTree *root)
+{
+    // 左右子树高度只相差1
+    if ((GetAvlTreeHeight(root->leftNode) + 1u) >= GetAvlTreeHeight(root->rightNode)) {
+        UpdateAvlTreeHeight(root);
+        return root;
+    }
+    /* 左子树高度大于右子树, 先右旋转再左旋转 */
+    BSL_AvlTree *curNode = root->rightNode;
+    if (GetAvlTreeHeight(curNode->leftNode) > GetAvlTreeHeight(curNode->rightNode)) {
+        root->rightNode = AVL_RotateRight(curNode);
+    }
+    return AVL_RotateLeft(root);
+}
+
+/**
+ * @brief   AVL左平衡
+ * @param   root [IN] 待平衡的根节点
+ * @return  root 平衡后的根节点
+ */
+static BSL_AvlTree *AVL_RebalanceLeft(BSL_AvlTree *root)
+{
+    // 左右子树高度只相差1
+    if ((GetAvlTreeHeight(root->rightNode) + 1u) >= GetAvlTreeHeight(root->leftNode)) {
+        UpdateAvlTreeHeight(root);
+        return root;
+    }
+    /* 右子树高度大于左子树, 先左旋转再右旋转 */
+    BSL_AvlTree *curNode = root->leftNode;
+    if (GetAvlTreeHeight(curNode->rightNode) > GetAvlTreeHeight(curNode->leftNode)) {
+        root->leftNode = AVL_RotateLeft(curNode);
+    }
+    return AVL_RotateRight(root);
+}
+
+static void AVL_FreeData(BSL_ElementData data, BSL_AVL_DATA_FREE_FUNC freeFunc)
+{
+    if (freeFunc != NULL) {
+        freeFunc(data);
+    }
+}
+
+BSL_AvlTree *BSL_AVL_InsertNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AvlTree *node)
+{
+    if (root == NULL) {
+        node->nodeId = nodeId;
+        return node;
+    }
+
+    if (root->nodeId > nodeId) {
+        // nodeId比根节点nodeId小, 插入左子树
+        root->leftNode = BSL_AVL_InsertNode(root->leftNode, nodeId, node);
+
+        return AVL_RebalanceLeft(root);
+    } else if (root->nodeId < nodeId) {
+        // nodeId比根节点nodeId大, 插入右子树
+        root->rightNode = BSL_AVL_InsertNode(root->rightNode, nodeId, node);
+
+        return AVL_RebalanceRight(root);
+    }
+
+    /* key相同不能插入 */
+    LOG_BINLOG_FIXLEN(BINLOG_ID05003, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+        "AVL tree insert key nodeId(%"PRIu64") already exist", nodeId, NULL, NULL, NULL);
+    return NULL;
+}
+
+BSL_AvlTree *BSL_AVL_SearchNode(BSL_AvlTree *root, uint64_t nodeId)
+{
+    BSL_AvlTree *curNode = root;
+    while (curNode != NULL) {
+        // 匹配到节点
+        if (curNode->nodeId == nodeId) {
+            break;
+        } else if (curNode->nodeId > nodeId) {
+            // nodeId比根节点nodeId小, 搜索左子树
+            curNode = curNode->leftNode;
+        } else {
+            // nodeId比根节点nodeId大, 搜索右子树
+            curNode = curNode->rightNode;
+        }
+    }
+
+    // 搜索不到指定节点, 返回NULL
+    return curNode;
+}
+
+/**
+ * @brief   删除同时拥有左右子节点的指定avl节点
+ * @param   rmNodeChild [IN] 待删除avl节点的子节点
+ *          removeNode  [IN] 待删除avl节点
+ * @return  root 返回删除后的avl树根节点
+ */
+static BSL_AvlTree *AVL_DeleteNodeWithTwoChilds(BSL_AvlTree *rmNodeChild, BSL_AvlTree *removeNode)
+{
+    if (rmNodeChild == NULL || removeNode == NULL) {
+        return NULL;
+    }
+
+    if (rmNodeChild->rightNode == NULL) {
+        // 无论rmNodeChild是否有左节点, 都将左节点与祖父节点连接起来
+        BSL_AvlTree *curNode = rmNodeChild->leftNode;
+        removeNode->nodeId = rmNodeChild->nodeId;
+        removeNode->data = rmNodeChild->data;
+
+        SAL_FREE(rmNodeChild);
+        return curNode;
+    }
+
+    rmNodeChild->rightNode = AVL_DeleteNodeWithTwoChilds(rmNodeChild->rightNode, removeNode);
+    return AVL_RebalanceLeft(rmNodeChild);
+}
+
+BSL_AvlTree *BSL_AVL_DeleteNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AVL_DATA_FREE_FUNC func)
+{
+    if (root == NULL) {
+        return root;
+    }
+
+    if (root->nodeId == nodeId) {
+        if (root->leftNode == NULL) {
+            if (root->rightNode == NULL) {
+                // 左右节点均为NULL
+                AVL_FreeData(root->data, func);
+                SAL_FREE(root);
+                return NULL;
+            } else {
+                // 只有右节点
+                BSL_AvlTree *curNode = root->rightNode;
+                AVL_FreeData(root->data, func);
+                SAL_FREE(root);
+                return (curNode);
+            }
+        } else if (root->rightNode == NULL) {
+            // 只有左节点
+            BSL_AvlTree *curNode = root->leftNode;
+            AVL_FreeData(root->data, func);
+            SAL_FREE(root);
+            return (curNode);
+        } else {
+            // 有左右节点
+            AVL_FreeData(root->data, func);
+            root->leftNode = AVL_DeleteNodeWithTwoChilds(root->leftNode, root);
+            return AVL_RebalanceRight(root);
+        }
+    }
+
+    if (root->nodeId > nodeId) {
+        root->leftNode = BSL_AVL_DeleteNode(root->leftNode, nodeId, func);
+        return AVL_RebalanceRight(root);
+    } else {
+        root->rightNode = BSL_AVL_DeleteNode(root->rightNode, nodeId, func);
+        return AVL_RebalanceLeft(root);
+    }
+}
+
+void BSL_AVL_DeleteTree(BSL_AvlTree *root, BSL_AVL_DATA_FREE_FUNC func)
+{
+    if (root == NULL) {
+        return;
+    }
+
+    BSL_AVL_DeleteTree(root->leftNode, func);
+    BSL_AVL_DeleteTree(root->rightNode, func);
+    AVL_FreeData(root->data, func);
+    SAL_FREE(root);
+}
diff --git a/code/sdk/open_source/HiTLS/bsl/err/src/avl.h b/code/sdk/open_source/HiTLS/bsl/err/src/avl.h
new file mode 100644 (file)
index 0000000..2ad1ecc
--- /dev/null
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file avl.h
+ * Description: 平衡树功能相关接口
+ * Author: guzhou
+ * Create: 2022-02-18
+ */
+
+#ifndef AVL_H
+#define AVL_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *BSL_ElementData;
+
+typedef void (*BSL_AVL_DATA_FREE_FUNC)(BSL_ElementData data);
+
+/* AVL tree node structure */
+typedef struct AvlTree {
+    uint32_t height;
+    uint64_t nodeId;
+    struct AvlTree *rightNode;
+    struct AvlTree *leftNode;
+    BSL_ElementData data;
+} BSL_AvlTree;
+
+/**
+ * @ingroup BSL
+ * @brief 创建一个树节点
+ *
+ * @par 描述:
+ * 创建一个树节点,并设置节点数据
+ *
+ * @attention 无
+ * @param data [IN] 树节点的数据指针
+ * @retval NULL 内存分配失败
+ */
+BSL_AvlTree *BSL_AVL_MakeLeafNode(BSL_ElementData data);
+
+/**
+ * @ingroup BSL
+ * @brief 查找节点
+ *
+ * @par 描述:
+ * 通过nodeId查找avl树的节点
+ *
+ * @attention 无
+ * @param root 树的根节点指针
+ * @param nodeId [IN] 作为key,树的节点id
+ * @retval NULL 没有查到相应的节点
+ * @retval 非NULL 查到的相应节点的指针
+ */
+BSL_AvlTree *BSL_AVL_SearchNode(BSL_AvlTree *root, uint64_t nodeId);
+
+/**
+ * @ingroup BSL
+ * @brief 在树中创建一个节点
+ *
+ * @par 描述:
+ * 在树中创建一个节点
+ *
+ * @attention 如果nodeId已经存在,则无法插入
+ * @param root [IN] 树的根节点指针
+ * @param nodeId [IN] 作为被创建节点的key
+ * @param node [IN] 树节点
+ * @retval 非NULL 树或子树的根节点
+ */
+BSL_AvlTree *BSL_AVL_InsertNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AvlTree *node);
+
+/**
+ * @ingroup BSL
+ * @brief 删除特定的树节点
+ *
+ * @par 描述:
+ * 删除nodeId相应的树节点
+ *
+ * @attention 无
+ * @param root [IN] 树的根节点指针
+ * @param nodeId [IN] 被删节点的key
+ * @param func [IN] 被删节点数据释放的函数指针
+ * @retval NULL 树中的节点都已删除
+ * @retval 非NULL 树或子树的根结点指针
+ */
+BSL_AvlTree *BSL_AVL_DeleteNode(BSL_AvlTree *root, uint64_t nodeId, BSL_AVL_DATA_FREE_FUNC func);
+
+/**
+ * @ingroup BSL
+ * @brief 删除树的所有节点
+ *
+ * @par 描述:
+ * 删除树的所有节点
+ *
+ * @attention 无
+ * @param root [IN] 树的根节点指针
+ * @param func [IN] 被删节点数据释放的函数指针
+ */
+void BSL_AVL_DeleteTree(BSL_AvlTree *root, BSL_AVL_DATA_FREE_FUNC func);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/bsl/err/src/err.c b/code/sdk/open_source/HiTLS/bsl/err/src/err.c
new file mode 100644 (file)
index 0000000..13e76cd
--- /dev/null
@@ -0,0 +1,321 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * Description: 错误码栈的实现
+ * Author: guzhou
+ * Create: 2022-02-11
+ */
+
+#include <stdbool.h>
+#include <inttypes.h>
+#include "securec.h"
+#include "bsl_log_internal.h"
+#include "sal_mem.h"
+#include "sal_threadlock.h"
+#include "avl.h"
+#include "bsl_errno.h"
+#include "bsl_binlog_id.h"
+#include "bsl_err_internal.h"
+#include "bsl_err.h"
+
+/* 错误信息栈大小 */
+#define SAL_MAX_ERROR_STACK 20
+
+/* 错误信息栈 */
+typedef struct {
+    /* 栈的当前指向位置,为-1时表示空栈 */
+    uint16_t bottom; // 栈底
+    uint16_t top; // 栈顶
+    uint32_t flag; // 用于保护错误栈不被清理,目前用于异步场景中
+
+    /* 存储特定线程的错误码信息 */
+    int32_t errorStack[SAL_MAX_ERROR_STACK];
+
+    /* 错误码的标记,用于部分清除、防侧信道 */
+    uint32_t errorFlags[SAL_MAX_ERROR_STACK];
+
+    /* 存储出错的文件名 */
+    const char *filename[SAL_MAX_ERROR_STACK];
+
+    /* 存储出错文件的行号 */
+    uint32_t line[SAL_MAX_ERROR_STACK];
+} ErrorCodeStack;
+
+/* 错误栈的avl树根节点 */
+static BSL_AvlTree *g_avlRoot = NULL;
+
+/* 当前avl节点数量 */
+static uint32_t g_avlNodeCount = 0;
+
+/* avl树所允许的最大节点数 */
+static uint32_t g_maxAvlNodes = 0x0000FFFF;
+
+/* 线程锁的句柄 */
+static BSL_SAL_ThreadLockHandle g_errLock;
+
+static void StackReset(ErrorCodeStack *stack)
+{
+    if (stack != NULL) {
+        (void)memset_s(stack, sizeof(*stack), 0, sizeof(*stack));
+    }
+}
+
+static void StackResetIndex(ErrorCodeStack *stack, uint32_t i)
+{
+    bool invalid = stack == NULL || i >= SAL_MAX_ERROR_STACK;
+    if (!invalid) {
+        stack->errorStack[i] = 0;
+        stack->line[i] = 0;
+        stack->filename[i] = NULL;
+        stack->errorFlags[i] = 0;
+    }
+}
+
+static void StackDataFree(BSL_ElementData data)
+{
+    SAL_FREE(data);
+}
+
+static ErrorCodeStack *GetStack(void)
+{
+    const uint64_t threadId = SAL_ThreadGetId();
+    BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
+    if (curNode != NULL) {
+        return curNode->data; // 已有错误栈直接返回
+    }
+    // 需要新建错误栈
+    if (g_avlNodeCount >= g_maxAvlNodes) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05005, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "New Avl Node failed.", 0, 0, 0, 0);
+        return NULL;
+    }
+    ErrorCodeStack *stack = (ErrorCodeStack *)SAL_CALLOC(1, sizeof(ErrorCodeStack));
+    if (stack == NULL) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05004, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "CALLOC error code stack failed", 0, 0, 0, 0);
+        return NULL;
+    }
+    BSL_AvlTree *node = BSL_AVL_MakeLeafNode(stack);
+    if (node == NULL) {
+        StackDataFree(stack);
+        LOG_BINLOG_FIXLEN(BINLOG_ID05006, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "avl insert node failed, threadId %"PRIu64, threadId, 0, 0, 0);
+        return NULL;
+    }
+    g_avlNodeCount++;
+    g_avlRoot = BSL_AVL_InsertNode(g_avlRoot, threadId, node); /* 上层已经保证threadId节点不存在 */
+    return stack;
+}
+
+void BSL_ERR_PushError(int32_t err, const char *file, uint32_t lineNo)
+{
+    if (err == BSL_SUCCESS) {
+        return; // 不允许push success
+    }
+
+    const uint64_t threadId = SAL_ThreadGetId();
+
+    int32_t ret = SAL_ThreadWriteLock(g_errLock);
+    if (ret != BSL_SUCCESS) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05007, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "acquire lock failed when pushing error, threadId %"PRIu64", error code %d", threadId, ret, 0, 0);
+        return;
+    }
+
+    ErrorCodeStack *stack = GetStack();
+    if (stack != NULL) {
+        if (stack->top == stack->bottom && stack->errorStack[stack->top] != 0) {
+            stack->bottom = (stack->bottom + 1) % SAL_MAX_ERROR_STACK;
+        }
+        stack->errorFlags[stack->top] = 0;
+        stack->errorStack[stack->top] = err;
+        stack->filename[stack->top] = file;
+        stack->line[stack->top] = lineNo;
+        stack->top = (stack->top + 1) % SAL_MAX_ERROR_STACK;
+    }
+
+    SAL_ThreadUnlock(g_errLock);
+}
+
+void BSL_ERR_ClearError(void)
+{
+    uint64_t threadId = SAL_ThreadGetId();
+    int32_t ret = SAL_ThreadWriteLock(g_errLock);
+    if (ret != BSL_SUCCESS) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05008, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "acquire lock failed when clearing error, threadId %"PRIu64, threadId, 0, 0, 0);
+        return;
+    }
+
+    BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
+    if (curNode != NULL) {
+        ErrorCodeStack *errStack = curNode->data;
+        if (errStack->flag == 0) {
+            StackReset(errStack);
+        }
+    }
+
+    SAL_ThreadUnlock(g_errLock);
+}
+
+void BSL_ERR_RemoveErrorStack(bool isRemoveAll)
+{
+    int32_t ret = SAL_ThreadWriteLock(g_errLock);
+    if (ret != BSL_SUCCESS) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05009, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "acquire lock failed when removing error stack, threadId %"PRIu64, SAL_ThreadGetId(), 0, 0, 0);
+        return;
+    }
+
+    if (g_avlRoot != NULL) {
+        if (isRemoveAll) {
+            BSL_AVL_DeleteTree(g_avlRoot, StackDataFree);
+            g_avlNodeCount = 0;
+            g_avlRoot = NULL;
+        } else {
+            uint64_t threadId = SAL_ThreadGetId();
+            BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
+            if (curNode != NULL) {
+                g_avlNodeCount--;
+                g_avlRoot = BSL_AVL_DeleteNode(g_avlRoot, threadId, StackDataFree);
+            }
+        }
+    }
+
+    SAL_ThreadUnlock(g_errLock);
+}
+
+// 获取索引,last表示获取最后一个错误码或第一个错误码
+uint16_t GetIndex(ErrorCodeStack *errStack, bool last)
+{
+    uint16_t idx;
+
+    if (last) {
+        idx = errStack->top - 1;
+        if (idx >= SAL_MAX_ERROR_STACK) {
+            idx = SAL_MAX_ERROR_STACK - 1;
+        }
+    } else  {
+        idx = errStack->bottom;
+    }
+
+    return idx;
+}
+
+// clr为true表示外部操作是get,false表示外部操作是peek
+// get操作会在获取错误信息后清理,而peek操作则不会
+// last为true表示获取栈顶的最后一个错误码,false表示获取栈底的第一个错误码
+static int32_t GetErrorInfo(const char **file, uint32_t *lineNo, bool clr, bool last)
+{
+    uint16_t idx;
+
+    int32_t ret = SAL_ThreadReadLock(g_errLock);
+    if (ret != BSL_SUCCESS) {
+        return BSL_ERR_ERR_ACQUIRE_READ_LOCK_FAIL;
+    }
+
+    if (g_avlRoot == NULL) {
+        /* 如果avlRoot为空,说明没有任何线程push error,所以error理应为success */
+        SAL_ThreadUnlock(g_errLock);
+        return BSL_SUCCESS;
+    }
+
+    const uint64_t threadId = SAL_ThreadGetId();
+    BSL_AvlTree *curNode = BSL_AVL_SearchNode(g_avlRoot, threadId);
+    if (curNode == NULL) {
+        /* 如果curNode为空,说明当前线程没有push error,所以error理应为success */
+        SAL_ThreadUnlock(g_errLock);
+        return BSL_SUCCESS;
+    }
+
+    ErrorCodeStack *errStack = curNode->data; // 不会为NULL
+
+    idx = GetIndex(errStack, last);
+    if (errStack->errorStack[idx] == 0) { // 错误栈为空
+        SAL_ThreadUnlock(g_errLock);
+        return BSL_SUCCESS;
+    }
+
+    int32_t errorCode = errStack->errorStack[idx];   /* 获取指定的错误号 */
+    uint32_t fileLine = errStack->line[idx]; /* 获取指定的行号 */
+    const char *f = errStack->filename[idx]; // 获取指定的文件名
+    if (clr) { // get or peek?
+        StackResetIndex(errStack, idx);
+        if (last) {
+            errStack->top = idx;
+        } else {
+            errStack->bottom = (idx + 1) % SAL_MAX_ERROR_STACK;
+        }
+    }
+
+    SAL_ThreadUnlock(g_errLock);
+
+    if (file != NULL && lineNo != NULL) { // 这两一起,只获得其中一个没有意义
+        if (f == NULL) {
+            *file = "NA";
+            *lineNo = 0;
+        } else {
+            *file = f;
+            *lineNo = fileLine;
+        }
+    }
+
+    return errorCode;
+}
+
+static int32_t GetLastErrorInfo(const char **file, uint32_t *lineNo, bool clr)
+{
+    return GetErrorInfo(file, lineNo, clr, true);
+}
+
+static int32_t GetFirstErrorInfo(const char **file, uint32_t *lineNo, bool clr)
+{
+    return GetErrorInfo(file, lineNo, clr, false);
+}
+
+int32_t BSL_ERR_GetLastErrorFileLine(const char **file, uint32_t *lineNo)
+{
+    return GetLastErrorInfo(file, lineNo, true);
+}
+
+int32_t BSL_ERR_PeekLastErrorFileLine(const char **file, uint32_t *lineNo)
+{
+    return GetLastErrorInfo(file, lineNo, false);
+}
+
+int32_t BSL_ERR_GetLastError(void)
+{
+    return GetLastErrorInfo(NULL, NULL, true);
+}
+
+int32_t BSL_ERR_GetErrorFileLine(const char **file, uint32_t *lineNo)
+{
+    return GetFirstErrorInfo(file, lineNo, true);
+}
+
+int32_t BSL_ERR_PeekErrorFileLine(const char **file, uint32_t *lineNo)
+{
+    return GetFirstErrorInfo(file, lineNo, false);
+}
+
+int32_t BSL_ERR_GetError(void)
+{
+    return GetFirstErrorInfo(NULL, NULL, true);
+}
+
+int32_t BSL_ERR_Init(void)
+{
+    if (g_errLock != NULL) {
+        return BSL_SUCCESS;
+    }
+    int32_t ret = SAL_ThreadLockNew(&g_errLock);
+    return ret;
+}
+
+void BSL_ERR_DeInit(void)
+{
+    if (g_errLock == NULL) {
+        return;
+    }
+    SAL_ThreadLockFree(g_errLock);
+    g_errLock = NULL;
+}
diff --git a/code/sdk/open_source/HiTLS/bsl/include/bsl_binlog_id.h b/code/sdk/open_source/HiTLS/bsl/include/bsl_binlog_id.h
new file mode 100644 (file)
index 0000000..53e2783
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       BSL模块的打点日志点号id
+ */
+
+#ifndef BSL_BINLOG_ID_H
+#define BSL_BINLOG_ID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum BSL_BINLOG_ID {
+    BINLOG_ID05001 = 5001, BINLOG_ID05002, BINLOG_ID05003, BINLOG_ID05004, BINLOG_ID05005,
+    BINLOG_ID05006, BINLOG_ID05007, BINLOG_ID05008, BINLOG_ID05009, BINLOG_ID05010,
+    BINLOG_ID05011, BINLOG_ID05012, BINLOG_ID05013, BINLOG_ID05014, BINLOG_ID05015,
+    BINLOG_ID05016, BINLOG_ID05017, BINLOG_ID05018, BINLOG_ID05019, BINLOG_ID05020,
+    BINLOG_ID05021, BINLOG_ID05022, BINLOG_ID05023, BINLOG_ID05024, BINLOG_ID05025,
+    BINLOG_ID05026, BINLOG_ID05027, BINLOG_ID05028, BINLOG_ID05029, BINLOG_ID05030,
+    BINLOG_ID05031, BINLOG_ID05032, BINLOG_ID05033, BINLOG_ID05034, BINLOG_ID05035,
+    BINLOG_ID05036, BINLOG_ID05037, BINLOG_ID05038, BINLOG_ID05039, BINLOG_ID05040,
+    BINLOG_ID05041, BINLOG_ID05042, BINLOG_ID05043, BINLOG_ID05044, BINLOG_ID05045,
+    BINLOG_ID05046, BINLOG_ID05047, BINLOG_ID05048, BINLOG_ID05049, BINLOG_ID05050,
+    BINLOG_ID05051, BINLOG_ID05052, BINLOG_ID05053, BINLOG_ID05054, BINLOG_ID05055,
+    BINLOG_ID05056, BINLOG_ID05057, BINLOG_ID05058, BINLOG_ID05059, BINLOG_ID05060,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/bsl/include/bsl_bytes.h b/code/sdk/open_source/HiTLS/bsl/include/bsl_bytes.h
new file mode 100644 (file)
index 0000000..19d1fd0
--- /dev/null
@@ -0,0 +1,192 @@
+/**
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       字节流的编解码接口
+ */
+
+#ifndef BSL_BYTES_H
+#define BSL_BYTES_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   uint8_t 字节流转 uint16_t 类型数据
+ *
+ * @attention data 不能为空
+ *
+ * @param   data [IN] uint8_t 字节流
+ *
+ * @return  uint16_t,转换后的数据
+ */
+static inline uint16_t BSL_ByteToUint16(const uint8_t *data)
+{
+    /** 第0字节左移8位,第1字节不变,或操作后得到 uint16_t */
+    return ((uint16_t)data[0] << 8) | ((uint16_t)data[1]);
+}
+
+/**
+ * @brief   uint16_t 类型数据转 uint8_t 字节流
+ *
+ * @attention data 不能为空
+ *
+ * @param   num [IN] 待转换的数据
+ * @param   data [OUT] 转换后的数据
+ */
+static inline void BSL_Uint16ToByte(uint16_t num, uint8_t *data)
+{
+    /** 转换到字节流 */
+    data[0] = (uint8_t)(num >> 8);    // 数据右移8位,放到第0字节
+    data[1] = (uint8_t)(num & 0xffu); // 数据与上0xffu,放到第1字节
+    return;
+}
+
+/**
+ * @brief   uint8_t 字节流转 uint24_t 类型数据
+ *
+ * @attention data 不能为空
+ *
+ * @param   data [IN] uint8_t 字节流
+ *
+ * @return  uint24_t,转换后的数据
+ */
+static inline uint32_t BSL_ByteToUint24(const uint8_t *data)
+{
+    /** 第0字节左移16位,第1字节左移8位,第2字节不变,或操作后得到 uint24_t */
+    return ((uint32_t)data[0] << 16) | ((uint32_t)data[1] << 8) | ((uint32_t)data[2]);
+}
+
+/**
+ * @brief   uint24_t 类型数据转 uint8_t 字节流
+ *
+ * @attention data 不能为空
+ *
+ * @param   num [IN] 待转换的数据
+ * @param   data [OUT] 转换后的数据
+ */
+static inline void BSL_Uint24ToByte(uint32_t num, uint8_t *data)
+{
+    /** 转换到字节流 */
+    data[0] = (uint8_t)(num >> 16);   // 数据右移16位,放到第0字节
+    data[1] = (uint8_t)(num >> 8);    // 数据右移8位,放到第1字节
+    data[2] = (uint8_t)(num & 0xffu); // 数据与上0xffu,放到第2字节
+    return;
+}
+
+/**
+ * @brief   uint8_t 字节流转 uint32_t 类型数据
+ *
+ * @attention data 不能为空
+ *
+ * @param   data [IN]  uint8_t 字节流
+ *
+ * @return  uint32_t,转换后的数据
+ */
+static inline uint32_t BSL_ByteToUint32(const uint8_t *data)
+{
+    /** 第0字节左移24位,第1字节左移16位,第2字节左移8位,第3字节不变,或操作后得到 uint32_t */
+    return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | ((uint32_t)data[3]);
+}
+
+/**
+ * @brief   uint8_t 字节流转 uint48_t 类型数据
+ *
+ * @attention data 不能为空
+ *
+ * @param   data [IN]  uint8_t 字节流
+ *
+ * @return  uint48_t,转换后的数据
+ */
+static inline uint64_t BSL_ByteToUint48(const uint8_t *data)
+{
+    /** 第0字节左移40位,第1字节左移32位,第2字节左移24位,第3字节左移16位,第4字节左移8位,第5字节不变,
+       或操作后得到 uint48_t */
+    return ((uint64_t)data[0] << 40) | ((uint64_t)data[1] << 32) | ((uint64_t)data[2] << 24) |
+        ((uint64_t)data[3] << 16) | ((uint64_t)data[4] << 8) | ((uint64_t)data[5]);
+}
+
+/**
+ * @brief   uint48_t 类型数据转 uint8_t 字节流
+ *
+ * @attention data 不能为空
+ *
+ * @param   num [IN] 待转换的数据
+ * @param   data [OUT] 转换后的数据
+ */
+static inline void BSL_Uint48ToByte(uint64_t num, uint8_t *data)
+{
+    /** 转换到字节流 */
+    data[0] = (uint8_t)(num >> 40);   // 数据右移40位,放到第0字节
+    data[1] = (uint8_t)(num >> 32);   // 数据右移32位,放到第1字节
+    data[2] = (uint8_t)(num >> 24);   // 数据右移24位,放到第2字节
+    data[3] = (uint8_t)(num >> 16);   // 数据右移16位,放到第3字节
+    data[4] = (uint8_t)(num >> 8);    // 数据右移8位,放到第4字节
+    data[5] = (uint8_t)(num & 0xffu); // 数据与上0xffu,放到第5字节
+    return;
+}
+
+/**
+ * @brief   uint8_t 字节流转 uint64_t 类型数据
+ *
+ * @attention data 不能为空
+ *
+ * @param   data [IN] uint8_t 字节流
+ *
+ * @return  uint32_t,转换后的数据
+ */
+static inline uint64_t BSL_ByteToUint64(const uint8_t *data)
+{
+    /** 第0字节左移56位,第1字节左移48位,第2字节左移40位,第3字节左移32位,第4字节左移24位,第5字节左移16位,
+        第6字节左移8位,第7字节不变,或操作后得到 uint64_t */
+    return ((uint64_t)data[0] << 56) | ((uint64_t)data[1] << 48) | ((uint64_t)data[2] << 40) |
+        ((uint64_t)data[3] << 32) | ((uint64_t)data[4] << 24) | ((uint64_t)data[5] << 16) |
+        ((uint64_t)data[6] << 8) | ((uint64_t)data[7]);
+}
+
+/**
+ * @brief   uint32_t 类型数据转 uint8_t 字节流
+ *
+ * @attention data 不能为空
+ *
+ * @param   num [IN] 待转换的数据
+ * @param   data [OUT] 转换后的数据
+ */
+static inline void BSL_Uint32ToByte(uint32_t num, uint8_t *data)
+{
+    /** 转换到字节流 */
+    data[0] = (uint8_t)(num >> 24);   // 数据右移24位,放到第0字节
+    data[1] = (uint8_t)(num >> 16);   // 数据右移16位,放到第1字节
+    data[2] = (uint8_t)(num >> 8);    // 数据右移8位,放到第2字节
+    data[3] = (uint8_t)(num & 0xffu); // 数据与上0xffu,放到第3字节
+    return;
+}
+
+/**
+ * @brief   uint64_t 类型数据转 uint8_t 字节流
+ *
+ * @attention data 不能为空
+ *
+ * @param   num [IN] 待转换的数据
+ * @param   data [OUT] 转换后的数据
+ */
+static inline void BSL_Uint64ToByte(uint64_t num, uint8_t *data)
+{
+    /** 转换到字节流 */
+    data[0] = (uint8_t)(num >> 56);   // 数据右移56位,放到第0字节
+    data[1] = (uint8_t)(num >> 48);   // 数据右移48位,放到第1字节
+    data[2] = (uint8_t)(num >> 40);   // 数据右移40位,放到第2字节
+    data[3] = (uint8_t)(num >> 32);   // 数据右移32位,放到第3字节
+    data[4] = (uint8_t)(num >> 24);   // 数据右移24位,放到第4字节
+    data[5] = (uint8_t)(num >> 16);   // 数据右移16位,放到第5字节
+    data[6] = (uint8_t)(num >> 8);    // 数据右移8位,放到第6字节
+    data[7] = (uint8_t)(num & 0xffu); // 数据与上0xffu,放到第7字节
+    return;
+}
+
+#ifdef __cplusplus
+}
+#endif /* end __cplusplus */
+
+#endif // BSL_BYTES_H
diff --git a/code/sdk/open_source/HiTLS/bsl/include/bsl_list.h b/code/sdk/open_source/HiTLS/bsl/include/bsl_list.h
new file mode 100644 (file)
index 0000000..6487f26
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       链表操作
+ */
+
+#ifndef BSL_LIST_H
+#define BSL_LIST_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 该结构被用来保存双向链表中节点的前向指针和后向指针。
+ * 这个链表不包含实质的数据区,一般用于组织(串接)数据节点
+ */
+typedef struct ListHeadNode {
+    struct ListHeadNode *next, *prev;
+} ListHead;
+
+/**
+ * @brief   初始化链表(链表重用时的初始化)
+ *
+ * @param   head [IN] 链表头结点的地址(The address of the head of a list )
+ */
+#define LIST_INIT(head) (head)->next = (head)->prev = (head)
+
+/**
+ * @brief   将节点item插入到节点where之后
+            变化前: where->A->B  变化后: where->item->A->B
+ *
+ * @param   where [IN] item插入后的前一个节点地址。(The address where the item will be inserted after)
+ * @param   item  [IN] 待插入节点地址(The address of the item)
+ */
+#define LIST_ADD_AFTER(where, item) do {  \
+    (item)->next       = (where)->next; \
+    (item)->prev       = (where);       \
+    (where)->next      = (item);        \
+    (item)->next->prev = (item);        \
+} while (0)
+
+/**
+ * @brief   将节点item插入到节点where之前
+ *          变化前: A->where->B  变化后: A->item->where->B
+ *
+ * @param   where [IN] item插入后的后一个节点地址。(The address where the item will be inserted before)
+ * @param   item  [IN] 待插入节点地址(The address of the item)
+ */
+#define LIST_ADD_BEFORE(where, item) LIST_ADD_AFTER((where)->prev, (item))
+
+/**
+ * @brief   删除节点item
+ *
+ * @param   item [IN] 待删除的节点(The address of the item to be removed)
+ */
+#define LIST_REMOVE(item) do { \
+    (item)->prev->next = (item)->next; \
+    (item)->next->prev = (item)->prev; \
+} while (0)
+
+/**
+ * @brief   检查链表是否为空(Judge whether a list is empty)
+ *
+ * @param   head [IN] 需要检查的链表(The address of the list to be judged)
+ */
+#define LIST_IS_EMPTY(head) ((head)->next == (head))
+
+/**
+ * @brief   安全遍历一个链表(Travel through a list safety)
+ *
+ * @param   head [IN] 需要遍历的链表(The head of a list)
+ * @param   temp [IN] 指向当前节点以便安全删除当前节点(pointer used to save current item so you can free item safety)
+ * @param   item [IN] 遍历链表所用的缓存节点(A temporary list item for travelling the list)
+ */
+#define LIST_FOR_EACH_ITEM_SAFE(item, temp, head) \
+    for ((item) = (head)->next, (temp) = (item)->next; (item) != (head); (item) = (temp), (temp) = (item)->next)
+
+/**
+ * @brief   通过链表某个节点(小结点)找到该节点所在结构(大节点)的起始地址
+ *
+ * @param   item   [IN] 特定节点变量(The address of a list item)
+ * @param   type   [IN] 包含链表节点的大节点类型(The type of a struct which includes the list item)
+ * @param   member [IN] 结构体内的list节点成员名称(The member variable of the struct whose type is list item)
+ *
+ * 说明:
+ * 每个结构变量形成一个一个的大节点(包含数据和list小结点), 大节点是通过list 这个链表(小节点)串起来的。
+ *  ---------      ---------      ---------    --               ----
+ * |  pre    |<---|  pre    |<---|  pre    |     |==>小结点         |
+ * |  next   |--->|  next   |--->|  next   |     |                  |
+ *  ---------      ---------      ---------    --                   | ===> 大节点
+ * |  data1  |    |  data1  |    |  data1  |                        |
+ * |  data2  |    |  data2  |    |  data2  |                        |
+ *  ---------      ---------      ---------                      ----
+ * 不直接用list作为大节点的原因是 list(ListHead 类型)只有头尾指针,不包含数据区。
+ * 这样 list链表可以适用挂接任意个数据的场合,具有通用性。
+ */
+#define LIST_ENTRY(item, type, member) \
+    ((type *)((uintptr_t)(char *)(item) - (uintptr_t)(&((type *)0)->member)))
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BSL_LIST_H
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/bsl/log/include/bsl_log_internal.h b/code/sdk/open_source/HiTLS/bsl/log/include/bsl_log_internal.h
new file mode 100644 (file)
index 0000000..9898450
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file bsl_log_internal.h
+ * Description: 日志模块
+ * Author: guzhou
+ * Create: 2022-02-11
+ */
+
+#ifndef BSL_LOG_INTERNAL_H
+#define BSL_LOG_INTERNAL_H
+
+#include <stdint.h>
+#include "bsl_log.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void LOG_BinLogFixLen(uint32_t logId, uint32_t logLevel, uint32_t logType,
+    void *format, void *para1, void *para2, void *para3, void *para4);
+
+void LOG_BinLogVarLen(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para);
+
+/**
+ * @ingroup BSL
+ * @brief 打点日志,format中只能含有不超过4个参数,参数中不能有%s
+ *
+ * @attention format中只能含有不超过4个参数,参数中不能有%s。不够4个参数要被0或NULL,多于4个参数则要多次调用本函数。
+ *            要打%s日志请使用LOG_BINLOG_FIXLEN。
+ * @param logId [IN] 点号id,每个点号id只能用一次
+ * @param level [IN] 日志级别
+ * @param logType [IN] 日志类别,目前仅有BSL_LOG_BINLOG_TYPE_RUN,为后续预留扩展
+ * @param format [IN] 仅含有1个%s的格式化字符串
+ * @param para [IN] 字符串指针
+ */
+#define LOG_BINLOG_FIXLEN(logId, logLevel, logType, format, para1, para2, para3, para4) \
+    LOG_BinLogFixLen(logId, logLevel, logType, \
+        (void *)(uintptr_t)(const void *)(format), (void *)(uintptr_t)(para1), (void *)(uintptr_t)(para2), \
+        (void *)(uintptr_t)(para3), (void *)(uintptr_t)(para4))
+
+/**
+ * @ingroup BSL
+ * @brief 打点日志,format中含有且只能含有1个%s
+ *
+ * @attention format中含有且只能含有1个%s,多个字符串打点则要多次调用本函数。
+ *            要打非%s的参数请使用LOG_BINLOG_FIXLEN。
+ * @param logId [IN] 点号id,每个点号id只能用一次
+ * @param level [IN] 日志级别
+ * @param logType [IN] 日志类别,目前仅有BSL_LOG_BINLOG_TYPE_RUN,为后续预留扩展
+ * @param format [IN] 仅含有1个%s的格式化字符串
+ * @param para [IN] 字符串指针
+ */
+#define LOG_BINLOG_VARLEN(logId, logLevel, logType, format, para) \
+    LOG_BinLogVarLen(logId, logLevel, logType, \
+        (void *)(uintptr_t)(const void *)(format), (void *)(uintptr_t)(const void *)(para))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BSL_LOG_INTERNAL_H
diff --git a/code/sdk/open_source/HiTLS/bsl/log/src/log.c b/code/sdk/open_source/HiTLS/bsl/log/src/log.c
new file mode 100644 (file)
index 0000000..25236d3
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * Description: 日志模块的实现,调用由产品注册的日志输出函数
+ * Author: guzhou
+ * Create: 2022-02-11
+ */
+
+#include <stdbool.h>
+#include "securec.h"
+#include "bsl_errno.h"
+#include "bsl_log_internal.h"
+
+/* HiTLS版本字符串 */
+static char g_hitlsVersion[HITLS_VERSION_LEN] = HITLS_VERSION;
+
+int32_t BSL_LOG_GetVersion(char *version, uint32_t *versionLen)
+{
+    if (version == NULL || versionLen == NULL) {
+        return BSL_LOG_ERR_BAD_PARAM;
+    }
+
+    if (*versionLen < HITLS_VERSION_LEN) {
+        return BSL_LOG_ERR_BAD_PARAM;
+    }
+
+    uint32_t len = (uint32_t)strlen(g_hitlsVersion);
+    if (memcpy_s(version, *versionLen, g_hitlsVersion, len) != EOK) {
+        return BSL_LOG_ERR_MEMCPY_FAIL;
+    }
+
+    *versionLen = len;
+    return BSL_SUCCESS;
+}
+
+static BSL_LOG_BinLogFixLenFunc g_fixLenFunc = NULL;
+static BSL_LOG_BinLogVarLenFunc g_varLenFunc = NULL;
+static uint32_t g_binlogLevel = BSL_LOG_LEVEL_ERR; // 默认开启error级
+static uint32_t g_binlogType = BSL_LOG_BINLOG_TYPE_RUN; // 默认开启run类型,可扩展增加其它类型
+
+int32_t BSL_LOG_RegBinLogFunc(const BSL_LOG_BinLogFuncs *funcs)
+{
+    bool invalid = funcs == NULL || funcs->fixLenFunc == NULL || funcs->varLenFunc == NULL;
+    if (invalid) {
+        return BSL_NULL_INPUT;
+    }
+    g_fixLenFunc = funcs->fixLenFunc;
+    g_varLenFunc = funcs->varLenFunc;
+    return BSL_SUCCESS;
+}
+
+int32_t BSL_LOG_SetBinLogLevel(uint32_t level)
+{
+    if (level > BSL_LOG_LEVEL_DEBUG) {
+        return BSL_LOG_ERR_BAD_PARAM;
+    }
+    g_binlogLevel = level;
+    return BSL_SUCCESS;
+}
+
+uint32_t BSL_LOG_GetBinLogLevel(void)
+{
+    return g_binlogLevel;
+}
+
+void LOG_BinLogFixLen(uint32_t logId, uint32_t logLevel, uint32_t logType,
+    void *format, void *para1, void *para2, void *para3, void *para4)
+{
+    bool invalid = (logLevel > g_binlogLevel) || ((logType & g_binlogType) == 0) || (g_fixLenFunc == NULL);
+    if (!invalid) {
+        g_fixLenFunc(logId, logLevel, logType, format, para1, para2, para3, para4);
+    }
+}
+
+void LOG_BinLogVarLen(uint32_t logId, uint32_t logLevel, uint32_t logType, void *format, void *para)
+{
+    bool invalid = (logLevel > g_binlogLevel) || ((logType & g_binlogType) == 0) || (g_varLenFunc == NULL);
+    if (!invalid) {
+        g_varLenFunc(logId, logLevel, logType, format, para);
+    }
+}
diff --git a/code/sdk/open_source/HiTLS/bsl/sal/include/sal_mem.h b/code/sdk/open_source/HiTLS/bsl/sal/include/sal_mem.h
new file mode 100644 (file)
index 0000000..57bfbfd
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file sal_mem.h
+ * Description: 内存模块
+ * Author: guzhou
+ * Create: 2022-02-11
+ */
+
+/** @defgroup SAL SAL子模块接口 */
+
+#ifndef SAL_MEM_H
+#define SAL_MEM_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup SAL
+ * @brief 分配内存空间
+ *
+ * @par 描述:
+ * 分配内存空间
+ *
+ * @attention 无
+ * @param size [IN] 分配内存的大小
+ * @return 申请成功返回指向内存的指针,NULL为申请失败
+ */
+void *SAL_Malloc(uint32_t size);
+
+/**
+ * @ingroup SAL
+ * @brief 分配内存空间并清零
+ *
+ * @par 描述:
+ * 分配内存空间并清零,最大分配UINT32_MAX大小的内存空间
+ *
+ * @attention num*size不应出现溢出回绕
+ * @param num [IN] 分配内存的数量
+ * @param size [IN] 每块内存的大小
+ * @return 申请成功返回指向内存的指针,NULL为申请失败或溢出回绕
+ */
+void *SAL_Calloc(uint32_t num, uint32_t size);
+
+/**
+ * @ingroup SAL
+ * @brief   拷贝内存空间
+ * @param   src 源内存地址
+ * @param   size 内存空间总大小
+ * @return  申请成功返回指向内存的指针,NULL为申请失败
+ */
+void *SAL_Dump(const void *src, uint32_t size);
+
+/**
+ * @ingroup SAL
+ * @brief 释放指定的内存
+ *
+ * @par 描述:
+ * 释放指定的内存
+ *
+ * @attention 无
+ * @param value [IN] 待释放的内存空间指针
+ */
+void SAL_Free(void *value);
+
+/**
+ * @ingroup SAL
+ * @brief 敏感信息置零
+ *
+ * @param ptr [IN] 要置零的内存
+ * @param size [IN] 要置零的内存的长度
+ *
+ * @return 无
+ */
+void SAL_CleanseData(void *ptr, uint32_t size);
+
+#define SAL_MALLOC(size_) SAL_Malloc((size_))
+
+#define SAL_CALLOC(num_, size_) SAL_Calloc((num_), (size_))
+
+#define SAL_DUMP(src_, size_) SAL_Dump((src_), (size_))
+
+#define SAL_FREE(value_)                        \
+    do {                                        \
+        if ((value_) != NULL) {                 \
+            SAL_Free((void *)(value_));         \
+            (value_) = NULL;                    \
+        }                                       \
+    } while (false)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/bsl/sal/include/sal_threadlock.h b/code/sdk/open_source/HiTLS/bsl/sal/include/sal_threadlock.h
new file mode 100644 (file)
index 0000000..2357138
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file sal_threadlock.h
+ * Description: 线程锁模块
+ * Author: guzhou
+ * Create: 2022-02-11
+ */
+
+#ifndef SAL_THREADLOCK_H
+#define SAL_THREADLOCK_H
+
+#include <stdint.h>
+#include "bsl_sal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup SAL
+ * @brief 新建一个线程锁
+ *
+ * @par 描述:
+ * 新建一个线程锁,如果是单线程环境则总是返回成功
+ *
+ * @attention 无
+ * @param lock [IN/OUT] 锁句柄
+ * @retval #BSL_SUCCESS 新建成功,或者是单线程环境
+ * @retval #BSL_SAL_ERR_NO_MEMORY 内存空间不足,无法申请进程锁空间
+ * @retval #BSL_SAL_ERR_UNKNOWN 线程锁初始化失败
+ * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+ */
+int32_t SAL_ThreadLockNew(BSL_SAL_ThreadLockHandle *lock);
+
+/**
+ * @ingroup SAL
+ * @brief 锁住读操作
+ *
+ * @par 描述:
+ * 锁住读操作,如果是单线程环境则总是返回成功
+ *
+ * @attention 无
+ * @param lock [IN] 锁句柄
+ * @retval #BSL_SUCCESS 成功,或者是单线程环境
+ * @retval #BSL_SAL_ERR_UNKNOWN 操作失败
+ * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+ */
+int32_t SAL_ThreadReadLock(BSL_SAL_ThreadLockHandle lock);
+
+/**
+ * @ingroup SAL
+ * @brief 锁住写操作
+ *
+ * @par 描述:
+ * 锁住写操作,如果是单线程环境则总是返回成功
+ *
+ * @attention 无
+ * @param lock [IN] 锁句柄
+ * @retval #BSL_SUCCESS 成功,或者是单线程环境
+ * @retval #BSL_SAL_ERR_UNKNOWN 操作失败
+ * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+ */
+int32_t SAL_ThreadWriteLock(BSL_SAL_ThreadLockHandle lock);
+
+/**
+ * @ingroup SAL
+ * @brief 解锁
+ *
+ * @par 描述:
+ * 解锁,如果是单线程环境则总是返回成功
+ *
+ * @attention 无
+ * @param lock [IN] 锁句柄
+ * @retval #BSL_SUCCESS 成功,或者是单线程环境
+ * @retval #BSL_SAL_ERR_UNKNOWN 操作失败
+ * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+ */
+int32_t SAL_ThreadUnlock(BSL_SAL_ThreadLockHandle lock);
+
+/**
+ * @ingroup SAL
+ * @brief 释放线程锁
+ *
+ * @par 描述:
+ * 释放线程锁
+ *
+ * @attention 无
+ * @param lock [IN] 锁句柄
+ */
+void SAL_ThreadLockFree(BSL_SAL_ThreadLockHandle lock);
+
+/**
+ * @ingroup SAL
+ * @brief 获取线程id
+ *
+ * @par 描述:
+ * 获取线程id
+ *
+ * @attention 无
+ * @retval 线程id,单线程环境为0
+ */
+uint64_t SAL_ThreadGetId(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/bsl/sal/src/sal_mem.c b/code/sdk/open_source/HiTLS/bsl/sal/src/sal_mem.c
new file mode 100644 (file)
index 0000000..b1de98e
--- /dev/null
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * Description: 内存分配、释放的实现,由产品注册内存分配、释放的函数
+ * Author: guzhou
+ * Create: 2022-02-11
+ */
+
+#include <stdlib.h>
+#include "securec.h"
+#include "bsl_log_internal.h"
+#include "bsl_sal.h"
+#include "bsl_errno.h"
+#include "bsl_binlog_id.h"
+#include "sal_mem.h"
+
+static BSL_SAL_MemCallback g_memCallback = {0};
+
+void *SAL_Malloc(uint32_t size)
+{
+    if (g_memCallback.pfMalloc == NULL) {
+        return NULL;
+    }
+    return g_memCallback.pfMalloc(size);
+}
+
+void SAL_Free(void *value)
+{
+    if (g_memCallback.pfFree == NULL) {
+        return;
+    }
+    g_memCallback.pfFree(value);
+}
+
+void *SAL_Calloc(uint32_t num, uint32_t size)
+{
+    if (num == 0 || size == 0) {
+        return SAL_Malloc(0);
+    }
+    if (num > UINT32_MAX / size) { // 按《华为C语言编程规范V5.1》G.INT.02处理回绕
+        return NULL;
+    }
+    uint32_t blockSize = num * size;
+    uint8_t *ptr = SAL_Malloc(blockSize);
+    if (ptr == NULL) {
+        return NULL;
+    }
+    // 大于SECUREC_MEM_MAX_LEN的话要分段处理,因为memset_s仅能处理SECUREC_MEM_MAX_LEN这么大的
+    uint32_t offset = 0;
+    while (blockSize > SECUREC_MEM_MAX_LEN) {
+        if (memset_s(&ptr[offset], SECUREC_MEM_MAX_LEN, 0, SECUREC_MEM_MAX_LEN) != EOK) {
+            SAL_FREE(ptr);
+            return NULL;
+        }
+        offset += SECUREC_MEM_MAX_LEN;
+        blockSize -= SECUREC_MEM_MAX_LEN;
+    }
+    if (memset_s(&ptr[offset], blockSize, 0, blockSize) != EOK) {
+        SAL_FREE(ptr);
+        return NULL;
+    }
+    return ptr;
+}
+
+void *SAL_Dump(const void *src, uint32_t size)
+{
+    if (g_memCallback.pfMalloc == NULL) {
+        return NULL;
+    }
+
+    void *ptr = g_memCallback.pfMalloc(size);
+    if (ptr == NULL) {
+        return NULL;
+    }
+
+    if (memcpy_s(ptr, size, src, size) != EOK) {
+        SAL_FREE(ptr);
+        return NULL;
+    }
+
+    return ptr;
+}
+
+int32_t BSL_SAL_RegMemCallback(BSL_SAL_MemCallback *cb)
+{
+    if ((cb == NULL) || (cb->pfMalloc == NULL) || (cb->pfFree == NULL)) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05011, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "invalid params", NULL, NULL, NULL, NULL);
+        return BSL_SAL_ERR_BAD_PARAM;
+    }
+    g_memCallback.pfMalloc = cb->pfMalloc;
+    g_memCallback.pfFree = cb->pfFree;
+    return BSL_SUCCESS;
+}
+
+#if !defined(__clang__)
+#pragma GCC push_options
+#pragma GCC optimize("O3")
+#endif
+#define CLEAN_THRESHOLD_SIZE 16UL
+
+static void CleanSensitiveDataLess16Byte(void *buf, uint32_t bufLen)
+{
+    uint8_t *tmp = (uint8_t *)buf;
+    switch (bufLen) {
+        case 16: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-16内存写0
+        /* FALLTHRU */
+        case 15: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-15内存写0
+        /* FALLTHRU */
+        case 14: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-14内存写0
+        /* FALLTHRU */
+        case 13: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-13内存写0
+        /* FALLTHRU */
+        case 12: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-12内存写0
+        /* FALLTHRU */
+        case 11: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-11内存写0
+        /* FALLTHRU */
+        case 10: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-10内存写0
+        /* FALLTHRU */
+        case 9: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-9内存写0
+        /* FALLTHRU */
+        case 8: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-8内存写0
+        /* FALLTHRU */
+        case 7: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-7内存写0
+        /* FALLTHRU */
+        case 6: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-6内存写0
+        /* FALLTHRU */
+        case 5: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-5内存写0
+        /* FALLTHRU */
+        case 4: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-4内存写0
+        /* FALLTHRU */
+        case 3: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-3内存写0
+        /* FALLTHRU */
+        case 2: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-2内存写0
+        /* FALLTHRU */
+        case 1: *(tmp++) = (uint8_t)0; // fall-through, 对第bufLen-1内存写0
+        /* FALLTHRU */
+        default:                   /* Do nothing */
+            break;
+    }
+}
+
+static void CleanSensitiveData(void *buf, uint32_t bufLen)
+{
+    uint8_t *tmp = (uint8_t *)buf;
+    uint32_t boundOpt;
+
+    if (((uintptr_t)buf & 0x3) == 0) { // buf & 0x3,用于判断是否是4字节对齐
+        boundOpt = (bufLen >> 4) << 4; // 右移4bit再左移4bit,用于计算16的整数倍
+        for (uint32_t i = 0; i < boundOpt; i += 16) { // 每次清零16片内存
+            uint32_t *ctmp = (uint32_t *)(tmp + i);
+            ctmp[0] = 0;
+            ctmp[1] = 0; // 对i + 1内存进行清零
+            ctmp[2] = 0; // 对i + 2内存进行清零
+            ctmp[3] = 0; // 对i + 3内存进行清零
+        }
+    } else {
+        boundOpt = (bufLen >> 2) << 2; // 右移2bit再左移2bit,用于计算4的整数倍
+        for (uint32_t i = 0; i < boundOpt; i += 4) { // 每次清零4片内存
+            tmp[i] = 0;
+            tmp[i + 1] = 0; // 对i + 1内存进行清零
+            tmp[i + 2] = 0; // 对i + 2内存进行清零
+            tmp[i + 3] = 0; // 对i + 3内存进行清零
+        }
+    }
+    for (uint32_t i = boundOpt; i < bufLen; ++i) {
+        tmp[i] = 0;
+    }
+}
+
+void SAL_CleanseData(void *ptr, uint32_t size)
+{
+    if (ptr == NULL) {
+        return;
+    }
+    if (size > CLEAN_THRESHOLD_SIZE) {
+        CleanSensitiveData(ptr, size);
+    } else {
+        CleanSensitiveDataLess16Byte(ptr, size);
+    }
+}
+
+#if !defined(__clang__)
+#pragma GCC pop_options
+#endif
diff --git a/code/sdk/open_source/HiTLS/bsl/sal/src/sal_threadlock.c b/code/sdk/open_source/HiTLS/bsl/sal/src/sal_threadlock.c
new file mode 100644 (file)
index 0000000..097270d
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * Description: 线程锁接口的实现,由产品注册线程相关的函数
+ * Author: guzhou
+ * Create: 2022-02-11
+ */
+
+#include <stddef.h>
+#include "bsl_log_internal.h"
+#include "bsl_errno.h"
+#include "bsl_binlog_id.h"
+#include "sal_threadlock.h"
+
+static BSL_SAL_ThreadCallback g_threadCallback = {0};
+
+/* 线程功能可裁剪,若产品不注册线程相关函数,视为使用单线程,线程相关函数默认返回成功 */
+
+int32_t SAL_ThreadLockNew(BSL_SAL_ThreadLockHandle *lock)
+{
+    if (g_threadCallback.pfThreadLockNew == NULL) {
+        return BSL_SUCCESS;
+    }
+    if (lock == NULL) {
+        return BSL_SAL_ERR_BAD_PARAM;
+    }
+    return g_threadCallback.pfThreadLockNew(lock);
+}
+
+int32_t SAL_ThreadReadLock(BSL_SAL_ThreadLockHandle lock)
+{
+    if (g_threadCallback.pfThreadReadLock == NULL) {
+        return BSL_SUCCESS;
+    }
+    if (lock == NULL) {
+        return BSL_SAL_ERR_BAD_PARAM;
+    }
+    return g_threadCallback.pfThreadReadLock(lock);
+}
+
+int32_t SAL_ThreadWriteLock(BSL_SAL_ThreadLockHandle lock)
+{
+    if (g_threadCallback.pfThreadWriteLock == NULL) {
+        return BSL_SUCCESS;
+    }
+    if (lock == NULL) {
+        return BSL_SAL_ERR_BAD_PARAM;
+    }
+    return g_threadCallback.pfThreadWriteLock(lock);
+}
+
+int32_t SAL_ThreadUnlock(BSL_SAL_ThreadLockHandle lock)
+{
+    if (g_threadCallback.pfThreadUnlock == NULL) {
+        return BSL_SUCCESS;
+    }
+    if (lock == NULL) {
+        return BSL_SAL_ERR_BAD_PARAM;
+    }
+    return g_threadCallback.pfThreadUnlock(lock);
+}
+
+void SAL_ThreadLockFree(BSL_SAL_ThreadLockHandle lock)
+{
+    if (g_threadCallback.pfThreadLockFree == NULL) {
+        return;
+    }
+    if (lock == NULL) {
+        return;
+    }
+    g_threadCallback.pfThreadLockFree(lock);
+}
+
+uint64_t SAL_ThreadGetId(void)
+{
+    if (g_threadCallback.pfThreadGetId == NULL) {
+        return 0;
+    }
+    return g_threadCallback.pfThreadGetId();
+}
+
+int32_t BSL_SAL_RegThreadCallback(BSL_SAL_ThreadCallback *cb)
+{
+    if ((cb == NULL) || (cb->pfThreadLockNew == NULL) || (cb->pfThreadLockFree == NULL) ||
+        (cb->pfThreadReadLock == NULL) || (cb->pfThreadWriteLock == NULL) ||
+        (cb->pfThreadUnlock == NULL) || (cb->pfThreadGetId == NULL)) {
+        LOG_BINLOG_FIXLEN(BINLOG_ID05012, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
+            "invalid params", NULL, NULL, NULL, NULL);
+        return BSL_SAL_ERR_BAD_PARAM;
+    }
+    g_threadCallback.pfThreadLockNew = cb->pfThreadLockNew;
+    g_threadCallback.pfThreadLockFree = cb->pfThreadLockFree;
+    g_threadCallback.pfThreadReadLock = cb->pfThreadReadLock;
+    g_threadCallback.pfThreadWriteLock = cb->pfThreadWriteLock;
+    g_threadCallback.pfThreadUnlock = cb->pfThreadUnlock;
+    g_threadCallback.pfThreadGetId = cb->pfThreadGetId;
+    return BSL_SUCCESS;
+}
diff --git a/code/sdk/open_source/HiTLS/crypto/aes/include/crypt_aes.h b/code/sdk/open_source/HiTLS/crypto/aes/include/crypt_aes.h
new file mode 100644 (file)
index 0000000..d73963f
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * @defgroup    crypt_aes  crypt_aes.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       AES加解密接口
+ */
+#ifndef CRYPT_AES_H
+#define CRYPT_AES_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define CRYPT_AES_MAX_ROUNDS  14
+#define CRYPT_AES_MAX_KEYLEN  (4 * (CRYPT_AES_MAX_ROUNDS + 1))
+
+/**
+ * @ingroup CRYPT_AES_Key
+ *
+ * aes 密钥结构体
+ */
+typedef struct {
+    uint32_t key[CRYPT_AES_MAX_KEYLEN];
+    uint32_t rounds;
+} CRYPT_AES_Key;
+
+/**
+ * @ingroup aes
+ * @brief 设置AES加密秘钥。
+ *
+ * @param ctx [IN]  AES 句柄
+ * @param key [IN]  加密密钥
+ * @param len [IN]  秘钥长度,为128。
+*/
+int32_t CRYPT_AES_SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief 设置AES加密秘钥。
+ *
+ * @param ctx [IN]  AES 句柄
+ * @param key [IN]  加密密钥
+ * @param len [IN]  秘钥长度,为192。
+*/
+int32_t CRYPT_AES_SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief 设置AES加密秘钥。
+ *
+ * @param ctx [IN]  AES 句柄
+ * @param key [IN]  加密密钥
+ * @param len [IN]  秘钥长度,为256。
+*/
+int32_t CRYPT_AES_SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief 设置AES解密秘钥。
+ *
+ * @param ctx [IN]  AES 句柄
+ * @param key [IN] 解密密钥
+ * @param len [IN]  秘钥长度,为128
+*/
+int32_t CRYPT_AES_SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief 设置AES解密秘钥。
+ *
+ * @param ctx [IN]  AES 句柄
+ * @param key [IN] 解密密钥
+ * @param len [IN]  秘钥长度,为192
+*/
+int32_t CRYPT_AES_SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief 设置AES解密秘钥。
+ *
+ * @param ctx [IN]  AES 句柄
+ * @param key [IN] 解密密钥
+ * @param len [IN]  秘钥长度,可以为256。
+*/
+int32_t CRYPT_AES_SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief AES加密。
+ *
+ * @param ctx [IN]  AES句柄,存有密钥
+ * @param in  [IN]  输入明文数据,需为16字节。
+ * @param out [OUT] 输出密文数据,长度为16字节。
+ * @param len [IN]  块长度。
+*/
+int32_t CRYPT_AES_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief AES解密。
+ *
+ * @param ctx [IN]  AES句柄,存有密钥
+ * @param in  [IN]  输入密文数据,需为16字节。
+ * @param out [OUT] 输出明文数据,长度为16字节。
+ * @param len [IN]  块长度,长度为16。
+*/
+int32_t CRYPT_AES_Decrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+/**
+ * @ingroup aes
+ * @brief 清除aes密钥信息
+ *
+ * @param ctx [IN]  AES句柄,存有密钥
+ * @return void
+*/
+void CRYPT_AES_Clean(CRYPT_AES_Key *ctx);
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/aes/src/crypt_aes.c b/code/sdk/open_source/HiTLS/crypto/aes/src/crypt_aes.c
new file mode 100644 (file)
index 0000000..7001122
--- /dev/null
@@ -0,0 +1,918 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_aes.c
+ * Description: 提供AES算法实现
+ * Author: mayihui
+ * Create: 2022-5-5
+ * Modification History
+ * DATE        NAME             DESCRIPTION
+ * --------------------------------------------------------------------------
+ * 2022-5-5  mayihui        提供AES算法实现
+ */
+#include "crypt_aes.h"
+#include "securec.h"
+#include "bsl_err_internal.h"
+#include "crypt_utils.h"
+#include "crypt_errno.h"
+#include "sal_mem.h"
+
+#define SSEARCH(t0, t1, t2, t3)                                                    \
+    (((uint32_t)S[((t0) >> 24)] << 24) ^ ((uint32_t)S[((t1) >> 16) & 0xff] << 16) ^ \
+        ((uint32_t)S[((t2) >> 8) & 0xff] << 8) ^ ((uint32_t)S[(t3) & 0xff]))
+
+#define INVSSEARCH(t0, t1, t2, t3)                                                       \
+    (((uint32_t)INV_S[((t0) >> 24)] << 24) ^ ((uint32_t)INV_S[((t3) >> 16) & 0xff] << 16) ^ \
+        ((uint32_t)INV_S[((t2) >> 8) & 0xff] << 8) ^ ((uint32_t)INV_S[(t1) & 0xff]))
+
+/* S盒 来源于 FIPS 197 Figure 7. S-box */
+static const uint8_t S[256] = {
+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U,
+};
+/* 逆S盒 来源于 FIPS 197 Figure 14. Inverse S-box */
+static const uint8_t INV_S[256] = {
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+
+static const uint32_t RCON[] = {
+    0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000,
+    0x36000000,
+};
+
+static const uint32_t TE0[256] = {
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const uint32_t TE1[256] = {
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const uint32_t TE2[256] = {
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const uint32_t TE3[256] = {
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const uint32_t TD0[256] = {
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const uint32_t TD1[256] = {
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const uint32_t TD2[256] = {
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const uint32_t TD3[256] = {
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+
+void SetDecryptKey(CRYPT_AES_Key *ctx);
+
+static inline uint32_t AES_G(uint32_t w, uint32_t rcon)
+{
+    uint32_t ret = 0;
+    /* 查表并进行移位 */
+    ret ^= (uint32_t)S[(w & 0x000000FF) >>  0] << 8;  // 0, 8, S盒内行列转换关系
+    ret ^= (uint32_t)S[(w & 0x0000FF00) >>  8] << 16; // 8, 16, S盒内行列转换关系
+    ret ^= (uint32_t)S[(w & 0x00FF0000) >> 16] << 24; // 16, 24, S盒内行列转换关系
+    ret ^= (uint32_t)S[(w & 0xFF000000) >> 24] << 0; // 24, S盒内行列转换关系
+    ret ^= rcon;
+    return ret;
+}
+
+int32_t CRYPT_AES_SetEncryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len)
+{
+    if (ctx == NULL || key == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    // 16 bytes = 128 bits
+    if (len != 16) {
+        BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
+        return CRYPT_AES_ERR_KEYLEN;
+    }
+    uint32_t *ekey = ctx->key;
+    ekey[0] = GET_UINT32_BE(key, 0);  // ekey 0:  key 0 下标开始的4个字节
+    ekey[1] = GET_UINT32_BE(key, 4);  // ekey 1:  key 4 下标开始的4个字节
+    ekey[2] = GET_UINT32_BE(key, 8);  // ekey 2:  key 8 下标开始的4个字节
+    ekey[3] = GET_UINT32_BE(key, 12);  // ekey 3:  key 12 下标开始的4个字节
+
+    // 128bit 需要秘钥长度 11 * 4 = 44,拓展轮数为10 -> 10 * 4 + 4 = 44
+    uint32_t times;
+    ctx->rounds = 10;  // 10 rounds
+    for (times = 0; times < 9; times++) { // 9 times
+        ekey[4] = AES_G(ekey[3], RCON[times]) ^ ekey[0];  // ekey 4 = (ekey 3 xor rcon) ^ ekey 0
+        ekey[5] = ekey[4] ^ ekey[1];  // ekey 5 = ekey 4 ^ ekey 1
+        ekey[6] = ekey[5] ^ ekey[2];  // ekey 6 = ekey 5 ^ ekey 2
+        ekey[7] = ekey[6] ^ ekey[3];  // ekey 7 = ekey 6 ^ ekey 3
+        ekey += 4;  // add 4
+    }
+    // the last times
+    ekey[4] = AES_G(ekey[3], RCON[times]) ^ ekey[0];  // ekey 4 = (ekey 3 xor rcon) ^ ekey 0
+    ekey[5] = ekey[4] ^ ekey[1];  // ekey 5 = ekey 4 ^ ekey 1
+    ekey[6] = ekey[5] ^ ekey[2];  // ekey 6 = ekey 5 ^ ekey 2
+    ekey[7] = ekey[6] ^ ekey[3];  // ekey 7 = ekey 6 ^ ekey 3
+    return CRYPT_SUCCESS;
+}
+
+int32_t CRYPT_AES_SetEncryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len)
+{
+    if (ctx == NULL || key == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    // 24 bytes = 192 bits
+    if (len != 24) {
+        BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
+        return CRYPT_AES_ERR_KEYLEN;
+    }
+    uint32_t *ekey = ctx->key;
+    ekey[0] = GET_UINT32_BE(key, 0);  // ekey 0:  key 0 下标开始的4个字节
+    ekey[1] = GET_UINT32_BE(key, 4);  // ekey 1:  key 4 下标开始的4个字节
+    ekey[2] = GET_UINT32_BE(key, 8);  // ekey 2:  key 8 下标开始的4个字节
+    ekey[3] = GET_UINT32_BE(key, 12); // ekey 3:  key 12 下标开始的4个字节
+    ekey[4] = GET_UINT32_BE(key, 16); // ekey 4:  key 16 下标开始的4个字节
+    ekey[5] = GET_UINT32_BE(key, 20); // ekey 5:  key 20 下标开始的4个字节
+
+    uint32_t times;
+    ctx->rounds = 12;  // 12 rounds
+
+    for (times = 0; times < 7; times++) { // 7 times
+        ekey[6] = AES_G(ekey[5], RCON[times]) ^ ekey[0];  // ekey 6 = AES_G(ekey 5 xor rcon) ^ ekey 0
+        ekey[7] = ekey[6] ^ ekey[1];    // ekey 7 = ekey 6 ^ ekey 1
+        ekey[8] = ekey[7] ^ ekey[2];    // ekey 8 = ekey 7 ^ ekey 2
+        ekey[9] = ekey[8] ^ ekey[3];    // ekey 9 = ekey 8 ^ ekey 3
+        ekey[10] = ekey[9] ^ ekey[4];  // ekey 10 = ekey 9 ^ ekey 4
+        ekey[11] = ekey[10] ^ ekey[5]; // ekey 11 = ekey 10 ^ ekey 5
+        ekey += 6;  // add 6
+    }
+    // the last times
+    ekey[6] = AES_G(ekey[5], RCON[times]) ^ ekey[0];  // ekey 6 = AES_G(ekey 5 xor rcon) ^ ekey 0
+    ekey[7] = ekey[6] ^ ekey[1];    // ekey 7 = ekey 6 ^ ekey 1
+    ekey[8] = ekey[7] ^ ekey[2];    // ekey 8 = ekey 7 ^ ekey 2
+    ekey[9] = ekey[8] ^ ekey[3];    // ekey 9 = ekey 8 ^ ekey 3
+    return CRYPT_SUCCESS;
+}
+
+int32_t CRYPT_AES_SetEncryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len)
+{
+    if (ctx == NULL || key == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    uint32_t *ekey = ctx->key;
+    // 32 bytes = 256 bits
+    if (len != 32) {
+        BSL_ERR_PUSH_ERROR(CRYPT_AES_ERR_KEYLEN);
+        return CRYPT_AES_ERR_KEYLEN;
+    }
+    ekey[0] = GET_UINT32_BE(key, 0);  // ekey 0:  key 0 下标开始的4个字节
+    ekey[1] = GET_UINT32_BE(key, 4);  // ekey 1:  key 4 下标开始的4个字节
+    ekey[2] = GET_UINT32_BE(key, 8);  // ekey 2:  key 8 下标开始的4个字节
+    ekey[3] = GET_UINT32_BE(key, 12); // ekey 3:  key 12 下标开始的4个字节
+    ekey[4] = GET_UINT32_BE(key, 16); // ekey 4:  key 16 下标开始的4个字节
+    ekey[5] = GET_UINT32_BE(key, 20); // ekey 5:  key 20 下标开始的4个字节
+    ekey[6] = GET_UINT32_BE(key, 24); // ekey 6:  key 24 下标开始的4个字节
+    ekey[7] = GET_UINT32_BE(key, 28); // ekey 7:  key 28 下标开始的4个字节
+
+    /*  需要秘钥长度 15 * 4 = 60,拓展轮数为7 -> 7 * 8 + 8 - 4 = 60 */
+    uint32_t times;
+    ctx->rounds = 14;  // 14 轮
+    uint32_t tmp;
+    for (times = 0; times < 6; times++) { // 6 times
+        ekey[8] = AES_G(ekey[7], RCON[times]) ^ ekey[0];  // ekey 8 = AES_G(ekey 7 xor rcon) ^ ekey 0
+        ekey[9] = ekey[8] ^ ekey[1];   // ekey 9 = ekey 8 ^ ekey 1
+        ekey[10] = ekey[9] ^ ekey[2];  // ekey 10 = ekey 9 ^ ekey 2
+        ekey[11] = ekey[10] ^ ekey[3]; // ekey 11 = ekey 10 ^ ekey 3
+        /* 弥补G操作的移位 */
+        tmp = (ekey[11] >> 8) | (ekey[11] << 24);  // tmp is ekey 11 >> 8 | ekey 11 << 24
+        ekey[12] = AES_G(tmp, 0) ^ ekey[4];  // ekey 12 = AES_G(tme, 0) ^ ekey 4
+        ekey[13] = ekey[12] ^ ekey[5];  // ekey 13 = ekey 12 ^ ekey 5
+        ekey[14] = ekey[13] ^ ekey[6];  // ekey 14 = ekey 13 ^ ekey 6
+        ekey[15] = ekey[14] ^ ekey[7];  // ekey 15 = ekey 14 ^ ekey 7
+        ekey += 8;  // add 8
+    }
+    // the last times
+    ekey[8] = AES_G(ekey[7], RCON[times]) ^ ekey[0];  // ekey 8 = AES_G(ekey 7 xor rcon) ^ ekey 0
+    ekey[9] = ekey[8] ^ ekey[1];   // ekey 9 = ekey 8 ^ ekey 1
+    ekey[10] = ekey[9] ^ ekey[2];  // ekey 10 = ekey 9 ^ ekey 2
+    ekey[11] = ekey[10] ^ ekey[3]; // ekey 11 = ekey 10 ^ ekey 3
+    return CRYPT_SUCCESS;
+}
+
+void SetDecryptKey(CRYPT_AES_Key *ctx)
+{
+    uint32_t i, j;
+    uint32_t *dkey = ctx->key;
+    for (i = 1; i < ctx->rounds; i++) {
+        dkey += 4;  // 4, 每次运算16个字节
+        for (j = 0; j < 4; j++) {   // for 0 to 4 , 运算 16 / sizeof(uint32_t) 个循环
+            dkey[j] = TD0[S[(dkey[j] >> 24) & 0xff]] ^  // dkey j >> 24
+                      TD1[S[(dkey[j] >> 16) & 0xff]] ^  // dkey j >> 16
+                      TD2[S[(dkey[j] >>  8) & 0xff]] ^  // dkey j >> 8
+                      TD3[S[(dkey[j] >>  0) & 0xff]];  // dkey j >> 0
+        }
+    }
+}
+
+int32_t CRYPT_AES_SetDecryptKey128(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len)
+{
+    int32_t ret;
+    ret = CRYPT_AES_SetEncryptKey128(ctx, key, len);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+    SetDecryptKey(ctx);
+    return CRYPT_SUCCESS;
+}
+
+int32_t CRYPT_AES_SetDecryptKey192(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len)
+{
+    int32_t ret;
+    ret = CRYPT_AES_SetEncryptKey192(ctx, key, len);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+    SetDecryptKey(ctx);
+    return CRYPT_SUCCESS;
+}
+
+int32_t CRYPT_AES_SetDecryptKey256(CRYPT_AES_Key *ctx, const uint8_t *key, uint32_t len)
+{
+    int32_t ret;
+    ret = CRYPT_AES_SetEncryptKey256(ctx, key, len);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+    SetDecryptKey(ctx);
+    return CRYPT_SUCCESS;
+}
+
+#define AES_ROUND_INIT(in, r, enc)    \
+do { \
+    r##0 = GET_UINT32_BE(in, 0) ^ enc##key[0]; \
+    r##1 = GET_UINT32_BE(in, 4) ^ enc##key[1]; \
+    r##2 = GET_UINT32_BE(in, 8) ^ enc##key[2]; \
+    r##3 = GET_UINT32_BE(in, 12) ^ enc##key[3]; \
+} while (0)
+
+#define AES_ENC_ROUND(in, r, i, ekey)    \
+do { \
+    r##0 = TE0[(in##0 >> 24)] ^ TE1[(in##1 >> 16) & 0xff] ^ TE2[(in##2 >> 8) & 0xff] ^ TE3[(in##3) & 0xff] \
+                ^ (ekey)[((i) << 2) + 0]; \
+    r##1 = TE0[(in##1 >> 24)] ^ TE1[(in##2 >> 16) & 0xff] ^ TE2[(in##3 >> 8) & 0xff] ^ TE3[(in##0) & 0xff] \
+                ^ (ekey)[((i) << 2) + 1]; \
+    r##2 = TE0[(in##2 >> 24)] ^ TE1[(in##3 >> 16) & 0xff] ^ TE2[(in##0 >> 8) & 0xff] ^ TE3[(in##1) & 0xff] \
+                ^ (ekey)[((i) << 2) + 2]; \
+    r##3 = TE0[(in##3 >> 24)] ^ TE1[(in##0 >> 16) & 0xff] ^ TE2[(in##1 >> 8) & 0xff] ^ TE3[(in##2) & 0xff] \
+                ^ (ekey)[((i) << 2) + 3]; \
+} while (0)
+
+int32_t CRYPT_AES_Encrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
+{
+    (void)len;
+    const uint32_t *ekey = ctx->key;
+    uint32_t c0, c1, c2, c3, t0, t1, t2, t3;
+
+    AES_ROUND_INIT(in, c, e);
+
+    AES_ENC_ROUND(c, t, 1, ekey);
+    AES_ENC_ROUND(t, c, 2, ekey);
+    AES_ENC_ROUND(c, t, 3, ekey);
+    AES_ENC_ROUND(t, c, 4, ekey);
+    AES_ENC_ROUND(c, t, 5, ekey);
+    AES_ENC_ROUND(t, c, 6, ekey);
+    AES_ENC_ROUND(c, t, 7, ekey);
+    AES_ENC_ROUND(t, c, 8, ekey);
+    AES_ENC_ROUND(c, t, 9, ekey);
+
+    if (ctx->rounds > 10) {         // AES192/AES256执行10、11轮运算
+        AES_ENC_ROUND(t, c, 10, ekey);
+        AES_ENC_ROUND(c, t, 11, ekey);
+    }
+
+    if (ctx->rounds > 12) {         // AES256执行12、13轮运算
+        AES_ENC_ROUND(t, c, 12, ekey);
+        AES_ENC_ROUND(c, t, 13, ekey);
+    }
+
+    /* 最后一轮不进行列混淆,直接进行移位并查找s盒 */
+    ekey += ctx->rounds * 4;    // 最后一轮计算ekey的位置,前面已经使用过4 * rounds的ekey
+
+    c0 = SSEARCH(t0, t1, t2, t3) ^ ekey[0];  // operation ekey 0
+    c1 = SSEARCH(t1, t2, t3, t0) ^ ekey[1];  // operation ekey 1
+    c2 = SSEARCH(t2, t3, t0, t1) ^ ekey[2];  // operation ekey 2
+    c3 = SSEARCH(t3, t0, t1, t2) ^ ekey[3];  // operation ekey 3
+
+    PUT_UINT32_BE(c0, out, 0);  // c0转换为out下标为0的4个字节
+    PUT_UINT32_BE(c1, out, 4);  // c1转换为out下标为4的4个字节
+    PUT_UINT32_BE(c2, out, 8);  // c2转换为out下标为8的4个字节
+    PUT_UINT32_BE(c3, out, 12);  // c3转换为out下标为12的4个字节
+
+    return CRYPT_SUCCESS;
+}
+
+#define AES_DEC_ROUND(in, r, i, dkey)    \
+do { \
+    r##0 = TD0[(in##0 >> 24)] ^ TD1[(in##3 >> 16) & 0xff] ^ TD2[(in##2 >> 8) & 0xff] ^ TD3[(in##1) & 0xff] \
+            ^ (dkey)[((i) << 2) + 0]; \
+    r##1 = TD0[(in##1 >> 24)] ^ TD1[(in##0 >> 16) & 0xff] ^ TD2[(in##3 >> 8) & 0xff] ^ TD3[(in##2) & 0xff] \
+            ^ (dkey)[((i) << 2) + 1]; \
+    r##2 = TD0[(in##2 >> 24)] ^ TD1[(in##1 >> 16) & 0xff] ^ TD2[(in##0 >> 8) & 0xff] ^ TD3[(in##3) & 0xff] \
+            ^ (dkey)[((i) << 2) + 2]; \
+    r##3 = TD0[(in##3 >> 24)] ^ TD1[(in##2 >> 16) & 0xff] ^ TD2[(in##1 >> 8) & 0xff] ^ TD3[(in##0) & 0xff] \
+            ^ (dkey)[((i) << 2) + 3]; \
+} while (0)
+
+int32_t CRYPT_AES_Decrypt(const CRYPT_AES_Key *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
+{
+    (void)len;
+    const uint32_t *dkey = ctx->key + ctx->rounds * 4;  // 4 byte
+    uint32_t p0, p1, p2, p3, t0, t1, t2, t3;
+
+    // 初始化p0,dkey从key的尾部开始
+    AES_ROUND_INIT(in, p, d);
+
+    dkey = ctx->key;
+
+    if (ctx->rounds > 12) {         // AES256执行12、13轮运算
+        AES_DEC_ROUND(p, t, 13, dkey);
+        AES_DEC_ROUND(t, p, 12, dkey);
+    }
+
+    if (ctx->rounds > 10) {         // AES192执行10、11轮运算
+        AES_DEC_ROUND(p, t, 11, dkey);
+        AES_DEC_ROUND(t, p, 10, dkey);
+    }
+
+    AES_DEC_ROUND(p, t, 9, dkey);
+    AES_DEC_ROUND(t, p, 8, dkey);
+    AES_DEC_ROUND(p, t, 7, dkey);
+    AES_DEC_ROUND(t, p, 6, dkey);
+    AES_DEC_ROUND(p, t, 5, dkey);
+    AES_DEC_ROUND(t, p, 4, dkey);
+    AES_DEC_ROUND(p, t, 3, dkey);
+    AES_DEC_ROUND(t, p, 2, dkey);
+    AES_DEC_ROUND(p, t, 1, dkey);
+
+    /* 最后一轮不进行列混淆,直接进行移位并查找逆s盒 */
+    p0 = INVSSEARCH(t0, t1, t2, t3) ^ dkey[0];  // dkey 0
+    p1 = INVSSEARCH(t1, t2, t3, t0) ^ dkey[1];  // dkey 1
+    p2 = INVSSEARCH(t2, t3, t0, t1) ^ dkey[2];  // dkey 2
+    p3 = INVSSEARCH(t3, t0, t1, t2) ^ dkey[3];  // dkey 3
+
+    PUT_UINT32_BE(p0, out, 0);  // in 从 0 下标开始的4个字节
+    PUT_UINT32_BE(p1, out, 4);  // in 从 4 下标开始的4个字节
+    PUT_UINT32_BE(p2, out, 8);  // in 从 8 下标开始的4个字节
+    PUT_UINT32_BE(p3, out, 12);  // in 从 12 下标开始的4个字节
+    SAL_CleanseData(&p0, sizeof(uint32_t));
+    SAL_CleanseData(&p1, sizeof(uint32_t));
+    SAL_CleanseData(&p2, sizeof(uint32_t));
+    SAL_CleanseData(&p3, sizeof(uint32_t));
+
+    return CRYPT_SUCCESS;
+}
+
+void CRYPT_AES_Clean(CRYPT_AES_Key *ctx)
+{
+    if (ctx == NULL) {
+        return;
+    }
+
+    SAL_CleanseData((void *)(ctx), sizeof(CRYPT_AES_Key));
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/hkdf/include/crypt_hkdf.h b/code/sdk/open_source/HiTLS/crypto/hkdf/include/crypt_hkdf.h
new file mode 100644 (file)
index 0000000..23155bf
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_hkdf.h
+ * Description: hkdf算法原语实现
+ * Author: liushaoming
+ * Create: 2022-05-11
+ */
+
+#ifndef CRYPT_HKDF_H
+#define CRYPT_HKDF_H
+
+#include <stdint.h>
+#include "crypt_local_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+ * @brief hkdf密钥派生算法
+ *
+ * @param macMeth [in] hmac算法method,仅支持HMAC方法
+ * @param mdMeth [in] md算法method
+ * @param key [IN] 密码,用户输入的字符串
+ * @param keyLen [IN] 密码长度,任意长度,包括0长度。
+ * @param salt [IN] 盐值,用户输入的字符串
+ * @param saltLen [IN] 盐值长度,任意长度,包括0长度。
+ * @param info [in] 额外信息
+ * @param infoLen [in] 额外信息长度,任意长度,包括0长度。
+ * @param out [OUT] 派生密钥
+ * @param outLen [IN] 派生密钥长度,不为0的任意整数,其中最大值:
+ *                      CRYPT_MAC_HMAC_SHA1对应最大值为5100、
+ *                      CRYPT_MAC_HMAC_SHA224对应最大值为7140、
+ *                      CRYPT_MAC_HMAC_SHA256对应最大值为8160、
+ *                      CRYPT_MAC_HMAC_SHA384对应最大值为12240、
+ *                      CRYPT_MAC_HMAC_SHA512对应最大值为16320、
+ *
+ * @return  CRYPT_OK 成功
+ *          其他错误码参考 ht_error.h
+ */
+
+int32_t CRYPT_HKDF(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, uint32_t keyLen,
+    const uint8_t *salt, uint32_t saltLen, const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/hkdf/src/hkdf.c b/code/sdk/open_source/HiTLS/crypto/hkdf/src/hkdf.c
new file mode 100644 (file)
index 0000000..59d5aca
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file hkdf.c
+ * Description: hkdf算法原语实现
+ * Author: liushaoming
+ * Create: 2022-05-11
+ */
+#include <stdint.h>
+#include "securec.h"
+#include "bsl_err_internal.h"
+#include "sal_mem.h"
+#include "crypt_local_types.h"
+#include "crypt_errno.h"
+#include "crypt_utils.h"
+#include "crypt_hkdf.h"
+
+#define HKDF_MAX_HMACSIZE 64
+
+int32_t CRYPT_HKDF_Extract(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key,
+    uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, uint8_t *prk, uint32_t *prkLen)
+{
+    int32_t ret = CRYPT_SUCCESS;
+    void *macCtx = SAL_MALLOC(macMeth->ctxSize);
+    if (macCtx == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
+        return CRYPT_MEM_ALLOC_FAIL;
+    }
+    (void)memset_s(macCtx, macMeth->ctxSize, 0, macMeth->ctxSize);
+
+    ret = macMeth->initCtx(macCtx, mdMeth);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    ret = macMeth->init(macCtx, salt, saltLen);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    ret = macMeth->update(macCtx, key, keyLen);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    ret = macMeth->final(macCtx, prk, prkLen);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+
+EXIT:
+    macMeth->deinit(macCtx);
+    macMeth->deinitCtx(macCtx);
+    SAL_FREE(macCtx);
+    return ret;
+}
+
+int32_t CRYPT_HKDF_Expand(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *prk, uint32_t prkLen,
+    const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t outLen)
+{
+    int32_t ret = CRYPT_SUCCESS;
+    uint8_t hash[HKDF_MAX_HMACSIZE];
+    uint32_t hashLen = HKDF_MAX_HMACSIZE;
+    uint8_t counter = 1;
+    uint32_t totalLen = 0;
+    uint32_t n;
+    void *macCtx = SAL_MALLOC(macMeth->ctxSize);
+    if (macCtx == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
+        return CRYPT_MEM_ALLOC_FAIL;
+    }
+
+    ret = macMeth->initCtx(macCtx, mdMeth);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    ret = macMeth->init(macCtx, prk, prkLen);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    ret = macMeth->update(macCtx, info, infoLen);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    ret = macMeth->update(macCtx, &counter, 1);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    ret = macMeth->final(macCtx, hash, &hashLen);
+    GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+    if (hashLen >= outLen) {
+        (void)memcpy_s(out, outLen, hash, outLen);
+        goto EXIT;
+    }
+    (void)memcpy_s(out, outLen, hash, hashLen);
+    totalLen += hashLen;
+    /* ceil(a / b) = (a + b - 1) / b */
+    n = (outLen + hashLen - 1) / hashLen;
+    // 2 表示计数2,上面代码已经使用了计数1
+    counter = 2;
+    for (uint32_t i = 2; i <= n; i++, counter++) {
+        macMeth->reinit(macCtx);
+        ret = macMeth->update(macCtx, hash, hashLen);
+        GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+        ret = macMeth->update(macCtx, info, infoLen);
+        GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+        ret = macMeth->update(macCtx, &counter, 1);
+        GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+        ret = macMeth->final(macCtx, hash, &hashLen);
+        GOTO_EXIT_IF(ret != CRYPT_SUCCESS);
+        hashLen = hashLen > (outLen - totalLen) ? (outLen - totalLen) : hashLen;
+        (void)memcpy_s(out + totalLen, outLen - totalLen, hash, hashLen);
+        totalLen += hashLen;
+    }
+
+EXIT:
+    macMeth->deinit(macCtx);
+    macMeth->deinitCtx(macCtx);
+    SAL_FREE(macCtx);
+    return ret;
+}
+
+int32_t CRYPT_HKDF(const EAL_MacMethod *macMeth, const EAL_MdMethod *mdMeth, const uint8_t *key, uint32_t keyLen,
+    const uint8_t *salt, uint32_t saltLen, const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len)
+{
+    if (macMeth == NULL || mdMeth == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    if (key == NULL && keyLen > 0) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    if (salt == NULL && saltLen > 0) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    if (info == NULL && infoLen > 0) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    if ((out == NULL) || (len == 0)) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    int ret;
+    uint32_t hashLen = mdMeth->mdSize;
+    /* len cannot be larger than 255 * hashLen */
+    if (len > hashLen * 255) {
+        return CRYPT_HKDF_DKLEN_OVERFLOW;
+    }
+
+    uint8_t prk[HKDF_MAX_HMACSIZE];
+    uint32_t prkLen = HKDF_MAX_HMACSIZE;
+    ret = CRYPT_HKDF_Extract(macMeth, mdMeth, key, keyLen, salt, saltLen, prk, &prkLen);
+    if (ret != CRYPT_SUCCESS) {
+        return ret;
+    }
+    ret = CRYPT_HKDF_Expand(macMeth, mdMeth, prk, prkLen, info, infoLen, out, len);
+    if (ret != CRYPT_SUCCESS) {
+        return ret;
+    }
+    return CRYPT_SUCCESS;
+}
diff --git a/code/sdk/open_source/HiTLS/crypto/hmac/include/crypt_hmac.h b/code/sdk/open_source/HiTLS/crypto/hmac/include/crypt_hmac.h
new file mode 100644 (file)
index 0000000..6c154f4
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_hmac.h
+ * Description: hmac原语实现头文件
+ * Author: liushaoming
+ * Create: 2022-04-18
+ */
+#ifndef CRYPT_HMAC_H
+#define CRYPT_HMAC_H
+
+#include <stdint.h>
+#include "crypt_local_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cpluscplus */
+
+#define HMAC_MAXBLOCKSIZE 128
+#define HMAC_MAXOUTSIZE   64
+
+typedef struct HMAC_Ctx {
+    const EAL_MdMethod *method;
+    void *mdCtx;            /* md ctx */
+    void *oCtx;             /* opad ctx */
+    void *iCtx;             /* ipad ctx */
+} CRYPT_HMAC_Ctx;
+
+int32_t CRYPT_HMAC_InitCtx(CRYPT_HMAC_Ctx *ctx, const EAL_MdMethod *m);
+void    CRYPT_HMAC_DeinitCtx(CRYPT_HMAC_Ctx *ctx);
+int32_t CRYPT_HMAC_Init(CRYPT_HMAC_Ctx *ctx, const uint8_t *key, uint32_t len);
+int32_t CRYPT_HMAC_Update(CRYPT_HMAC_Ctx *ctx, const uint8_t *in, uint32_t len);
+int32_t CRYPT_HMAC_Final(CRYPT_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len);
+void    CRYPT_HMAC_Reinit(CRYPT_HMAC_Ctx *ctx);
+void    CRYPT_HMAC_Deinit(CRYPT_HMAC_Ctx *ctx);
+uint32_t  CRYPT_HMAC_GetMacLen(const CRYPT_HMAC_Ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif /* __cpluscplus */
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/hmac/src/hmac.c b/code/sdk/open_source/HiTLS/crypto/hmac/src/hmac.c
new file mode 100644 (file)
index 0000000..75f819a
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file hmac.c
+ * Description: hmac原语实现
+ * Author: liushaoming
+ * Create: 2022-04-18
+ */
+#include <stdlib.h>
+#include <stdbool.h>
+#include "securec.h"
+#include "sal_mem.h"
+#include "crypt_errno.h"
+#include "bsl_err_internal.h"
+#include "crypt_hmac.h"
+
+
+#define GOTO_ERROR_IF(condition, ret) do {   \
+    if (condition) {                         \
+        BSL_ERR_PUSH_ERROR((ret));           \
+        goto ERR;                            \
+    }                                        \
+} while (0)
+
+uint32_t CRYPT_HMAC_GetMacLen(const CRYPT_HMAC_Ctx *ctx)
+{
+    if (ctx == NULL || ctx->method == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return 0;
+    }
+    return ctx->method->mdSize;
+}
+
+int32_t CRYPT_HMAC_InitCtx(CRYPT_HMAC_Ctx *ctx, const EAL_MdMethod *m)
+{
+    if (ctx == NULL || m == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+
+    void *mdCtx = (void *)SAL_MALLOC(m->ctxSize * 3); // 3个ctx 包括mdCtx iCtx oCtx
+    if (mdCtx == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
+        return CRYPT_MEM_ALLOC_FAIL;
+    }
+    // 3个ctx清零 包括mdCtx iCtx oCtx
+    (void)memset_s(mdCtx, m->ctxSize * 3, 0, m->ctxSize * 3);
+
+    ctx->mdCtx = mdCtx;
+    ctx->iCtx = (void *)((uint8_t *)mdCtx + m->ctxSize);
+    // 偏移2个ctxSize (mdCtx,iCtx)
+    ctx->oCtx = (void *)((uint8_t *)mdCtx + m->ctxSize * 2);
+    ctx->method = m;
+
+    return CRYPT_SUCCESS;
+}
+
+void CRYPT_HMAC_DeinitCtx(CRYPT_HMAC_Ctx *ctx)
+{
+    if (ctx == NULL || ctx->method == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return;
+    }
+    const EAL_MdMethod *method = ctx->method;
+    // 3个ctx清零 包括mdCtx iCtx oCtx
+    SAL_CleanseData((void *)(ctx->mdCtx), method->ctxSize * 3);
+    SAL_FREE(ctx->mdCtx);
+}
+
+int32_t CRYPT_HMAC_Init(CRYPT_HMAC_Ctx *ctx, const uint8_t *key, uint32_t len)
+{
+    if (ctx == NULL || ctx->method == NULL || (key == NULL && len != 0)) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    const EAL_MdMethod *method = ctx->method;
+    uint32_t blockSize = method->blockSize;
+    uint8_t tmp[HMAC_MAXBLOCKSIZE];
+    uint32_t tmpLen = HMAC_MAXBLOCKSIZE;
+    const uint8_t *keyTmp = key;
+    uint32_t i, keyLen = len;
+    uint8_t ipad[HMAC_MAXBLOCKSIZE];
+    uint8_t opad[HMAC_MAXBLOCKSIZE];
+    int32_t ret;
+
+    if (keyLen > blockSize) {
+        keyTmp = tmp;
+        ret = method->init(ctx->mdCtx);
+        GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+        ret = method->update(ctx->mdCtx, key, keyLen);
+        GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+        ret = method->final(ctx->mdCtx, tmp, &tmpLen);
+        GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+        keyLen = method->mdSize;
+    }
+    for (i = 0; i < keyLen; i++) {
+        ipad[i] = 0x36 ^ keyTmp[i];
+        opad[i] = 0x5c ^ keyTmp[i];
+    }
+    for (i = keyLen; i < blockSize; i++) {
+        ipad[i] = 0x36;
+        opad[i] = 0x5c;
+    }
+    ret = method->init(ctx->iCtx);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+    ret = method->update(ctx->iCtx, ipad, method->blockSize);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+    ret = method->init(ctx->oCtx);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+    ret = method->update(ctx->oCtx, opad, method->blockSize);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+    ret = method->copyCtx(ctx->mdCtx, ctx->iCtx);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+
+    (void)memset_s(tmp, HMAC_MAXBLOCKSIZE, 0, HMAC_MAXBLOCKSIZE);
+    return CRYPT_SUCCESS;
+
+ERR:
+    method->deinit(ctx->mdCtx);
+    method->deinit(ctx->iCtx);
+    method->deinit(ctx->oCtx);
+    return ret;
+}
+
+int32_t CRYPT_HMAC_Update(CRYPT_HMAC_Ctx *ctx, const uint8_t *in, uint32_t len)
+{
+    if (ctx == NULL || ctx->method == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    return ctx->method->update(ctx->mdCtx, in, len);
+}
+
+int32_t CRYPT_HMAC_Final(CRYPT_HMAC_Ctx *ctx, uint8_t *out, uint32_t *len)
+{
+    if (ctx == NULL || ctx->method == NULL || out == NULL || len == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    const EAL_MdMethod *method = ctx->method;
+    if (*len < method->mdSize) {
+        BSL_ERR_PUSH_ERROR(CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH);
+        return CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH;
+    }
+    *len = method->mdSize;
+    uint8_t tmp[HMAC_MAXOUTSIZE];
+    uint32_t tmpLen = sizeof(tmp);
+    int32_t ret;
+    ret = method->final(ctx->mdCtx, tmp, &tmpLen);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+    ret = method->copyCtx(ctx->mdCtx, ctx->oCtx);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+    ret = method->update(ctx->mdCtx, tmp, tmpLen);
+    GOTO_ERROR_IF(ret != CRYPT_SUCCESS, ret);
+    return method->final(ctx->mdCtx, out, len);
+ERR:
+    return ret;
+}
+
+void CRYPT_HMAC_Reinit(CRYPT_HMAC_Ctx *ctx)
+{
+    if (ctx == NULL || ctx->method == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return;
+    }
+    const EAL_MdMethod *method = ctx->method;
+    method->copyCtx(ctx->mdCtx, ctx->iCtx);
+}
+
+void CRYPT_HMAC_Deinit(CRYPT_HMAC_Ctx *ctx)
+{
+    if (ctx == NULL || ctx->method == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return;
+    }
+    const EAL_MdMethod *method = ctx->method;
+    (void)method->deinit(ctx->mdCtx);
+    (void)method->deinit(ctx->iCtx);
+    (void)method->deinit(ctx->oCtx);
+}
diff --git a/code/sdk/open_source/HiTLS/crypto/include/crypt_arm.h b/code/sdk/open_source/HiTLS/crypto/include/crypt_arm.h
new file mode 100644 (file)
index 0000000..2bd0ae8
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * @defgroup    crypt_arm.h
+ * @ingroup     crypto
+ * @brief       arm_arch 对应的宏设置
+ */
+ 
+#ifndef CRYPT_ARM_H
+#define CRYPT_ARM_H
+
+#ifndef CRYPT_VAL
+#define CRYPT_VAL               16
+#endif
+#ifndef CRYPT_VAL2
+#define CRYPT_VAL2              26
+#endif
+#if defined(__arm__) || defined (__arm)
+#define CRYPT_CAP               CRYPT_VAL
+#define CRYPT_CE                CRYPT_VAL2
+#define CRYPT_ARM_NEON          (1 << 12)
+#define CRYPT_ARM_AES           (1 << 0)
+#define CRYPT_ARM_PMULL         (1 << 1)
+#define CRYPT_ARM_SHA1          (1 << 2)
+#define CRYPT_ARM_SHA256        (1 << 3)
+#elif defined(__aarch64__)
+#define CRYPT_CAP               CRYPT_VAL
+#define CRYPT_CE                CRYPT_VAL
+#define CRYPT_ARM_NEON          (1 << 1)
+#define CRYPT_ARM_AES           (1 << 3)
+#define CRYPT_ARM_PMULL         (1 << 4)
+#define CRYPT_ARM_SHA1          (1 << 5)
+#define CRYPT_ARM_SHA256        (1 << 6)
+#define CRYPT_ARM_SM3           (1 << 18)
+#define CRYPT_ARM_SM4           (1 << 19)
+#define CRYPT_ARM_SHA512        (1 << 21)
+#endif
+
+#ifndef __ASSEMBLER__
+extern unsigned int g_cryptArmCpuInfo;
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/include/crypt_binlog_id.h b/code/sdk/open_source/HiTLS/crypto/include/crypt_binlog_id.h
new file mode 100644 (file)
index 0000000..b627cc6
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       CRYPTO模块的打点日志点号id
+ */
+
+#ifndef CRYPT_BINLOG_ID_H
+#define CRYPT_BINLOG_ID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum CRYPTO_BINLOG_ID {
+    BINLOG_ID10001 = 10001, BINLOG_ID10002, BINLOG_ID10003, BINLOG_ID10004, BINLOG_ID10005,
+    BINLOG_ID10006, BINLOG_ID10007, BINLOG_ID10008,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/include/crypt_encode.h b/code/sdk/open_source/HiTLS/crypto/include/crypt_encode.h
new file mode 100644 (file)
index 0000000..b9c8aa9
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_encode.h
+ * Description: dsa中der-asn1相关的编解码接口
+ * Author: linkaixin
+ * Create: 2022-3-21
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-3-21   linkaixin        dsa中der-asn1相关的编解码接口
+ */
+#ifndef CRYPT_ENCODE_H
+#define CRYPT_ENCODE_H
+#if defined(HITLS_CRYPTO_DSA) || defined(HITLS_CRYPTO_SM2) \
+    || defined(HITLS_CRYPTO_SM9) || defined(HITLS_CRYPTO_ECDSA)
+#include "crypt_bn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cpluscplus */
+
+#define DSA_MIN_PBITS 1024 // DSA最小规格1024bit
+#define DSA_MAX_PBITS 3072 // DSA最大规格3072bit
+#define DSA_MIN_QBITS 160  // DSA参数q最小规格
+
+typedef struct {
+    BN_BigNum *r;
+    BN_BigNum *s;
+} DSA_Sign;
+// 签名数据编码
+int32_t SignDataEncode(const DSA_Sign *s, uint8_t *sign, uint32_t *signLen);
+
+// 签名数据解码
+int32_t SignDataDecode(DSA_Sign *s, const uint8_t *sign, uint32_t signLen);
+
+// 获取签名数据所需长度
+uint32_t SignEnCodeLen(uint32_t rLen, uint32_t sLen);
+
+// 大数进行编码时的流长度
+uint32_t SignStringLenOfBn(const BN_BigNum *num);
+
+#ifdef HITLS_CRYPTO_SM9
+int32_t SignDataEncodeByString(uint8_t *sign, uint32_t *signLen,
+    const uint8_t *h, uint32_t hLen, const uint8_t *s, uint32_t sLen);
+
+int32_t SignDataDecode2String(const uint8_t *sign, uint32_t signLen,
+    uint8_t *h, uint32_t *hLen, uint8_t *s, uint32_t *sLen);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/include/crypt_local_types.h b/code/sdk/open_source/HiTLS/crypto/include/crypt_local_types.h
new file mode 100644 (file)
index 0000000..a5fcfc6
--- /dev/null
@@ -0,0 +1,247 @@
+/*\r
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.\r
+ * @file crypt_local_types.h\r
+ * Description: 算法操作语义抽象\r
+ * Author: zhangqiankun\r
+ * Create: 2022-2-14\r
+ * Modification History\r
+ *  DATE        NAME             DESCRIPTION\r
+ *  --------------------------------------------------------------------------\r
+ *  2022-2-14  zhangqiankun        创建算法操作语义抽象文件\r
+ *  2022-2-16  zhangqiankun        修改MD抽象层内容\r
+ */\r
+\r
+#ifndef CRYPT_LOCAL_TYPES_H\r
+#define CRYPT_LOCAL_TYPES_H\r
+\r
+#include <stdint.h>\r
+#include <stdlib.h>\r
+#include "crypt_algid.h"\r
+#include "crypt_types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+/* MD算法操作接口原型 */\r
+typedef int32_t (*MdInit)(void *data);\r
+typedef int32_t (*MdUpdate)(void *data, const uint8_t *input, uint32_t len);\r
+typedef int32_t (*MdFinal)(void *data, uint8_t *out, uint32_t *len);\r
+typedef void (*MdDeinit)(void *data);\r
+typedef int32_t (*MdCopyCtx)(void *dst, void *src);\r
+\r
+typedef struct {\r
+    uint16_t blockSize;            // HASH算法单次处理的blockSize,配合其他算法使用\r
+    uint16_t mdSize;               // HASH算法的输出长度\r
+    uint16_t ctxSize;              // HASH的上下文的size\r
+    MdInit init;                   // 初始化MD上下文的密钥\r
+    MdUpdate update;               // 添加MD计算的分块数据\r
+    MdFinal final;                 // 完成MD计算,得到MD结果\r
+    MdDeinit deinit;               // 清理MD上下文密钥信息\r
+    MdCopyCtx copyCtx;             // 拷贝MD上下文\r
+} EAL_MdMethod;\r
+\r
+typedef struct {\r
+    uint16_t hashSize;               // Siphash算法的输出长度\r
+    uint16_t compressionRounds;     // 压缩轮数\r
+    uint16_t finalizationRounds;    // 收尾轮数\r
+} EAL_SiphashMethod;\r
+\r
+/* 非对称原语方法提供 */\r
+typedef void *(*PkeyNew)(void);\r
+typedef void (*PkeyFree)(void *key);\r
+typedef void *(*PkeyNewParaById)(int32_t id);\r
+typedef void (*PkeyFreePara)(void *para);\r
+typedef int32_t (*PkeySetPara)(void *key, const void *para);\r
+typedef int32_t (*PkeyGetPara)(const void *key, void *para);\r
+typedef int32_t (*PkeyGen)(void *key);\r
+typedef uint32_t (*PkeyBits)(void *key);\r
+typedef uint32_t (*PkeyGetSignLen)(void *key);\r
+typedef int32_t (*PkeyCtrl)(void *key, CRYPT_PkeyCtrl opt, void *val, uint32_t len);\r
+typedef int32_t (*PkeySetPrv)(void *key, const void *prv);\r
+typedef int32_t (*PkeySetPub)(void *key, const void *pub);\r
+typedef int32_t (*PkeyGetPrv)(const void *key, void *prv);\r
+typedef int32_t (*PkeyGetPub)(const void *key, void *pub);\r
+typedef void *(*PkeyNewPara)(const void *para);\r
+typedef int32_t (*PkeySign)(const void *key, const uint8_t *data, uint32_t dataLen,\r
+    uint8_t *sign, uint32_t *signLen);\r
+typedef int32_t (*PkeyVerify)(const void *key, const uint8_t *data, uint32_t dataLen,\r
+    const uint8_t *sign, uint32_t signLen);\r
+typedef int32_t (*PkeyComputeShareKey)(const void *key, const void *pub,\r
+    uint8_t *share, uint32_t *shareLen);\r
+typedef int32_t (*PkeyCrypt)(const void *key, const uint8_t *data, uint32_t dataLen,\r
+    uint8_t *out, uint32_t *outLen);\r
+typedef int32_t (*PkeyCheck)(const void *key);\r
+\r
+\r
+/**\r
+* @ingroup  EAL\r
+*\r
+* eal的method结构体\r
+*/\r
+typedef struct {\r
+    PkeyNew newCtx;                         // 申请秘钥对结构体资源\r
+    PkeyFree freeCtx;                       // 秘钥结构体释放\r
+    PkeySetPara setPara;                    // 在秘钥对结构体中设置参数\r
+    PkeyGetPara getPara;                    // 在秘钥对结构体中获取参数\r
+    PkeyGen gen;                            // 生成秘钥对\r
+    PkeyBits bits;                          // 获取秘钥长\r
+    PkeyGetSignLen signLen;                 // 获取签名数据长度\r
+    PkeyCtrl ctrl;                          // 控制参数\r
+    PkeyNewParaById newParaById;            // 通过参数ID生成参数\r
+    PkeyFreePara freePara;                  // 释放秘钥参数\r
+    PkeyNewPara newPara;                    // 生成秘钥参数\r
+    PkeySetPub setPub;                      // 设置公钥\r
+    PkeySetPrv setPrv;                      // 设置私钥\r
+    PkeyGetPub getPub;                      // 获取公钥\r
+    PkeyGetPrv getPrv;                      // 获取私钥\r
+    PkeySign sign;                          // 签名\r
+    PkeyVerify verify;                      // 验签\r
+    PkeyComputeShareKey computeShareKey;    // 计算共享秘钥\r
+    PkeyCrypt encrypt;                        // 加密\r
+    PkeyCrypt decrypt;                      // 解密\r
+    PkeyCheck check;                        // 检查密钥对一致性\r
+} EAL_PkeyMethod;\r
+\r
+/**\r
+ * @ingroup  sym_algid\r
+ * 对称加解密算法ID\r
+ */\r
+typedef enum {\r
+    CRYPT_SYM_AES128 = 0,\r
+    CRYPT_SYM_AES192,\r
+    CRYPT_SYM_AES256,\r
+    CRYPT_SYM_CHACHA20,\r
+    CRYPT_SYM_SM4,\r
+    CRYPT_SYM_TDES,\r
+    CRYPT_SYM_MAX\r
+} CRYPT_SYM_AlgId;\r
+\r
+typedef struct EAL_CipherMethodLocal {\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 初始化句柄,注册其他模块\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*initCtx)(void *ctx, const struct EAL_CipherMethodLocal *m);\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 反初始化句柄,回到调用init后的状态, 包括释放内存\r
+     * @return void\r
+     */\r
+    void (*deinitCtx)(void *ctx);\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 清除密钥,敏感信息,但不释放内存,回到initCtx后的状态\r
+     * @return void\r
+     */\r
+    void (*clean)(void *ctx);\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 设置加密密钥和密钥长度\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*setEncryptKey)(void *ctx, const uint8_t *key, uint32_t len);\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 设置解密密钥和密钥长度\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*setDecryptKey)(void *ctx, const uint8_t *key, uint32_t len);\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 对输入数据进行加密,加解密的数据长度一致\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*encrypt)(void *ctx, const uint8_t *in, uint8_t *out, uint32_t len);\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 对输入数据进行加密,加解密的数据长度一致\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*decrypt)(void *ctx, const uint8_t *in, uint8_t *out, uint32_t len);\r
+    /**\r
+     * @ingroup crypt_type\r
+     * @brief 对ctx进行参数设置\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*ctrl)(void *ctx, uint32_t opt, void *val, uint32_t len);\r
+\r
+    uint8_t blockSize;   /**< 块大小的字节数 */\r
+    uint16_t ctxSize;   /**< ctx句柄大小,最大支持到65535字节 */\r
+    CRYPT_SYM_AlgId algId;      /**< 算法ID */\r
+} EAL_CipherMethod;\r
+\r
+/* MAC算法操作接口原型 */\r
+// 初始化内存,并设置方法\r
+typedef int32_t (*MacInitCtx)(void *ctx, const void *method);\r
+// 完成key初始化\r
+typedef int32_t (*MacInit)(void *ctx, const uint8_t *key, uint32_t len);\r
+typedef int32_t (*MacUpdate)(void *ctx, const uint8_t *in, uint32_t len);\r
+typedef int32_t (*MacFinal)(void *ctx, const uint8_t *out, uint32_t *len);\r
+typedef void    (*MacDeinit)(void *ctx);\r
+// 与initCtx接口动作相反。清理敏感数据\r
+typedef void    (*MacDeinitCtx)(void *ctx);\r
+typedef void    (*MacReinit)(void *ctx);\r
+typedef uint32_t (*MacGetMacLen)(void *ctx);\r
+\r
+/* MAC算法操作方法集合 */\r
+typedef struct {\r
+    MacInitCtx initCtx;       // 申请内存,初始化并设置方法\r
+    MacInit init;             // 初始化MAC上下文的密钥\r
+    MacUpdate update;         // 添加MAC计算的分块数据\r
+    MacFinal final;           // 完成MAC计算,得到MAC结果\r
+    MacDeinit deinit;         // 清理MAC上下文密钥信息\r
+    MacDeinitCtx deinitCtx;   // 清理敏感数据并释放内存\r
+    MacReinit reinit;         // 重新初始化MAC上下文中的密钥,用于多次MAC计算密钥相同的场景\r
+    MacGetMacLen getLen;      // 获取MAC计算结果数据长度\r
+    uint16_t ctxSize;         // MAC 算法上下文大小\r
+} EAL_MacMethod;\r
+\r
+typedef struct {\r
+    union {\r
+        const EAL_MacMethod *macMethod;\r
+        const EAL_CipherMethod *modeMethod; // gmac 依赖对称算法的方法\r
+        const void *masMeth;    // 主算法的方法指针\r
+    };\r
+    union {\r
+        const EAL_MdMethod *md;        // hmac 依赖md算法\r
+        const EAL_CipherMethod *ciph;  // cmac 依赖aes接口\r
+        const EAL_SiphashMethod *sip;  // siphash method\r
+        const void *depMeth;           // 依赖算法指针,预留用于拓展\r
+    };\r
+} EAL_MacMethLookup;\r
+\r
+/**\r
+ * @ingroup  mode_algid\r
+ * 对称加解密模式ID\r
+ */\r
+typedef enum {\r
+    CRYPT_MODE_CBC = 0,\r
+    CRYPT_MODE_CTR,\r
+    CRYPT_MODE_ECB,\r
+    CRYPT_MODE_XTS,\r
+    CRYPT_MODE_CCM,\r
+    CRYPT_MODE_GCM,\r
+    CRYPT_MODE_CHACHA20_POLY1305,\r
+    CRYPT_MODE_CFB,\r
+    CRYPT_MODE_OFB,\r
+    CRYPT_MODE_MAX\r
+} CRYPT_MODE_AlgId;\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ *\r
+ * RSA用于签名时,PSS填充方式的结构体\r
+ */\r
+typedef struct {\r
+    int32_t saltLen;        /**< pss 盐值长度,-1表示hashLen,-2表示MaxLen */\r
+    const EAL_MdMethod *mdMeth;    /**< pss 填充时的mdid */\r
+    const EAL_MdMethod *mgfMeth;   /**< pss 填充时的mgfid */\r
+} RSA_PadingPara;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+#endif // EAL_LOCAL_TYPES_H\r
diff --git a/code/sdk/open_source/HiTLS/crypto/include/crypt_util_rand.h b/code/sdk/open_source/HiTLS/crypto/include/crypt_util_rand.h
new file mode 100644 (file)
index 0000000..1e2cd72
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_util_rand.h
+ * Description: 公共随机数注册头文件
+ * Author: panxinrong
+ * Create: 2022-5-14
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-5-14  panxinrong        创建
+ */
+
+#ifndef CRYPT_UTIL_RAND_H
+#define CRYPT_UTIL_RAND_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int32_t (*CRYPT_RandFunc)(uint8_t *rand, uint32_t randLen);
+
+/**
+ * @brief   随机数注册
+ *
+ * @param   func [IN] 随机数获取接口
+ */
+void CRYPT_RandRegist(CRYPT_RandFunc func);
+
+/**
+ * @brief   生成随机数
+ *
+ * @param   rand [OUT] 随机数buffer
+ * @param   randLen [IN] 随机数长度
+ *
+ * @retval  CRYPT_SUCCESS 生成随机数成功
+ * @retval  CRYPT_NO_REGIST_RAND 随机数未注册
+ * @retval  注册的随机数生成失败返回的错误
+ */
+int32_t CRYPT_Rand(uint8_t *rand, uint32_t randLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/include/crypt_utils.h b/code/sdk/open_source/HiTLS/crypto/include/crypt_utils.h
new file mode 100644 (file)
index 0000000..9fab630
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_utils.h
+ * Description: 公共头文件
+ * Author: zhangqiankun
+ * Create: 2022-3-5
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-3-5  zhangqiankun        创建公共头文件
+ */
+
+#ifndef CRYPT_UTILS_H
+#define CRYPT_UTILS_H
+
+#include <stdint.h>
+#include "crypt_algid.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define PUT_UINT32_BE(v, p, i)                                         \
+do {                                                                   \
+    (p)[(i) + 0] = (uint8_t)((v) >> 24); /* 24: 4th byte */      \
+    (p)[(i) + 1] = (uint8_t)((v) >> 16); /* 16: 3rd byte */      \
+    (p)[(i) + 2] = (uint8_t)((v) >>  8); /*  8: 2nd byte */      \
+    (p)[(i) + 3] = (uint8_t)((v) >>  0); /*  0: 1st byte */      \
+} while (0)
+
+#define GET_UINT32_BE(p, i)                                            \
+(                                                                      \
+    ((uint32_t)(p)[(i) + 0] << 24) | /* 24: 4th byte */                \
+    ((uint32_t)(p)[(i) + 1] << 16) | /* 16: 3rd byte */                \
+    ((uint32_t)(p)[(i) + 2] <<  8) | /*  8: 2nd byte */                \
+    ((uint32_t)(p)[(i) + 3] <<  0)   /*  0: 1st byte */                \
+)
+
+#define PUT_UINT32_LE(v, p, i)                                         \
+do {                                                                   \
+    (p)[(i) + 3] = (uint8_t)((v) >> 24); /* 24: 4th byte */      \
+    (p)[(i) + 2] = (uint8_t)((v) >> 16); /* 16: 3rd byte */      \
+    (p)[(i) + 1] = (uint8_t)((v) >>  8); /*  8: 2nd byte */      \
+    (p)[(i) + 0] = (uint8_t)((v) >>  0); /*  0: 1st byte */      \
+} while (0)
+
+#define PUT_UINT64_LE(v, p, i) do {                                    \
+    (p)[(i) + 7] = (uint8_t)((v) >> 56); /* 56: 8th byte */            \
+    (p)[(i) + 6] = (uint8_t)((v) >> 48); /* 48: 7rd byte */            \
+    (p)[(i) + 5] = (uint8_t)((v) >> 40); /* 40: 6nd byte */            \
+    (p)[(i) + 4] = (uint8_t)((v) >> 32); /* 32: 5st byte */            \
+    (p)[(i) + 3] = (uint8_t)((v) >> 24); /* 24: 4th byte */            \
+    (p)[(i) + 2] = (uint8_t)((v) >> 16); /* 16: 3rd byte */            \
+    (p)[(i) + 1] = (uint8_t)((v) >>  8); /*  8: 2nd byte */            \
+    (p)[(i) + 0] = (uint8_t)((v) >>  0); /*  0: 1st byte */            \
+} while (0)
+
+#define GET_UINT64_LE(p, i)                                            \
+(                                                                      \
+    ((uint64_t)(p)[(i) + 7] << 56) | ((uint64_t)(p)[(i) + 6] << 48) |  \
+    ((uint64_t)(p)[(i) + 5] << 40) | ((uint64_t)(p)[(i) + 4] << 32) |  \
+    ((uint64_t)(p)[(i) + 3] << 24) | ((uint64_t)(p)[(i) + 2] << 16) |  \
+    ((uint64_t)(p)[(i) + 1] <<  8) | ((uint64_t)(p)[(i) + 0] <<  0)    \
+)
+
+/**
+ * 判断是否满足条件condition,如果满足则跳转到EXIT标签
+ */
+#define GOTO_EXIT_IF(condition) \
+    do {                        \
+        if (condition) {        \
+            goto EXIT;          \
+        }                       \
+    } while (0)
+
+/**
+ * func返回值不为CRYPT_SUCCESS跳转到错误退出位置
+ */
+#define GOTO_ERR_IF(func, ret) do { \
+        (ret) = (func); \
+        if ((ret) != CRYPT_SUCCESS) { \
+            BSL_ERR_PUSH_ERROR((ret)); \
+            goto ERR; \
+        } \
+    } while (0)
+
+/**
+ * @brief 将两个数组的数据进行异或运算
+ *
+ * @param a [IN] 输入数据a
+ * @param b [IN] 输入数据b
+ * @param r [out] 输出结果数据
+ * @param len [IN] 输出结果数据长度
+ */
+#define DATA_XOR(a, b, r, len)       \
+    do {                             \
+        uint32_t subscript;          \
+        for (subscript = 0; subscript < (len); subscript++) { \
+            (r)[subscript] = (a)[subscript] ^ (b)[subscript]; \
+        }                             \
+    } while (0)
+
+/**
+ * @brief 将两个数组的数据每次32bit进行异或运算, 调用者保证输入输出是32bit的整数倍.地址为4字节对齐才做类型转换
+ *
+ * @param a [IN] 输入数据a
+ * @param b [IN] 输入数据b
+ * @param r [out] 输出结果数据
+ * @param len [IN] 输出结果数据长度
+ */
+#define DATA32_XOR(a, b, r, len)                                \
+    do {                                                        \
+        uint32_t ii;                                            \
+        uintptr_t aPtr = (uintptr_t)(a);                        \
+        uintptr_t bPtr = (uintptr_t)(b);                        \
+        uintptr_t rPtr = (uintptr_t)(r);                        \
+        if (((aPtr & 0x3) != 0) || ((bPtr & 0x3) != 0) || ((rPtr & 0x3) != 0)) {     \
+            for (ii = 0; ii < (len); ii++) {                    \
+                (r)[ii] = (a)[ii] ^ (b)[ii];                    \
+            }                                                   \
+        } else {                                                \
+            for (ii = 0; ii < (len); ii += 4) {                 \
+                *(uint32_t *)((r) + ii) = (*(const uint32_t *)((a) + ii)) ^ (*(const uint32_t *)((b) + ii)); \
+            }                                                   \
+        }                                                       \
+    } while (0)
+
+/**
+ * @brief 将两个数组的数据每次64bit进行异或运算, 调用者保证输入输出是64bit的整数倍。地址为8字节对齐才做类型转换
+ *
+ * @param a [IN] 输入数据a
+ * @param b [IN] 输入数据b
+ * @param r [out] 输出结果数据
+ * @param len [IN] 输出结果数据长度
+ */
+#define DATA64_XOR(a, b, r, len)                                \
+    do {                                                        \
+        uint32_t ii;                                            \
+        uintptr_t aPtr = (uintptr_t)(a);                        \
+        uintptr_t bPtr = (uintptr_t)(b);                        \
+        uintptr_t rPtr = (uintptr_t)(r);                        \
+        if (((aPtr & 0x7) != 0) || ((bPtr & 0x7) != 0) || ((rPtr & 0x7) != 0)) {     \
+            for (ii = 0; ii < (len); ii++) {                    \
+                (r)[ii] = (a)[ii] ^ (b)[ii];                    \
+            }                                                   \
+        } else {                                                \
+            for (ii = 0; ii < (len); ii += 8) {                 \
+                *(uint64_t *)((r) + ii) = (*(const uint64_t *)((a) + ii)) ^ (*(const uint64_t *)((b) + ii)); \
+            }                                                   \
+        }                                                       \
+    } while (0)
+
+/* Assumes that x is uint32_t and 0 < n < 32 */
+#define ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+#define ROTR64(x, n) (((x) << (64 - (n))) | ((x) >> (n))) // Assumes that x is uint64_t and 0 < n < 64
+
+#define IS_BUF_NON_ZERO(out, outLen)  (((out) != NULL) && ((outLen) > 0))
+#define CRYPT_IS_BUF_NON_ZERO(out, outLen)  (((out) != NULL) && ((outLen) > 0))
+#define CRYPT_CHECK_DATA_INVALID(d) (((d)->data == NULL && (d)->len != 0))
+#define CRYPT_IsDataNull(d) ((d) == NULL || (d)->data == NULL || (d)->len == 0)
+#define CRYPT_IN_RANGE(x, range) ((x) >= (range)->min && (x) <= (range)->max)
+#define CRYPT_CHECK_BUF_INVALID(buf, len) (((buf) == NULL && (len) != 0))
+#define CRYPT_SWAP32(x) ((((x) & 0xff000000) >> 24) | \
+                         (((x) & 0x00ff0000) >> 8) | \
+                         (((x) & 0x0000ff00) << 8) | \
+                         (((x) & 0x000000ff) << 24))
+#ifdef HITLS_BIG_ENDIAN
+
+#define CRYPT_HTONL(x) (x)
+
+// 将p + i解释为小端序, p的类型需要为uint8_t*
+#define GET_UINT32_LE(p, i)                                            \
+(                                                                      \
+    ((uint32_t)((const uint8_t *)(p))[(i) + 3] << 24) | /* 24: 4th byte */                \
+    ((uint32_t)((const uint8_t *)(p))[(i) + 2] << 16) | /* 16: 3rd byte */                \
+    ((uint32_t)((const uint8_t *)(p))[(i) + 1] <<  8) | /*  8: 2nd byte */                \
+    ((uint32_t)((const uint8_t *)(p))[(i) + 0] <<  0)   /*  0: 1st byte */                \
+)
+
+// 小端序转换位主机序
+#define CRYPT_LE32TOH(x)    CRYPT_SWAP32(x)
+// 主机序转换为小端序
+#define CRYPT_HTOLE32(x)    CRYPT_SWAP32(x)
+
+#else
+
+#define CRYPT_HTONL(x) CRYPT_SWAP32(x)
+
+// 将p + i解释为小端序
+#define GET_UINT32_LE(p, i)         \
+(                                   \
+    (((uintptr_t)(p) & 0x7) != 0) ? ((uint32_t)((const uint8_t *)(p))[(i) + 3] << 24) | /* 24: 4th byte */      \
+                                    ((uint32_t)((const uint8_t *)(p))[(i) + 2] << 16) | /* 16: 3rd byte */      \
+                                    ((uint32_t)((const uint8_t *)(p))[(i) + 1] <<  8) | /*  8: 2nd byte */      \
+                                    ((uint32_t)((const uint8_t *)(p))[(i) + 0] <<  0)   /*  0: 1st byte */      \
+                                  : (*(uint32_t *)((uint8_t *)(uintptr_t)(p) + (i)))                            \
+)
+
+// 小端序转换位主机序
+#define CRYPT_LE32TOH(x)    (x)
+// 主机序转换为小端序
+#define CRYPT_HTOLE32(x)    (x)
+
+#endif
+
+#ifdef HITLS_BIG_ENDIAN
+
+// 将p + i解释为小端序, p的类型需要为uint8_t*
+#define GET_UINT16_LE(p, i)                                            \
+(                                                                      \
+    ((uint16_t)((const uint8_t *)(p))[(i) + 1] <<  8) | /*  8: 2nd byte */                \
+    ((uint16_t)((const uint8_t *)(p))[(i) + 0] <<  0)   /*  0: 1st byte */                \
+)
+#else
+// 将p + i解释为小端序
+#define GET_UINT16_LE(p, i)         \
+(                                   \
+    (((uintptr_t)(p) & 0x7) != 0) ? ((uint16_t)((const uint8_t *)(p))[(i) + 1] <<  8) | /*  8: 2nd byte */      \
+                                    ((uint16_t)((const uint8_t *)(p))[(i) + 0] <<  0)   /*  0: 1st byte */      \
+                                  : (*(uint16_t *)((uint8_t *)(uintptr_t)(p) + (i)))                            \
+)
+#endif
+
+/*
+ * 64-bit integer manipulation functions (big endian)
+ */
+static inline uint64_t Uint64FromBeBytes(const uint8_t *bytes)
+{
+    return (((uint64_t)bytes[0] << 56) |    // 第0位左移7个字节(56)
+            ((uint64_t)bytes[1] << 48) |    // 第1位左移6个字节(48)
+            ((uint64_t)bytes[2] << 40) |    // 第2位左移5个字节(40)
+            ((uint64_t)bytes[3] << 32) |    // 第3位左移4个字节(32)
+            ((uint64_t)bytes[4] << 24) |    // 第4位左移3个字节(24)
+            ((uint64_t)bytes[5] << 16) |    // 第5位左移2个字节(16)
+            ((uint64_t)bytes[6] << 8) |     // 第6位左移1个字节(8)
+            (uint64_t)bytes[7]);            // 第7位可直接使用
+}
+
+static inline void Uint64ToBeBytes(uint64_t v, uint8_t *bytes)
+{
+    bytes[0] = (uint8_t)(v >> 56);  // 右移7个字节(56)
+    bytes[1] = (uint8_t)(v >> 48);  // 右移6个字节(48)
+    bytes[2] = (uint8_t)(v >> 40);  // 第2位右移5个字节(40)
+    bytes[3] = (uint8_t)(v >> 32);  // 第3位右移4个字节(32)
+    bytes[4] = (uint8_t)(v >> 24);  // 第4位右移3个字节(24)
+    bytes[5] = (uint8_t)(v >> 16);  // 第5位右移2个字节(16)
+    bytes[6] = (uint8_t)(v >> 8);   // 第6位右移1个字节(8)
+    bytes[7] = (uint8_t)(v & 0xffu);    // 第7位使用0xffu将其他位置0
+}
+
+uint32_t GetMdSizeById(CRYPT_MD_AlgId id);
+
+static inline uint32_t Uint32ConstTimeMsb(uint32_t a)
+{
+    // 31 == (4 * 8 - 1)
+    return 0u - (a >> 31);
+}
+
+static inline uint32_t Uint32ConstTimeIsZero(uint32_t a)
+{
+    return Uint32ConstTimeMsb(~a & (a - 1));
+}
+
+static inline uint32_t Uint32ConstTimeEqual(uint32_t a, uint32_t b)
+{
+    return Uint32ConstTimeIsZero(a ^ b);
+}
+// (mask & a) | (~mask & b)
+static inline uint32_t Uint32ConstTimeSelect(uint32_t mask, uint32_t a, uint32_t b)
+{
+    return ((mask) & a) | ((~mask) & b);
+}
+
+static inline uint32_t Uint32ConstTimeLt(uint32_t a, uint32_t b)
+{
+    return Uint32ConstTimeMsb(a ^ ((a ^ b) | ((a - b) ^ a)));
+}
+
+static inline uint32_t Uint32ConstTimeGt(uint32_t a, uint32_t b)
+{
+    return ~Uint32ConstTimeLt(a, b);
+}
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // CRYPT_UTILS_H
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes.h
new file mode 100644 (file)
index 0000000..0c90406
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+ * @defgroup    modes crypt_modes.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       modes句柄类型
+ */
+#ifndef CRYPT_MODES_H
+#define CRYPT_MODES_H
+
+#include <stdint.h>
+#include "crypt_eal_cipher.h"
+#include "crypt_types.h"
+#include "crypt_algid.h"
+#include "crypt_local_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define MODES_MAX_IV_LENGTH 24
+#define MODES_MAX_BUF_LENGTH 24
+#define DES_BLOCK_BYTE_NUM 8
+/**
+ * @ingroup crypt_mode_cipherctx
+ *  模式句柄
+ */
+typedef struct {
+    void *ciphCtx;  /* 每种算法自已定义的key  */
+    const EAL_CipherMethod *ciphMeth;  /* 对应底层的加解密, 操作keyctx */
+    uint8_t iv[MODES_MAX_IV_LENGTH]; /* 长度为blocksize */
+    uint8_t buf[MODES_MAX_BUF_LENGTH]; /* 缓存上一块的信息 */
+    uint8_t blockSize;     /* 保存块大小长度 */
+    uint8_t offset;   /* ctr、ofb模式下使用,若offset>0,iv的[0, offset-1]表示已使用过的数据,
+                         [offset, blockSize-1]表示未使用过的数据 */
+    uint8_t flag3Iv;       /* 是否为3个IV的标识 */
+    uint32_t ivIndex;       /* 表示使用第几块IV,TDES可能会有3个IV */
+    CRYPT_SYM_AlgId algId;  /* 对称算法ID */
+} MODE_CipherCtx;
+
+/**
+ * @brief 模块初始化,将加解密算法的method注册到模块中,并且开辟算法的上下文
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param method [IN] 对称加解密的方法
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_InitCtx(MODE_CipherCtx *ctx, const EAL_CipherMethod *method);
+
+/**
+ * @brief 模块反初始化,解除与算法模块的关系,并且释放算法的上下文
+ *
+ * @param ctx [IN] 模式句柄
+ * @param method [IN] 对称加解密的方法
+ */
+void MODE_DeInitCtx(MODE_CipherCtx *ctx);
+
+/**
+ * @brief 设置加密密钥
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param key [IN] 加密密钥
+ * @param len [IN] 加密密钥长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @brief 设置解密密钥
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param key [IN] 解密密钥
+ * @param len [IN] 解密密钥长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_SetDecryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @brief 对mode进行参数操作
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param opt [IN] 操作
+ * @param val [IN/OUT] 参数,可以是入参也可以是出参
+ * @param len [IN] 参数的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+/**
+ * @brief 获取分组大小
+ *
+ * @param ctx [IN] 模式句柄
+ * @param val [IN/OUT] 参数,可以是入参也可以是出参
+ * @param len [IN] 参数的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t GetBlockSize(MODE_CipherCtx *ctx, uint32_t *val, uint32_t len);
+
+/**
+ * @brief 模式内容清理,清除敏感数据,保留算法模块的内存以及方法
+ *
+ * @param ctx [IN] 模式句柄
+ * @return 无
+ */
+void MODE_Clean(MODE_CipherCtx *ctx);
+
+int32_t MODE_SetIv(MODE_CipherCtx *ctx, uint8_t *val, uint32_t len);
+int32_t MODE_GetIv(MODE_CipherCtx *ctx, uint8_t *val, uint32_t len);
+
+/**
+ * @brief SM4设置秘钥
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param key [IN] 秘钥
+ * @param len [IN] 秘钥的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t SM4_SetKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @brief SM4 deinit模式上下文
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ */
+void SM4_DeInitModeCtx(MODE_CipherCtx *ctx);
+
+// 从counter开始, 长度为counterLen的计数器
+static inline void IncCounter(uint8_t *counter, uint32_t counterLen)
+{
+    uint32_t i = counterLen;
+    uint16_t carry = 1;
+
+    while (i > 0) {
+        i--;
+        carry += counter[i];
+        counter[i] = carry & (0xFFu);
+        carry >>= 8;  // 取高8位
+    }
+}
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_cbc.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_cbc.h
new file mode 100644 (file)
index 0000000..f55a4e3
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * @defgroup    modes_cbc crypt_modes_cbc.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       modes句柄类型
+ */
+
+#ifndef CRYPT_MODES_CBC_H
+#define CRYPT_MODES_CBC_H
+
+#ifndef HITLS_CRYPTO_NO_CBC
+#include <stdbool.h>
+#include "crypt_modes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define CRYPT_SM4_BLOCKSIZE    16
+
+typedef struct {
+    uint8_t iv[CRYPT_SM4_BLOCKSIZE];
+    uint32_t rk[32]; // sm4 秘钥扩展后为32长度的uint32
+    bool safeMode; // 侧信道安全选项
+} CRYPT_SM4_ASM_Ctx;
+
+/**
+ * @brief CBC模式设置加密密钥
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param key [IN] 加密密钥
+ * @param len [IN] 加密密钥长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CBC_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @brief CBC模式加密
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CBC_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief CBC模式解密
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param in [IN] 待加密数据
+ * @param out [OUT] 已加密数据
+ * @param len [IN] 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CBC_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief 原语SM4 CBC模式加密块
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t SM4_CBC_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief 原语SM4 CBC模式解密块
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t SM4_CBC_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief 使用memset_s清理信息,仅供非认证算法使用
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ */
+void MODES_SM4_CBC_Clean(MODE_CipherCtx *ctx);
+
+/**
+ * @brief SM4 CBC模式下,对mode进行参数操作
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param opt [IN] 操作
+ * @param val [IN/OUT] 参数,可以是入参也可以是出参
+ * @param len [IN] 参数的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_SM4_CBC_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ccm.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ccm.h
new file mode 100644 (file)
index 0000000..4cbd08f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_modes_ccm.h
+ * Description: ccm模式
+ * Author: linkaixin
+ * Create: 2022-05-17
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-05-17  linkaixin        ccm模式头文件
+ */
+
+#ifndef CRYPT_MODES_CCM_H
+#define CRYPT_MODES_CCM_H
+
+#ifndef HITLS_CRYPTO_NO_CCM
+#include <stdint.h>
+#include "crypt_local_types.h"
+#include "crypt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define CCM_BLOCKSIZE 16
+
+typedef struct {
+    void *ciphCtx;  /* 每种算法自已定义的key  */
+    const EAL_CipherMethod *ciphMeth;  /* 对应底层的加解密, 操作keyctx */
+    uint8_t tagLen;    // tag长度 默认为16 在每次设置秘钥时进行重置
+
+    uint8_t nonce[CCM_BLOCKSIZE];  // nonce数据,ctr加密数据
+    uint8_t tag[CCM_BLOCKSIZE];    // tag数据,cbc加密中间数据
+    uint8_t last[CCM_BLOCKSIZE];   // ctr模式下上一块数据
+    uint64_t msgLen;    // 消息长度
+    uint8_t lastLen;    // ctr模式下上一块数据未使用数据长度
+    uint8_t tagInit;    // 标识tag是否做了初始化
+} MODES_CCM_Ctx;
+
+int32_t MODES_CCM_InitCtx(MODES_CCM_Ctx *ctx, const struct EAL_CipherMethodLocal *m);
+
+void MODES_CCM_DeinitCtx(MODES_CCM_Ctx *ctx);
+
+void MODES_CCM_Clean(MODES_CCM_Ctx *ctx);
+
+int32_t MODES_CCM_Ctrl(MODES_CCM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+int32_t MODES_CCM_SetKey(MODES_CCM_Ctx *ctx, const uint8_t *key, uint32_t len);
+
+int32_t MODES_CCM_Encrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+int32_t MODES_CCM_Decrypt(MODES_CCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_cfb.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_cfb.h
new file mode 100644 (file)
index 0000000..833c233
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_modes_cfb.h
+ * Description: cfb模式
+ * Author: chenrenhao
+ * Create: 2022-10-08
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-10-08  chenrenhao       cfb模式头文件
+ */
+
+#ifndef CRYPT_MODES_CFB_H
+#define CRYPT_MODES_CFB_H
+
+#ifndef HITLS_CRYPTO_NO_CFB
+#include "crypt_modes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+typedef struct {
+    MODE_CipherCtx *modeCtx;    /* 存放指向MODE_CipherCtx的指针 */
+    uint8_t feedbackBits;  /* 保存FeedBack长度 */
+    uint8_t cipherCache[3][DES_BLOCK_BYTE_NUM];     /* 3IV的TDES用,缓存前3块密文用于反馈 */
+    uint8_t cacheIndex;   /* 3IV的TDES用,当前使用哪一块缓存 */
+} MODE_CFB_Ctx;
+
+/**
+ * @brief 模块初始化,将加解密算法的method注册到模块中,并且开辟算法的上下文
+ *
+ * @param ctx [IN] 模式句柄
+ * @param method [IN] 对称加解密的方法
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CFB_InitCtx(MODE_CFB_Ctx *ctx, const EAL_CipherMethod *method);
+
+/**
+ * @brief CFB模式加密,可对任意字节进行加密,包含1-bit/8-bit/64-bit/128-bit CFB
+ *
+ * @param [IN] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CFB_Encrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief CFB模式解密,可对任意字节进行解密,包含1-bit/8-bit/64-bit/128-bit CFB
+ *
+ * @param ctx [IN] 模式句柄
+ * @param in [IN] 待解密数据
+ * @param out [OUT] 已解密数据
+ * @param len [IN] 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CFB_Decrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief 对mode进行参数操作
+ *
+ * @param ctx [IN] 模式句柄
+ * @param opt [IN] 操作 (Set/Get IV; Set/Get FeedbackSize)
+ * @param val [IN/OUT] 参数,可以是入参也可以是出参
+ * @param len [IN] 参数的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CFB_Ctrl(MODE_CFB_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+/**
+ * @brief CFB模式内容清理,清除敏感数据,保留算法模块的内存以及方法
+ *
+ * @param ctx [IN] 模式句柄
+ * @return 无
+ */
+void MODE_CFB_Clean(MODE_CFB_Ctx *ctx);
+
+/**
+ * @brief CFB模式设置加密密钥
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param key [IN] 加密密钥
+ * @param len [IN] 加密密钥长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CFB_SetEncryptKey(MODE_CFB_Ctx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @brief 模块反初始化,解除与算法模块的关系,并且释放算法的上下文
+ *
+ * @param ctx [IN] 模式句柄
+ * @param method [IN] 对称加解密的方法
+ */
+void MODE_CFB_DeInitCtx(MODE_CFB_Ctx *ctx);
+
+/**
+ * @brief CFB模式对bit进行加解密的接口(内部接口,仅测试用)
+ */
+int32_t MODE_CFB_BitCrypt(MODE_CFB_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_chacha20poly1305.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_chacha20poly1305.h
new file mode 100644 (file)
index 0000000..a2c69a3
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_modes_chacha20poly1305.h
+ * Description: chacha20_poly1305模式
+ * Author: linkaixin
+ * Create: 2022-05-05
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-05-05  linkaixin        chacha20_poly1305模式头文件
+ */
+
+#ifndef CRYPT_MODES_CHACHA20POLY1305_H
+#define CRYPT_MODES_CHACHA20POLY1305_H
+
+#ifndef HITLS_CRYPTO_NO_CHACHA20POLY1305
+#include <stdint.h>
+#include "crypt_local_types.h"
+#include "crypt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+typedef struct {
+    uint32_t acc[6];  // acc中间数据 需大于130bit
+    uint32_t r[4];    // 秘钥信息r 16字节 即4 * sizeof(uint32_t)
+    uint32_t s[4];    // 秘钥信息s 16字节 即4 * sizeof(uint32_t)
+    uint32_t table[36]; // 用于汇编计算加速的表
+    uint8_t last[16]; // 上一次未处理数据缓存 一个block16字节
+    uint32_t lastLen; // 上一次数据还有剩下的长度 字节长度
+    uint32_t flag;    // 用于保存汇编状态信息
+} Poly1305Ctx;
+
+typedef struct {
+    void *key; // 方法用的句柄
+    const EAL_CipherMethod *method; // 算法方法
+    Poly1305Ctx polyCtx;
+    uint64_t aadLen; // 状态,标识数据是否设置
+    uint64_t cipherTextLen; // 状态,标识数据是否设置
+} MODES_CHACHA20POLY1305_Ctx;
+
+int32_t MODES_CHACHA20POLY1305_InitCtx(MODES_CHACHA20POLY1305_Ctx *ctx, const struct EAL_CipherMethodLocal *m);
+
+void MODES_CHACHA20POLY1305_DeinitCtx(MODES_CHACHA20POLY1305_Ctx *ctx);
+
+void MODES_CHACHA20POLY1305_Clean(MODES_CHACHA20POLY1305_Ctx *ctx);
+
+int32_t MODES_CHACHA20POLY1305_Ctrl(MODES_CHACHA20POLY1305_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+int32_t MODES_CHACHA20POLY1305_SetEncryptKey(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *key, uint32_t len);
+
+int32_t MODES_CHACHA20POLY1305_SetDecryptKey(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *key, uint32_t len);
+
+int32_t MODES_CHACHA20POLY1305_Encrypt(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+int32_t MODES_CHACHA20POLY1305_Decrypt(MODES_CHACHA20POLY1305_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ctr.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ctr.h
new file mode 100644 (file)
index 0000000..6c39866
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * @defgroup    modes_ctr crypt_modes_ctr.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       modes句柄类型
+ */
+
+#ifndef CRYPT_MODES_CTR_H
+#define CRYPT_MODES_CTR_H
+
+#ifndef HITLS_CRYPTO_NO_CTR
+#include "crypt_modes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+ * @brief CTR模式加密
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_CTR_Crypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ecb.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ecb.h
new file mode 100644 (file)
index 0000000..b7e0ef4
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * @defgroup    modes_ecb crypt_modes_ecb.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       modes句柄类型
+ */
+
+#ifndef CRYPT_MODES_ECB_H
+#define CRYPT_MODES_ECB_H
+
+#ifndef HITLS_CRYPTO_NO_ECB
+#include "crypt_modes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/**
+ * @brief ECB模式加密
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_ECB_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief ECB模式解密
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param in [IN] 待加密数据
+ * @param out [OUT] 已加密数据
+ * @param len [IN] 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_ECB_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief ECB模式下,对mode进行参数操作
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param opt [IN] 操作
+ * @param val [IN/OUT] 参数,可以是入参也可以是出参
+ * @param len [IN] 参数的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_ECB_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+/**
+ * @brief 原语SM4 ECB模式加密块
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t SM4_ECB_EncryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief 原语SM4 ECB模式解密块
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t SM4_ECB_DecryptBlock(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief 使用memset_s清理信息,仅供非认证算法使用
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ */
+void MODES_SM4_ECB_Clean(MODE_CipherCtx *ctx);
+
+/**
+ * @brief SM4 ECB模式下,对mode进行参数操作
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param opt [IN] 操作
+ * @param val [IN/OUT] 参数,可以是入参也可以是出参
+ * @param len [IN] 参数的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_SM4_ECB_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_gcm.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_gcm.h
new file mode 100644 (file)
index 0000000..87922e7
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_modes_gcm.h
+ * Description: gcm模式
+ * Author: linkaixin
+ * Create: 2022-05-13
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-05-13  linkaixin        gcm模式头文件
+ */
+
+#ifndef CRYPT_MODES_GCM_H
+#define CRYPT_MODES_GCM_H
+
+#ifndef HITLS_CRYPTO_NO_GCM
+#include <stdint.h>
+#include "crypt_local_types.h"
+#include "crypt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define GCM_BLOCKSIZE 16
+
+typedef struct {
+    uint64_t h;
+    uint64_t l;
+} MODES_GCM_GF128;
+
+typedef struct {
+    // 该信息可一次设置,多次使用
+    uint8_t iv[GCM_BLOCKSIZE];      // 经过处理后的iv信息,长度为16字节
+    uint8_t ghash[GCM_BLOCKSIZE];   // tag计算的中间数据
+    MODES_GCM_GF128 hTable[16]; // 窗口使用4bit 需要预计算2^4(16)个表项
+    void *ciphCtx; // 方法用的句柄
+    const EAL_CipherMethod *ciphMeth; // 算法方法
+    /**
+     * tagLen may be any one of the following five values: 128, 120, 112, 104, or 96
+     * For certain applications, tagLen may be 64 or 32
+     */
+    uint8_t tagLen;
+    uint32_t cryptCnt; // 秘钥设置可用的加密次数
+
+    // 加解密中间信息,生命周期为一次加密操作,在每次加解密操作需要重置
+    uint8_t last[GCM_BLOCKSIZE];    // ctr mode last
+    uint8_t remCt[GCM_BLOCKSIZE];     // 剩余密文
+    uint8_t ek0[GCM_BLOCKSIZE];     // ek0
+    uint64_t plaintextLen;  // use for calc tag
+    uint32_t aadLen;        // use for calc tag
+    uint32_t lastLen;       // ctr mode lastLen
+} MODES_GCM_Ctx;
+
+int32_t MODES_GCM_InitCtx(MODES_GCM_Ctx *ctx, const struct EAL_CipherMethodLocal *m);
+
+void MODES_GCM_DeinitCtx(MODES_GCM_Ctx *ctx);
+
+void MODES_GCM_Clean(MODES_GCM_Ctx *ctx);
+
+int32_t MODES_GCM_Ctrl(MODES_GCM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+int32_t MODES_GCM_SetKey(MODES_GCM_Ctx *ctx, const uint8_t *ciphCtx, uint32_t len);
+
+int32_t MODES_GCM_Encrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+int32_t MODES_GCM_Decrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+int32_t AES_GCM_EncryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+int32_t AES_GCM_DecryptBlock(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ofb.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_ofb.h
new file mode 100644 (file)
index 0000000..4ba745d
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_modes_ofb.h
+ * Description: ofb模式
+ * Author: chenrenhao
+ * Create: 2022-10-08
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-10-08  chenrenhao       ofb模式头文件
+ */
+
+#ifndef CRYPT_MODES_OFB_H
+#define CRYPT_MODES_OFB_H
+
+#ifndef HITLS_CRYPTO_NO_OFB
+#include "crypt_modes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+
+/**
+ * @brief OFB模式加/解密,可对任意字节长度进行加/解密
+ *
+ * @param [IN] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_OFB_Crypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_xts.h b/code/sdk/open_source/HiTLS/crypto/modes/include/crypt_modes_xts.h
new file mode 100644 (file)
index 0000000..d491021
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * @defgroup    modes_xts crypt_modes_xts.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       modes句柄类型
+ */
+
+#ifndef CRYPT_MODES_XTS_H
+#define CRYPT_MODES_XTS_H
+
+#ifndef HITLS_CRYPTO_NO_XTS
+#include "crypt_modes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+/**
+ * @brief 模块初始化,将加解密算法的method注册到模块中,并且开辟算法的上下文
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param method [IN] 对称加解密的方法
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_XTS_InitCtx(MODE_CipherCtx *ctx, EAL_CipherMethod *method);
+/**
+ * @brief XTS模式设置加密密钥
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param key [IN] 加密密钥
+ * @param len [IN] 加密密钥长度,只支持32(256bit) 和 64(512bit)
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_XTS_SetEncryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @brief XTS模式设置解密密钥
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param key [IN] 解密密钥
+ * @param len [IN] 解密密钥长度,只支持32(256bit) 和 64(512bit)
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_XTS_SetDecryptKey(MODE_CipherCtx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @brief XTS模式加密, 当len不是16的整数倍时,不能再调用MODE_XTS_Encrypt进行新数据的加密
+ *
+ * @param [IN/OUT] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] len 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_XTS_Encrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief XTS模式解密,当len不是16的整数倍时,本轮解密结束
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param in [IN] 待加密数据
+ * @param out [OUT] 已加密数据
+ * @param len [IN] 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_XTS_Decrypt(MODE_CipherCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len);
+
+/**
+ * @brief 对xts mode进行参数操作
+ *
+ * @param ctx [IN/OUT] 模式句柄
+ * @param opt [IN] 操作
+ * @param val [IN/OUT] 参数,可以是入参也可以是出参
+ * @param len [IN] 参数的长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t MODE_XTS_Ctrl(MODE_CipherCtx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/src/asm_aes_gcm.h b/code/sdk/open_source/HiTLS/crypto/modes/src/asm_aes_gcm.h
new file mode 100644 (file)
index 0000000..4836124
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file asm_aes_gcm.h
+ * Description: aes_gcm 汇编优化头文件
+ * Author: haoruixiang
+ * Create: 2022-06-27
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-06-27  haoruixiang        aes_gcm 汇编优化头文件
+ */
+#ifndef ASM_AES_GCM_H
+#define ASM_AES_GCM_H
+ 
+#include "crypt_modes_gcm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+void AES_GCM_EncryptBlockAsm(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, void *key);
+void AES_GCM_DecryptBlockAsm(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, void *key);
+void AES_GCM_Encrypt16BlockAsm(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, void *key);
+void AES_GCM_Decrypt16BlockAsm(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, void *key);
+void AES_GCM_ClearAsm(void);
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/src/asm_sm4.h b/code/sdk/open_source/HiTLS/crypto/modes/src/asm_sm4.h
new file mode 100644 (file)
index 0000000..15fd45f
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file asm_sm4.h
+ * Description: 汇编SM4算法头文件
+ * Author: panxinrong
+ * Create: 2022-08-16
+ */
+
+#ifndef ASM_SM4_H
+#define ASM_SM4_H
+
+#include <stdint.h>
+#include "crypt_types.h"
+#include "crypt_modes_cbc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cpluscplus */
+
+/**
+ * @brief SM4 cbc设置加解密秘钥
+ *
+ * @param [IN] ctx sm4上下文
+ * @param [IN] key 秘钥
+ * @param [IN] keyLen 秘钥长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t CRYPT_SM4_ASM_SetKey(CRYPT_SM4_ASM_Ctx *ctx, const uint8_t *key, uint32_t keyLen);
+
+/**
+ * @brief SM4上下文清零
+ *
+ * @param [IN] ctx sm4上下文
+ */
+void CRYPT_SM4_ASM_Clean(CRYPT_SM4_ASM_Ctx *ctx);
+
+/**
+ * @brief sm4 CBC模式加密,使用前需要用Ctrl接口设置iv,数据长度必须是16整数倍
+ *
+ * @param [IN] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] length 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t CRYPT_SM4_CbcDecrypt(CRYPT_SM4_ASM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length);
+
+/**
+ * @brief sm4 CBC模式解密,使用前需要用Ctrl接口设置iv,数据长度必须是16整数倍
+ *
+ * @param [IN] ctx 模式句柄
+ * @param [IN] in 待解密数据
+ * @param [OUT] out 已解密数据
+ * @param [IN] length 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t CRYPT_SM4_CbcEncrypt(CRYPT_SM4_ASM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length);
+
+/**
+ * @brief sm4 CBC模式设置获取iv接口
+ *
+ * @param [IN] ctx 模式句柄
+ * @param [IN] opt 模式,支持CRYPT_CTRL_SET_IV和CRYPT_CTRL_GET_IV
+ * @param [IN/OUT] 设置的iv/获取的iv
+ * @param [IN] len iv长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t CRYPT_SM4_Ctrl(CRYPT_SM4_ASM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len);
+
+/**
+ * @brief sm4 ECB模式加密,数据长度必须是16整数倍
+ *
+ * @param [IN] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] length 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t CRYPT_SM4_EcbEncrypt(CRYPT_SM4_ASM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length);
+
+/**
+ * @brief sm4 ECB模式解密,数据长度必须是16整数倍
+ *
+ * @param [IN] ctx 模式句柄
+ * @param [IN] in 待加密数据
+ * @param [OUT] out 已加密数据
+ * @param [IN] length 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         失败返回:其他错误码
+ */
+int32_t CRYPT_SM4_EcbDecrypt(CRYPT_SM4_ASM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t length);
+
+void Sm4CbcDecrypt_80(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_96(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_112(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_128(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_144(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_160(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_176(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_192(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecrypt_64(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcDecryptConsTime_64(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcEncrypt(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4CbcEncryptConsTime(uint32_t *key, uint8_t *iv, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4SetKey(const uint8_t *key, uint32_t rk[32]);
+
+void Sm4Decrypt(uint32_t *key, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4DecryptConsTime(uint32_t *key, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4Encrypt(uint32_t *key, const uint8_t *in, uint8_t *out, uint32_t len);
+
+void Sm4EncryptConsTime(uint32_t *key, const uint8_t *in, uint8_t *out, uint32_t len);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cpluscplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/src/modes_gcm.c b/code/sdk/open_source/HiTLS/crypto/modes/src/modes_gcm.c
new file mode 100644 (file)
index 0000000..01afa5b
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file gcm.c
+ * Description: gcm模式
+ * Author: linkaixin
+ * Create: 2022-05-13
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-05-13  linkaixin        gcm模式
+ */
+#ifndef HITLS_CRYPTO_NO_GCM
+#include <stdint.h>
+#include "securec.h"
+#include "crypt_utils.h"
+#include "crypt_errno.h"
+#include "sal_mem.h"
+#include "bsl_err_internal.h"
+#include "modes_local.h"
+#include "crypt_modes_gcm.h"
+
+/**
+ * NIST_800-38D-5.2
+ * len(P) ≤ 2^39-256 (bit)
+ * 等价于 len(P) ≤ 2^36 - 32 (byte)
+ */
+#define GCM_MAX_COMBINED_LENGTH     (((uint64_t)1 << 36) - 32)
+/**
+ * NIST_800-38D-8.3
+ * The total number of invocations of the authenticated encryption function shall not exceed
+ * 2^32, including all IV lengths and all instances of the authenticated encryption function with
+ * the given ciphCtx
+ */
+#define GCM_MAX_INVOCATIONS_TIMES   ((uint32_t)(-1))
+
+#define GCM_BLOCK_MASK (0xfffffff0)
+
+int32_t MODES_GCM_InitCtx(MODES_GCM_Ctx *ctx, const struct EAL_CipherMethodLocal *m)
+{
+    if (ctx == NULL || m == NULL) {
+        return CRYPT_NULL_INPUT;
+    }
+    (void)memset_s(ctx, sizeof(MODES_GCM_Ctx), 0, sizeof(MODES_GCM_Ctx));
+    ctx->ciphMeth = m;
+    ctx->ciphCtx = SAL_MALLOC(m->ctxSize);
+    if (ctx->ciphCtx == NULL) {
+        return CRYPT_MEM_ALLOC_FAIL;
+    }
+    return CRYPT_SUCCESS;
+}
+
+void MODES_GCM_DeinitCtx(MODES_GCM_Ctx *ctx)
+{
+    if (ctx == NULL) {
+        return;
+    }
+    (void)SAL_CleanseData(ctx->ciphCtx, ctx->ciphMeth->ctxSize);
+    SAL_FREE(ctx->ciphCtx);
+    (void)SAL_CleanseData(ctx, sizeof(MODES_GCM_Ctx));
+}
+
+void MODES_GCM_Clean(MODES_GCM_Ctx *ctx)
+{
+    if (ctx == NULL) {
+        return;
+    }
+    void *ciphCtx = ctx->ciphCtx;
+    const EAL_CipherMethod *ciphMeth = ctx->ciphMeth;
+    SAL_CleanseData((void *)(ciphCtx), ciphMeth->ctxSize);
+    SAL_CleanseData((void *)(ctx), sizeof(MODES_GCM_Ctx));
+    ctx->ciphCtx = ciphCtx;
+    ctx->ciphMeth = ciphMeth;
+}
+
+int32_t MODES_GCM_SetKey(MODES_GCM_Ctx *ctx, const uint8_t *ciphCtx, uint32_t len)
+{
+    if (ctx == NULL) {
+        return CRYPT_NULL_INPUT;
+    }
+    uint8_t gcmKey[GCM_BLOCKSIZE] = { 0 };
+    MODES_GCM_Clean(ctx);
+    int32_t ret = ctx->ciphMeth->setEncryptKey(ctx->ciphCtx, ciphCtx, len);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+    ret = ctx->ciphMeth->encrypt(ctx->ciphCtx, gcmKey, gcmKey, GCM_BLOCKSIZE);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+    GcmTableGen4bit(gcmKey, ctx->hTable);
+    ctx->tagLen = 16; // 默认tag长度为128bit 即16字节
+    SAL_CleanseData(gcmKey, sizeof(gcmKey));
+    return CRYPT_SUCCESS;
+}
+
+// 更新使用次数
+static int32_t CheckUseCnt(const MODES_GCM_Ctx *ctx)
+{
+    // 128, 120, 112, 104, or 96 即 12 byte - 16 byte
+    if (ctx->cryptCnt == GCM_MAX_INVOCATIONS_TIMES) {
+        return CRYPT_MODES_KEYUSE_TOOMANY_TIME;
+    }
+    return CRYPT_SUCCESS;
+}
+
+/**
+ * NIST_800-38D-5.2
+ * 1 ≤ len(IV) ≤ 2^64 - 1 (bit)
+ * 当前限制其不超过 2^32 - 1 byte
+ */
+static int32_t SetIv(MODES_GCM_Ctx *ctx, const uint8_t *iv, uint32_t ivLen)
+{
+    if (iv == NULL || ivLen == 0) {
+        return CRYPT_NULL_INPUT;
+    }
+    int32_t ret = CheckUseCnt(ctx); // 检查使用次数
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+    uint32_t i;
+    uint64_t len = (uint64_t)ivLen;
+    // when ivLen == 0, do reinit, no need to refersh iv
+    if (len == 12) { // len(IV ) = 96bit = 12byte
+        const uint8_t ivPad[4] = {0x00, 0x00, 0x00, 0x01};
+        /* Y0 = IV || 0^31 || 1  if len(IV ) = 96 = 12byte */
+        (void)memcpy_s(ctx->iv, GCM_BLOCKSIZE, iv, 12);
+        (void)memcpy_s(ctx->iv + 12, GCM_BLOCKSIZE - 12, ivPad, sizeof(ivPad)); // 补充后4bit(base = 12)
+    } else {
+        /* Y0 = GHASH(H, {}, IV ) otherwise */
+        (void)memset_s(ctx->iv, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE);
+        const uint8_t *off = iv;
+        uint32_t blockLen = ivLen & GCM_BLOCK_MASK;
+        uint32_t lastLen = ivLen - blockLen;
+        uint8_t tmp[GCM_BLOCKSIZE] = {0};
+        if (blockLen > 0) {
+            GcmHashMultiBlock(ctx->iv, ctx->hTable, off, blockLen);
+            off += blockLen;
+        }
+        if (lastLen > 0) {
+            for (i = 0; i < lastLen; i++) {
+                tmp[i] = off[i];
+            }
+            GcmHashMultiBlock(ctx->iv, ctx->hTable, tmp, GCM_BLOCKSIZE);
+        }
+        len = (uint64_t)ivLen << 3; // bitLen = byteLen << 3
+        (void)SAL_CleanseData(tmp, GCM_BLOCKSIZE);
+        Uint64ToBeBytes(len, tmp + 8); // 后8字节存放iv长度
+        GcmHashMultiBlock(ctx->iv, ctx->hTable, tmp, GCM_BLOCKSIZE);
+    }
+    /**
+     * NIST_800-38D-7.1
+     * GCTR(J0)
+     */
+    ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->ek0, GCM_BLOCKSIZE);
+
+    /**
+     * NIST_800-38D-7.1
+     * INC32
+     * the 32-bit incrementing function is applied to the pre-counter block
+     * to produce the initial counter block for an invocation of the GCTR
+     * function on the plaintext
+     */
+    uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); // 偏移12字节,取最后四字节
+    ctr++;
+    PUT_UINT32_BE(ctr, ctx->iv, 12); // 偏移12字节写回
+
+    // 重置信息
+    (void)memset_s(ctx->ghash, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE);
+    ctx->aadLen = 0;
+    ctx->lastLen = 0;
+    ctx->plaintextLen = 0;
+
+    // 敏感信息清除
+    SAL_CleanseData(&ctr, sizeof(uint32_t));
+    return CRYPT_SUCCESS;
+}
+
+/**
+ * NIST_800-38D-5.2
+ * len(AAD) ≤ 2^64 - 1 (bit)
+ * 当前限制其不超过 2^32 - 1 byte
+ */
+static int32_t SetAad(MODES_GCM_Ctx *ctx, const uint8_t *aad, uint32_t aadLen)
+{
+    if (aad == NULL && aadLen != 0) {
+        return CRYPT_NULL_INPUT;
+    }
+    const uint8_t *off = aad;
+    uint32_t i;
+    if (ctx->aadLen != 0) { // aad已设置
+        BSL_ERR_PUSH_ERROR(CRYPT_MODES_AAD_REPEAT_SET_ERROR);
+        return CRYPT_MODES_AAD_REPEAT_SET_ERROR;
+    }
+    uint32_t blockLen = aadLen & GCM_BLOCK_MASK;
+    uint32_t lastLen = aadLen - blockLen;
+    if (blockLen > 0) {
+        GcmHashMultiBlock(ctx->ghash, ctx->hTable, off, blockLen);
+        off += blockLen;
+    }
+    if (lastLen > 0) {
+        uint8_t temp[GCM_BLOCKSIZE] = {0};
+        for (i = 0; i < lastLen; i++) {
+            temp[i] = off[i];
+        }
+        GcmHashMultiBlock(ctx->ghash, ctx->hTable, temp, GCM_BLOCKSIZE);
+    }
+    ctx->aadLen = aadLen;
+    return CRYPT_SUCCESS;
+}
+
+// 判断加密长度时候溢出,并刷新已加密长度信息
+int32_t CryptLenCheckAndRefresh(MODES_GCM_Ctx *ctx, uint32_t len)
+{
+    // len只有32bit 结合该长度限制,该计算不会产生溢出
+    uint64_t plaintextLen = ctx->plaintextLen + len;
+    if (plaintextLen > GCM_MAX_COMBINED_LENGTH) {
+        BSL_ERR_PUSH_ERROR(CRYPT_MODES_CRYPTLEN_OVERFLOW);
+        return CRYPT_MODES_CRYPTLEN_OVERFLOW;
+    }
+    ctx->plaintextLen = plaintextLen;
+    return CRYPT_SUCCESS;
+}
+
+typedef struct {
+    const uint8_t *in;
+    uint8_t *out;
+    const uint8_t *ctr;
+    uint8_t *ct;
+} XorCryptData;
+
+static void XorInEncrypt(XorCryptData *data, uint32_t len)
+{
+    uint32_t i;
+    for (i = 0; i < len; i++) {
+        data->out[i] = data->in[i] ^ data->ctr[i];
+        data->ct[i] = data->out[i];
+    }
+}
+
+static void XorInDecrypt(XorCryptData *data, uint32_t len)
+{
+    uint32_t i;
+    for (i = 0; i < len; i++) {
+        data->ct[i] = data->in[i];
+        data->out[i] = data->in[i] ^ data->ctr[i];
+    }
+}
+
+// 处理上一次update剩余数据
+uint32_t LastHandle(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
+{
+    uint32_t lastLen = 0;
+    if (ctx->lastLen > 0) {
+        XorCryptData data;
+        lastLen = (ctx->lastLen < len) ? ctx->lastLen : len;
+        data.in = in;
+        data.out = out;
+        data.ctr = &(ctx->last[GCM_BLOCKSIZE - ctx->lastLen]);
+        data.ct = &(ctx->remCt[GCM_BLOCKSIZE - ctx->lastLen]);
+        if (enc) { // ctx->lastLen 必然小于 GCM_BLOCKSIZE
+            XorInEncrypt(&data, lastLen);
+        } else {
+            XorInDecrypt(&data, lastLen);
+        }
+        // 刷新剩余长度
+        ctx->lastLen -= lastLen;
+        if (ctx->lastLen == 0) {
+            GcmHashMultiBlock(ctx->ghash, ctx->hTable, ctx->remCt, GCM_BLOCKSIZE);
+        }
+    }
+    return lastLen;
+}
+
+static void GcmMultiBlockCrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
+{
+    uint32_t blockLen = len;
+    const uint8_t *dataIn = in;
+    uint8_t *dataOut = out;
+    uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); // 计数信息,iv的最后32位,需偏移12字节(16 - 4 = 12)
+    if (enc == false) {
+        GcmHashMultiBlock(ctx->ghash, ctx->hTable, in, len);
+    }
+    while (blockLen > 0) {
+        ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->last, GCM_BLOCKSIZE);
+        DATA64_XOR(dataIn, ctx->last, dataOut, GCM_BLOCKSIZE);
+        /**
+        * NIST_800-38D-7.1
+        * INC32
+        */
+        ctr++;
+        PUT_UINT32_BE(ctr, ctx->iv, 12); // 偏移12字节,取最后四字节
+        // 刷新剩余长度
+        blockLen -= GCM_BLOCKSIZE;
+        // 偏移
+        dataIn += GCM_BLOCKSIZE;
+        dataOut += GCM_BLOCKSIZE;
+    }
+    if (enc) {
+        GcmHashMultiBlock(ctx->ghash, ctx->hTable, out, len);
+    }
+    // 敏感信息清除
+    SAL_CleanseData(&ctr, sizeof(uint32_t));
+}
+
+// enc标识为true时为加密操作,false为解密操作
+static int32_t MODES_GCM_Crypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
+{
+    if (ctx == NULL || in == NULL || out == NULL || len == 0) {
+        return CRYPT_NULL_INPUT;
+    }
+    int32_t ret = CryptLenCheckAndRefresh(ctx, len);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+    uint32_t lastLen = LastHandle(ctx, in, out, len, enc);
+    // 数据处理完毕,提前退出
+    if (lastLen == len) {
+        return CRYPT_SUCCESS;
+    }
+
+    XorCryptData data;
+    data.in = in + lastLen;
+    data.out = out + lastLen;
+    data.ctr = ctx->last;
+    data.ct = ctx->remCt;
+
+    uint32_t multiBlockLen = (len - lastLen) & GCM_BLOCK_MASK;
+    if (multiBlockLen > 0) {
+        GcmMultiBlockCrypt(ctx, data.in, data.out, multiBlockLen, enc);
+        data.in += multiBlockLen;
+        data.out += multiBlockLen;
+    }
+    uint32_t remLen = len - lastLen - multiBlockLen;
+    if (remLen > 0) {
+        uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); // 计数信息,iv的最后32位,需偏移12字节(16 - 4 = 12)
+        (void)ctx->ciphMeth->encrypt(ctx->ciphCtx, ctx->iv, ctx->last, GCM_BLOCKSIZE);
+        if (enc) {
+            XorInEncrypt(&data, remLen);
+        } else {
+            XorInDecrypt(&data, remLen);
+        }
+        /**
+         * NIST_800-38D-7.1
+         * INC32
+         */
+        ctr++;
+        PUT_UINT32_BE(ctr, ctx->iv, 12); // 偏移12字节,取最后四字节
+        // 敏感信息清除
+        SAL_CleanseData(&ctr, sizeof(uint32_t));
+    }
+    ctx->lastLen = (remLen > 0) ? (GCM_BLOCKSIZE - remLen) : 0;
+
+    return CRYPT_SUCCESS;
+}
+
+static void GcmPad(MODES_GCM_Ctx *ctx)
+{
+    // S = GHASHH (A || 0v || C || 0u || [len(A)]64 || [len(C)]64).
+    if (ctx->lastLen != 0) {
+        uint32_t offset = GCM_BLOCKSIZE - ctx->lastLen;
+        (void)memset_s(ctx->remCt + offset, GCM_BLOCKSIZE - offset, 0, ctx->lastLen);
+        GcmHashMultiBlock(ctx->ghash, ctx->hTable, ctx->remCt, GCM_BLOCKSIZE);
+    }
+    uint64_t aadLen = (uint64_t)(ctx->aadLen) << 3; // bitLen = byteLen << 3
+    uint64_t plaintextLen = ctx->plaintextLen << 3; // bitLen = byteLen << 3
+    uint8_t padBuf[GCM_BLOCKSIZE];
+    Uint64ToBeBytes(aadLen, padBuf);
+    Uint64ToBeBytes(plaintextLen, padBuf + 8); // 后64bit(8byte)为密文长度
+
+    GcmHashMultiBlock(ctx->ghash, ctx->hTable, padBuf, GCM_BLOCKSIZE);
+}
+
+static int32_t SetTagLen(MODES_GCM_Ctx *ctx, const uint8_t *val, uint32_t len)
+{
+    if (val == NULL) {
+        return CRYPT_NULL_INPUT;
+    }
+    if (len != sizeof(uint32_t)) {
+        BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR);
+        return CRYPT_MODES_CTRL_TAGLEN_ERROR;
+    }
+    /**
+     * NIST_800-38D-5.2.1.2
+     * The bit length of the tag, denoted t, is a security parameter, as discussed in Appendix B.
+     * In general, t may be any one of the following five values: 128, 120, 112, 104, or 96. For certain
+     * applications, t may be 64 or 32; guidance for the use of these two tag lengths, including
+     * requirements on the length of the input data and the lifetime of the ciphCtx in these cases,
+     * is given in Appendix C
+     */
+    uint32_t tagLen = *((const uint32_t *)val);
+    // 32bit 即 4 byte 64bit 即 8 byte 128, 120, 112, 104, or 96 即 12 byte - 16 byte
+    if (tagLen == 4 || tagLen == 8 || (tagLen >= 12 && tagLen <= 16)) {
+        ctx->tagLen = (uint8_t)tagLen;
+        return CRYPT_SUCCESS;
+    }
+    BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR);
+    return CRYPT_MODES_CTRL_TAGLEN_ERROR;
+}
+
+static int32_t GetTag(MODES_GCM_Ctx *ctx, uint8_t *val, uint32_t len)
+{
+    if (val == NULL) {
+        return CRYPT_NULL_INPUT;
+    }
+    if (len != ctx->tagLen) {
+        BSL_ERR_PUSH_ERROR(CRYPT_MODES_TAGLEN_ERROR);
+        return CRYPT_MODES_TAGLEN_ERROR;
+    }
+    ctx->cryptCnt++; // 加解密流程结束 秘钥使用次数+1
+    GcmPad(ctx);
+    uint32_t i;
+    for (i = 0; i < len; i++) {
+        val[i] = ctx->ghash[i] ^ ctx->ek0[i];
+    }
+    return CRYPT_SUCCESS;
+}
+
+int32_t MODES_GCM_Encrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
+{
+    return MODES_GCM_Crypt(ctx, in, out, len, true);
+}
+
+int32_t MODES_GCM_Decrypt(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
+{
+    return MODES_GCM_Crypt(ctx, in, out, len, false);
+}
+
+int32_t MODES_GCM_Ctrl(MODES_GCM_Ctx *ctx, CRYPT_CipherCtrl opt, void *val, uint32_t len)
+{
+    if (ctx == NULL) {
+        return CRYPT_NULL_INPUT;
+    }
+    switch (opt) {
+        case CRYPT_CTRL_SET_IV:
+            return SetIv(ctx, val, len);
+        case CRYPT_CTRL_SET_TAGLEN:
+            return SetTagLen(ctx, val, len);
+        case CRYPT_CTRL_SET_AAD:
+            return SetAad(ctx, val, len);
+        case CRYPT_CTRL_GET_TAG:
+            return GetTag(ctx, val, len);
+        default:
+            return CRYPT_MODES_CTRL_TYPE_ERROR;
+    }
+}
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/src/modes_local.h b/code/sdk/open_source/HiTLS/crypto/modes/src/modes_local.h
new file mode 100644 (file)
index 0000000..5cd37e8
--- /dev/null
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file modes_local.h
+ * Description: modes 内部处理函数
+ * Author: haoruixiang
+ * Create: 2022-6-26
+ * Modification History
+ *  DATE        NAME                         DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-06-26  haoruixiang                chacha20 内部处理函数
+ */
+#ifndef MODES_LOCAL_H
+#define MODES_LOCAL_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "crypt_modes_gcm.h"
+
+void GcmTableGen4bit(uint8_t key[GCM_BLOCKSIZE], MODES_GCM_GF128 hTable[16]);
+
+void GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16], const uint8_t *in, uint32_t inLen);
+
+int32_t CryptLenCheckAndRefresh(MODES_GCM_Ctx *ctx, uint32_t len);
+
+uint32_t LastHandle(MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc);
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/src/noasm_ghash.c b/code/sdk/open_source/HiTLS/crypto/modes/src/noasm_ghash.c
new file mode 100644 (file)
index 0000000..d731d88
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file noasm_ghash.c
+ * Description: ghash算法实现, C实现,对应有相应的汇编加速实现
+ * Author: linkaixin
+ * Create: 2022-05-13
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-05-13  linkaixin        gcm模式
+ */
+#ifndef HITLS_CRYPTO_NO_GCM
+#include "modes_local.h"
+#include "crypt_utils.h"
+#include "sal_mem.h"
+
+/* table[i] = (P^4)*i, P = 0x4000000000000000, i = 0...16 */
+static const uint64_t TABLE_P4_BITS[16] = {
+    0x0000000000000000, 0x1c20000000000000, 0x3840000000000000, 0x2460000000000000,
+    0x7080000000000000, 0x6ca0000000000000, 0x48c0000000000000, 0x54e0000000000000,
+    0xe100000000000000, 0xfd20000000000000, 0xd940000000000000, 0xc560000000000000,
+    0x9180000000000000, 0x8da0000000000000, 0xa9c0000000000000, 0xb5e0000000000000
+};
+
+// 计算 n*H n为0 .... 16
+void GcmTableGen4bit(uint8_t key[GCM_BLOCKSIZE], MODES_GCM_GF128 hTable[16])
+{
+    uint32_t i;
+    uint32_t j;
+    const uint64_t r = 0xE100000000000000;
+    hTable[0].h = 0;
+    hTable[0].l = 0;
+    hTable[8].h = Uint64FromBeBytes(key); // 表的中间项(16 / 2 == 8)为H本身
+    hTable[8].l = Uint64FromBeBytes(key + sizeof(uint64_t)); // 表的中间项(16 / 2 == 8)为H本身
+
+    for (i = 4; i > 0; i >>= 1) { // 4bit表,先计算2^n项的值
+        hTable[i].l = (hTable[ i * 2].h << 63) | (hTable[ i * 2].l >> 1); // 循环右移1bit h的高1位于l的低63位结合
+        hTable[i].h = (hTable[ i * 2].h >> 1) ^ ((hTable[ i * 2].l & 1) * r); // 2^n项的值
+    }
+    for (i = 1; i < 16; i <<= 1) { // 16个表项
+        for (j = 1; j < i; j++) {
+            hTable[i + j].h = hTable[i].h ^ hTable[j].h;
+            hTable[i + j].l = hTable[i].l ^ hTable[j].l;
+        }
+    }
+}
+
+// 计算 t = t * H
+void GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16], const uint8_t *in, uint32_t inLen)
+{
+    MODES_GCM_GF128 x;
+    uint8_t r;
+    uint8_t h, l, tag;   // 密文信息,摘要信息,非敏感信息
+    const uint8_t *tempIn = in;
+    for (uint32_t i = 0; i < inLen; i += GCM_BLOCKSIZE) {
+        uint8_t cnt = GCM_BLOCKSIZE - 1;
+        x.h = 0;
+        x.l = 0;
+        while (1) {
+            tag = t[cnt] ^ tempIn[cnt];
+
+            l = tag & 0xf;
+            h = (tag >> 4) & 0xf; // 高4bit
+            x.h ^= hTable[l].h;
+            x.l ^= hTable[l].l;
+
+            r = (x.l & 0xf);
+            x.l  = (x.h << 60) | (x.l >> 4); // 循环右移4bit h的高4位于l的低60位结合
+            x.h  = (x.h >> 4); // 循环右移4bit
+            x.h ^= TABLE_P4_BITS[r];
+
+            x.h ^= hTable[h].h;
+            x.l ^= hTable[h].l;
+            if (cnt == 0) {
+                break;
+            }
+            cnt--;
+            r = (x.l & 0xf);
+            x.l  = (x.h << 60) | (x.l >> 4); // 循环右移4bit h的高4位于l的低60位结合
+            x.h  = (x.h >> 4); // 循环右移4bit
+            x.h ^= TABLE_P4_BITS[r];
+        }
+        tempIn += GCM_BLOCKSIZE;
+        Uint64ToBeBytes(x.h, t);        // 高8位
+        Uint64ToBeBytes(x.l, t + 8);    // 低8位
+    }
+    // 敏感信息清除
+    SAL_CleanseData(&x, sizeof(MODES_GCM_GF128));
+    SAL_CleanseData(&r, sizeof(uint8_t));
+}
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/modes/src/poly1305_core.h b/code/sdk/open_source/HiTLS/crypto/modes/src/poly1305_core.h
new file mode 100644 (file)
index 0000000..a1542c4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file poly1305_core.h
+ * Description: poly1305内部头文件
+ * Author: pandeguang
+ * Create: 2022-06-27
+ * Modification History
+ *  DATE        NAME             DESCRIPTION
+ *  --------------------------------------------------------------------------
+ *  2022-06-27  pandeguang      poly1305内部算法头文件
+ */
+#ifndef POLY1305_CORE_H
+#define POLY1305_CORE_H
+
+#include "crypt_modes_chacha20poly1305.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define POLY1305_BLOCKSIZE 16
+#define POLY1305_TAGSIZE   16
+#define POLY1305_KEYSIZE   32
+
+void Poly1305InitForAsm(Poly1305Ctx *ctx);
+uint32_t Poly1305Block(Poly1305Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint32_t padbit);
+void Poly1305Last(Poly1305Ctx *ctx, uint8_t mac[POLY1305_TAGSIZE]);
+void Poly1305CleanRegister(void);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/sha2/include/crypt_sha2.h b/code/sdk/open_source/HiTLS/crypto/sha2/include/crypt_sha2.h
new file mode 100644 (file)
index 0000000..8dc4679
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_sha2.h
+ * Description: SHA2自研算法头文件,源码引用于HICRYPTO组件自研SHA2算法
+ * Author: liushaoming
+ * Create: 2022-02-11
+ */
+
+#ifndef CRYPT_SHA2_H
+#define CRYPT_SHA2_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cpluscplus */
+
+
+/** @defgroup LLF SHA2 Low level function */
+
+#ifndef HITLS_CRYPTO_NO_SHA224
+/* SHA2-224 */
+#define CRYPT_SHA2_224_BLOCKSIZE  64
+#define CRYPT_SHA2_224_DIGESTSIZE 28
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA256
+/* SHA2-256 */
+#define CRYPT_SHA2_256_BLOCKSIZE  64
+#define CRYPT_SHA2_256_DIGESTSIZE 32
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA384
+/* SHA2-384 */
+#define CRYPT_SHA2_384_BLOCKSIZE  128
+#define CRYPT_SHA2_384_DIGESTSIZE 48
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA512
+/* SHA2-512 */
+#define CRYPT_SHA2_512_BLOCKSIZE  128
+#define CRYPT_SHA2_512_DIGESTSIZE 64
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA256
+/* SHA2 256 ctx */
+typedef struct {
+    uint32_t h[CRYPT_SHA2_256_DIGESTSIZE / sizeof(uint32_t)]; /* 256 bits for SHA256 state */
+    uint32_t block[CRYPT_SHA2_256_BLOCKSIZE / sizeof(uint32_t)]; /* 512 bits block cache */
+    uint32_t lNum, hNum;                                           /* input bits counter, max 2^64 bits */
+    uint32_t blocklen;                                     /* block length */
+    uint32_t outlen;                                       /* digest output length */
+    uint32_t errorCode; /* error Code */
+} CRYPT_SHA2_256_Ctx;
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA224
+/* SHA2 224 ctx */
+typedef CRYPT_SHA2_256_Ctx CRYPT_SHA2_224_Ctx;
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA512
+/* SHA2 512 ctx */
+typedef struct {
+    uint64_t h[CRYPT_SHA2_512_DIGESTSIZE / sizeof(uint64_t)];
+    uint8_t block[CRYPT_SHA2_512_BLOCKSIZE];
+    uint64_t lNum, hNum;
+    uint32_t num, mdlen;
+    uint32_t errorCode; /* error Code */
+} CRYPT_SHA2_512_Ctx;
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA384
+/* SHA2 384 ctx */
+typedef CRYPT_SHA2_512_Ctx CRYPT_SHA2_384_Ctx;
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA224
+/**
+ * @defgroup CRYPT_SHA2_224_Init
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx *ctx)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to initialize the SHA224 ctx for a digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_224_Init function initializes the ctx for a digest operation. This function must be called before
+ * CRYPT_SHA2_224_Update or CRYPT_SHA2_224_Final operations. This function will not allocate memory for any of the
+ * ctx variables. Instead the caller is expected to pass a ctx pointer pointing to a valid memory location
+ * (either locally or dynamically allocated).
+ *
+ * @param[in] ctx The sha224 ctx [N/A]
+ *
+ * @retval #CRYPT_SUCCESS ctx is initialized
+ * @retval #CRYPT_NULL_INPUT ctx is NULL
+ */
+int32_t CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx *ctx);
+
+/**
+ * @defgroup CRYPT_SHA2_224_Update
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx *ctx, const uint8_t *data, usize_t nbytes)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to perform sha224 digest operation on chunks of data.
+ *
+ * @par Description
+ * CRYPT_SHA2_224_Update function performs digest operation on chunks of data. This method of digesting is used when
+ * data is present in multiple buffers or not available all at once. CRYPT_SHA2_224_Init must have been called before
+ * calling this function.
+ *
+ * @param[in] ctx The sha224 ctx [N/A]
+ * @param[in] data The input data [N/A]
+ * @param[in] nbytes The input data length [N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow
+ */
+int32_t CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx *ctx, const uint8_t *data, uint32_t nbytes);
+
+/**
+ * @defgroup CRYPT_SHA2_224_Final
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx *ctx, uint8_t *digest, uint32_t *len)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to complete sha224 digest operation on remaining data, and is
+ * called at the end of digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_224_Final function completes digest operation on remaining data, and is called at the end of digest
+ * operation. CRYPT_SHA2_224_Init must have been called before calling this function. This function calculates the
+ * digest. The memory for digest must already have been allocated.
+ *
+ * @param[in] ctx The sha224 ctx [N/A]
+ * @param[out] digest The digest [N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow
+ * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough
+ */
+int32_t CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx *ctx, uint8_t *digest, uint32_t *len);
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA256
+/**
+ * @defgroup CRYPT_SHA2_256_Init
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to initialize the SHA256 ctx for a digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_256_Init function initializes the ctx for
+ * a digest operation. This function must be called before
+ * CRYPT_SHA2_256_Update or CRYPT_SHA2_256_Final operations. This function will not
+ * allocate memory for any of the ctx variables. Instead the caller is
+ * expected to pass a ctx pointer pointing to a valid memory location
+ * (either locally or dynamically allocated).
+ *
+ * @param[in] ctx The sha256 ctx [N/A]
+ *
+ * @retval #CRYPT_SUCCESS ctx is initialized
+ * @retval #CRYPT_NULL_INPUT ctx is NULL
+ */
+int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx);
+
+/**
+ * @defgroup CRYPT_SHA2_256_Update
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, usize_t nbytes)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to perform sha256 digest operation on chunks of data.
+ *
+ * @par Description
+ * CRYPT_SHA2_256_Update function performs digest operation on
+ * chunks of data. This method of digesting is used when data is
+ * present in multiple buffers or not available all at once.
+ * CRYPT_SHA2_256_Init must have been called before calling this
+ * function.
+ *
+ * @param[in] ctx The sha256 ctx [N/A]
+ * @param[in] data The input data [N/A]
+ * @param[in] nbytes The input data length [N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow
+ */
+int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes);
+
+/**
+ * @defgroup CRYPT_SHA2_256_Final
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *len)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to complete sha256 digest operation on remaining data, and is
+ * called at the end of digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_256_Final function completes digest operation on remaining data, and
+ * is called at the end of digest operation.
+ * CRYPT_SHA2_256_Init must have been called before calling this function. This
+ * function calculates the digest. The memory for digest must
+ * already have been allocated.
+ *
+ * @param[in] ctx The sha256 ctx [N/A]
+ * @param[out] digest The digest [N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_ERR_OVERFLOW input message is overflow
+ * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough
+ */
+int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *outlen);
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA384
+/**
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_384_Init(CRYPT_SHA2_384_Ctx *ctx)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to initialize the SHA384 ctx for a digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_384_Init function initializes the ctx for a digest operation. This function must be called before
+ * CRYPT_SHA2_384_Update or CRYPT_SHA2_384_Final operations. This function will not allocate memory for any of the
+ * ctx variables. Instead the caller is expected to pass a ctx pointer pointing to a valid memory location
+ * (either locally or dynamically allocated).
+ *
+ * @param[in,out] ctx The sha384 ctx [N/A]
+ *
+ * @retval #CRYPT_SUCCESS ctx is initialized
+ * @retval #CRYPT_NULL_INPUT ctx is NULL
+ */
+int32_t CRYPT_SHA2_384_Init(CRYPT_SHA2_384_Ctx *ctx);
+
+/**
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_384_Update(CRYPT_SHA2_384_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to perform sha384 digest operation on chunks of data.
+ *
+ * @par Description
+ * CRYPT_SHA2_384_Update function performs digest operation on chunks of data. This method of digesting is used when
+ * data is present in multiple buffers or not available all at once. CRYPT_SHA2_384_Init must have been called before
+ * calling this function.
+ *
+ * @param[in,out] ctx The sha384 ctx [N/A]
+ * @param[in] data The input data [N/A]
+ * @param[in] nbytes The input data length [N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow
+ * @retval #CRYPT_SECUREC_FAIL secure c function fail.
+ */
+int32_t CRYPT_SHA2_384_Update(CRYPT_SHA2_384_Ctx *ctx, const uint8_t *data, uint32_t nbytes);
+/**
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_384_Final(CRYPT_SHA2_384_Ctx *ctx, uint8_t *digest, uint32_t *len)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to complete sha384 digest operation on remaining data, and is
+ * called at the end of digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_384_Final function completes digest operation on remaining data, and is called at the end of digest
+ * operation. CRYPT_SHA2_384_Init must have been called before calling this function. This function calculates the
+ * digest. The memory for digest must already have been allocated.
+ *
+ * @param[in,out] ctx The sha384 ctx [N/A]
+ * @param[out] digest The digest [N/A]
+ * @param[in,out] len length of buffer[N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow
+ * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough
+ */
+int32_t CRYPT_SHA2_384_Final(CRYPT_SHA2_384_Ctx *ctx, uint8_t *digest, uint32_t *len);
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA512
+/**
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_512_Init(CRYPT_SHA2_512_Ctx *ctx)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to initialize the SHA512 ctx for a digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_512_Init function initializes the ctx for a digest operation. This function must be called before
+ * CRYPT_SHA2_512_Update or CRYPT_SHA2_512_Final operations. This function will not allocate memory for any of the
+ * ctx variable. Instead the caller is expected to pass a ctx pointer pointing to a valid memory location
+ * (either locally or dynamically allocated).
+ *
+ * @param[in,out] ctx The sha512 ctx [N/A]
+ *
+ * @retval #CRYPT_SUCCESS ctx is initialized
+ * @retval #CRYPT_NULL_INPUT ctx is NULL
+ */
+int32_t CRYPT_SHA2_512_Init(CRYPT_SHA2_512_Ctx *ctx);
+
+/**
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_512_Update(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, usize_t nbytes)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to perform sha512 digest operation on chunks of data.
+ *
+ * @par Description
+ * CRYPT_SHA2_512_Update function performs digest operation on chunks of data. This method of digesting is used when
+ * data is present in multiple buffers or not available all at once. CRYPT_SHA2_512_Init must have been called before
+ * calling this function.
+ *
+ * @param[in,out] ctx The sha512 ctx [N/A]
+ * @param[in] data The input data [N/A]
+ * @param[in] nbytes The input data length [N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow
+ * @retval #CRYPT_SECUREC_FAIL secure c function fail.
+ */
+int32_t CRYPT_SHA2_512_Update(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, uint32_t nbytes);
+
+/**
+ * @ingroup LLF Low Level Functions
+ * @par Prototype
+ * @code
+ * int32_t CRYPT_SHA2_512_Final(CRYPT_SHA2_512_Ctx *ctx, uint8_t *digest, uint32_t *len)
+ * @endcode
+ *
+ * @par Purpose
+ * This is used to complete sha512 digest operation on remaining data, and is called at the end of digest operation.
+ *
+ * @par Description
+ * CRYPT_SHA2_512_Final function completes digest operation on remaining data, and is called at the end of digest
+ * operation. CRYPT_SHA2_512_Init must have been called before calling this function. This function calculates the
+ * digest. The memory for digest must already have been allocated.
+ *
+ * @param[in,out] ctx The sha512 ctx [N/A]
+ * @param[out] digest The digest [N/A]
+ * @param[in,out] len length of buffer[N/A]
+ *
+ * @retval #CRYPT_SUCCESS If partial digest is calculated
+ * @retval #CRYPT_NULL_INPUT input arguments is NULL
+ * @retval #CRYPT_SHA2_INPUT_OVERFLOW input message is overflow
+ * @retval #CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH output buffer is not enough
+ */
+int32_t CRYPT_SHA2_512_Final(CRYPT_SHA2_512_Ctx *ctx, uint8_t *digest, uint32_t *len);
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA224
+/**
+ * @ingroup LLF Low Level Functions
+ *
+ * @brief SHA224 deinit function
+ *
+ * @param[in,out] ctx The SHA224 ctx
+ */
+void CRYPT_SHA2_224_Deinit(CRYPT_SHA2_224_Ctx *ctx);
+
+int32_t CRYPT_SHA2_224_CopyCtx(CRYPT_SHA2_224_Ctx *dst, CRYPT_SHA2_224_Ctx *src);
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA256
+/**
+ * @ingroup LLF Low Level Functions
+ *
+ * @brief SHA256 deinit function
+ *
+ * @param[in,out] ctx The SHA256 ctx
+ */
+void CRYPT_SHA2_256_Deinit(CRYPT_SHA2_256_Ctx *ctx);
+
+int32_t CRYPT_SHA2_256_CopyCtx(CRYPT_SHA2_256_Ctx *dst, CRYPT_SHA2_256_Ctx *src);
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA384
+/**
+ * @ingroup LLF Low Level Functions
+ *
+ * @brief SHA384 deinit function
+ *
+ * @param[in,out] ctx The SHA384 ctx
+ */
+void CRYPT_SHA2_384_Deinit(CRYPT_SHA2_384_Ctx *ctx);
+
+int32_t CRYPT_SHA2_384_CopyCtx(CRYPT_SHA2_384_Ctx *dst, CRYPT_SHA2_384_Ctx *src);
+#endif
+
+#ifndef HITLS_CRYPTO_NO_SHA512
+/**
+ * @ingroup LLF Low Level Functions
+ *
+ * @brief SHA512 deinit function
+ *
+ * @param[in,out] ctx The SHA512 ctx
+ */
+void CRYPT_SHA2_512_Deinit(CRYPT_SHA2_512_Ctx *ctx);
+
+int32_t CRYPT_SHA2_512_CopyCtx(CRYPT_SHA2_512_Ctx *dst, CRYPT_SHA2_512_Ctx *src);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/sha2/src/noasm_sha256.c b/code/sdk/open_source/HiTLS/crypto/sha2/src/noasm_sha256.c
new file mode 100644 (file)
index 0000000..55b54f3
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * @file noasm_sha256.c
+ * Description: SHA2自研算法实现,源码引用于HICRYPTO组件自研SHA2算法
+ */
+
+#ifndef HITLS_CRYPTO_NO_SHA256
+#include "crypt_sha2.h"
+#include "crypt_utils.h"
+#include "sha2_core.h"
+
+static const uint32_t K256[64] = {
+    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+    0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+    0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+    0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+    0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+    0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+    0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL,
+};
+#define ROTR32(x, n) (((x) << (32 - (n))) | ((x) >> (n))) // Assumes that x is uint32_t and 0 < n < 32
+
+#define S0(x) (ROTR32((x), 7) ^ ROTR32((x), 18) ^ ((x) >> 3))
+#define S1(x) (ROTR32((x), 17) ^ ROTR32((x), 19) ^ ((x) >> 10))
+
+#define R(w, t) \
+    (S1((w)[(t) -  2]) + (w)[(t) -  7] +    \
+     S0((w)[(t) - 15]) + (w)[(t) - 16])
+
+#define ROUND(a, b, c, d, e, f, g, h, i, k)                                                                   \
+    do {                                                                                                      \
+        /* constants: 6, 11, 25 */                                                                            \
+        (h) += (ROTR32((e), 6) ^ ROTR32((e), 11) ^ ROTR32((e), 25)) +                                         \
+            ((g) ^ ((e) & ((f) ^ (g)))) + (k) + (i);                                                          \
+        (d) += (h);                                                                                           \
+        /* constants: 2, 13, 22 */                                                                            \
+        (h) += (ROTR32((a), 2) ^ ROTR32((a), 13) ^ ROTR32((a), 22)) +                                         \
+            (((a) & ((b) | (c))) | ((b) & (c)));                                                              \
+    } while (0)
+
+static void CompressBlock(uint32_t state[8], const uint8_t block[CRYPT_SHA2_256_BLOCKSIZE])
+{
+    uint32_t w[64];
+
+    // RFC 6.2.1. Prepare the message schedule w:
+    // For t = 0 to 15
+    //    Wt = M(i)t
+    for (unsigned i = 0; i < 16; i++) { // 16 rounds to prepare the message schedule
+        w[i] = GET_UINT32_BE(block, 4 * (i)); /* 4 means bytes of uint32_t */
+    }
+
+    // For t = 16 to 63
+    //    Wt = SSIG1(w(t-2)) + w(t-7) + SSIG0(t-15) + w(t-16)
+    // @perf: speed up about 18% than expanded in x86_64
+
+    // RFC 6.2.2. Initialize the working variables:
+    // a, b, ..., g, h = H(i-1)[0..7]
+    uint32_t a = state[0]; // a = H(i-1)0
+    uint32_t b = state[1]; // b = H(i-1)1
+    uint32_t c = state[2]; // c = H(i-1)2
+    uint32_t d = state[3]; // d = H(i-1)3
+    uint32_t e = state[4]; // e = H(i-1)4
+    uint32_t f = state[5]; // f = H(i-1)5
+    uint32_t g = state[6]; // g = H(i-1)6
+    uint32_t h = state[7]; // h = H(i-1)7
+
+    // RFC 6.2.3. Perform the main hash computation:
+    for (unsigned i = 0; i < 16; i += 8) {  /* 0 ~ 16 rounds to do hash computation, 8 rounds pre loop */
+        ROUND(a, b, c, d, e, f, g, h, w[i + 0], K256[i + 0]);
+        ROUND(h, a, b, c, d, e, f, g, w[i + 1], K256[i + 1]);
+        ROUND(g, h, a, b, c, d, e, f, w[i + 2], K256[i + 2]);
+        ROUND(f, g, h, a, b, c, d, e, w[i + 3], K256[i + 3]);
+        ROUND(e, f, g, h, a, b, c, d, w[i + 4], K256[i + 4]);
+        ROUND(d, e, f, g, h, a, b, c, w[i + 5], K256[i + 5]);
+        ROUND(c, d, e, f, g, h, a, b, w[i + 6], K256[i + 6]);
+        ROUND(b, c, d, e, f, g, h, a, w[i + 7], K256[i + 7]);
+    }
+
+    for (unsigned i = 16; i < 64; i += 8) {  /* 16 ~ 64 rounds to do hash computation, 8 rounds pre loop */
+        w[i + 0] = R(w, i + 0); /* 8 rounds pre loop, the NO.1 computation shift 0 bytes */
+        ROUND(a, b, c, d, e, f, g, h, w[i + 0], K256[i + 0]);
+        w[i + 1] = R(w, i + 1); /* 8 rounds pre loop, the NO.2 computation shift 1 bytes */
+        ROUND(h, a, b, c, d, e, f, g, w[i + 1], K256[i + 1]);
+        w[i + 2] = R(w, i + 2); /* 8 rounds pre loop, the NO.3 computation shift 2 bytes */
+        ROUND(g, h, a, b, c, d, e, f, w[i + 2], K256[i + 2]);
+        w[i + 3] = R(w, i + 3); /* 8 rounds pre loop, the NO.4 computation shift 3 bytes */
+        ROUND(f, g, h, a, b, c, d, e, w[i + 3], K256[i + 3]);
+        w[i + 4] = R(w, i + 4); /* 8 rounds pre loop, the NO.5 computation shift 4 bytes */
+        ROUND(e, f, g, h, a, b, c, d, w[i + 4], K256[i + 4]);
+        w[i + 5] = R(w, i + 5); /* 8 rounds pre loop, the NO.6 computation shift 5 bytes */
+        ROUND(d, e, f, g, h, a, b, c, w[i + 5], K256[i + 5]);
+        w[i + 6] = R(w, i + 6); /* 8 rounds pre loop, the NO.7 computation shift 6 bytes */
+        ROUND(c, d, e, f, g, h, a, b, w[i + 6], K256[i + 6]);
+        w[i + 7] = R(w, i + 7); /* 8 rounds pre loop, the NO.8 computation shift 7 bytes */
+        ROUND(b, c, d, e, f, g, h, a, w[i + 7], K256[i + 7]);
+    }
+
+    // RFC 6.2.4. Compute the intermediate hash value H(i):
+    // H(i) = [a, b, ..., g, h] + H(i-1)[0..7]
+    state[0] += a; // H(i)0 = a + H(i-1)0
+    state[1] += b; // H(i)1 = b + H(i-1)1
+    state[2] += c; // H(i)2 = c + H(i-1)2
+    state[3] += d; // H(i)3 = d + H(i-1)3
+    state[4] += e; // H(i)4 = e + H(i-1)4
+    state[5] += f; // H(i)5 = f + H(i-1)5
+    state[6] += g; // H(i)6 = g + H(i-1)6
+    state[7] += h; // H(i)7 = h + H(i-1)7
+}
+#undef ROTR32
+#undef ROUND
+
+void SHA256CompressMultiBlocks(uint32_t hash[8], const uint8_t *in, uint32_t num)
+{
+    uint32_t n = num;
+    const uint8_t *p = in;
+    while (n > 0) {
+        CompressBlock(hash, p);
+        p += CRYPT_SHA2_256_BLOCKSIZE;
+        n--;
+    }
+}
+#endif
diff --git a/code/sdk/open_source/HiTLS/crypto/sha2/src/sha2_256.c b/code/sdk/open_source/HiTLS/crypto/sha2/src/sha2_256.c
new file mode 100644 (file)
index 0000000..da0e26e
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @file crypt_sha2_256.c
+ * Description: SHA2自研算法实现,源码引用于HICRYPTO组件自研SHA2算法
+ * Author: liushaoming
+ * Create: 2022-02-14
+******************************************************************************/
+
+#ifndef HITLS_CRYPTO_NO_SHA256
+#include "crypt_sha2.h"
+#include <stdlib.h>
+#include "securec.h"
+#include "crypt_errno.h"
+#include "crypt_utils.h"
+#include "bsl_err_internal.h"
+#include "sha2_core.h"
+#include "sal_mem.h"
+
+// clang-format off
+#define BITS_PRE_BYTE   8 // bits per byte
+#define SHIFTS_PER_BYTE 3 // shifts per byte
+#define BITSIZE(t)      (sizeof(t) * BITS_PRE_BYTE)
+
+// clang-format on
+
+int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx)
+{
+    if (ctx == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    (void)memset_s(ctx, sizeof(CRYPT_SHA2_256_Ctx), 0, sizeof(CRYPT_SHA2_256_Ctx));
+    /**
+     * @RFC 4634 6.1 SHA-224 and SHA-256 Initialization
+     * SHA-256, the initial hash value, H(0):
+     * H(0)0 = 6a09e667
+     * H(0)1 = bb67ae85
+     * H(0)2 = 3c6ef372
+     * H(0)3 = a54ff53a
+     * H(0)4 = 510e527f
+     * H(0)5 = 9b05688c
+     * H(0)6 = 1f83d9ab
+     * H(0)7 = 5be0cd19
+     */
+    ctx->h[0] = 0x6a09e667UL;
+    ctx->h[1] = 0xbb67ae85UL;
+    ctx->h[2] = 0x3c6ef372UL;   // 第2位按照RFC 4634赋值
+    ctx->h[3] = 0xa54ff53aUL;   // 第3位按照RFC 4634赋值
+    ctx->h[4] = 0x510e527fUL;   // 第4位按照RFC 4634赋值
+    ctx->h[5] = 0x9b05688cUL;   // 第5位按照RFC 4634赋值
+    ctx->h[6] = 0x1f83d9abUL;   // 第6位按照RFC 4634赋值
+    ctx->h[7] = 0x5be0cd19UL;   // 第7位按照RFC 4634赋值
+    ctx->outlen = CRYPT_SHA2_256_DIGESTSIZE;
+    return CRYPT_SUCCESS;
+}
+
+void CRYPT_SHA2_256_Deinit(CRYPT_SHA2_256_Ctx *ctx)
+{
+    if (ctx == NULL) {
+        return;
+    }
+    SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_256_Ctx));
+}
+
+int32_t CRYPT_SHA2_256_CopyCtx(CRYPT_SHA2_256_Ctx *dst, CRYPT_SHA2_256_Ctx *src)
+{
+    if (dst == NULL || src == NULL) {
+        return CRYPT_NULL_INPUT;
+    }
+
+    (void)memcpy_s(dst, sizeof(CRYPT_SHA2_256_Ctx), src, sizeof(CRYPT_SHA2_256_Ctx));
+    return CRYPT_SUCCESS;
+}
+
+static uint32_t CheckIsCorrupted(CRYPT_SHA2_256_Ctx *ctx, uint32_t nbytes);
+static int32_t UpdateParamIsValid(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
+{
+    /* NULL check */
+    if ((ctx == NULL) || (data == NULL && nbytes != 0)) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+
+    if (ctx->errorCode != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
+        return CRYPT_SHA2_INPUT_OVERFLOW;
+    }
+
+    if (CheckIsCorrupted(ctx, nbytes) != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
+        return CRYPT_SHA2_INPUT_OVERFLOW;
+    }
+
+    return CRYPT_SUCCESS;
+}
+
+static uint32_t CheckIsCorrupted(CRYPT_SHA2_256_Ctx *ctx, uint32_t nbytes)
+{
+    uint32_t cnt0 = (ctx->lNum + (nbytes << SHIFTS_PER_BYTE)) & 0xffffffffUL;
+    if (cnt0 < ctx->lNum) { /* overflow */
+        if (++ctx->hNum == 0) {
+            ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW;
+            return CRYPT_SHA2_INPUT_OVERFLOW;
+        }
+    }
+    uint32_t cnt1 = ctx->hNum + (uint32_t)(nbytes >> (BITSIZE(uint32_t) - SHIFTS_PER_BYTE));
+    if (cnt1 < ctx->hNum) { /* overflow */
+        ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW;
+        return CRYPT_SHA2_INPUT_OVERFLOW;
+    }
+    ctx->hNum = cnt1;
+    ctx->lNum = cnt0;
+    return CRYPT_SUCCESS;
+}
+
+int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
+{
+    int32_t ret = UpdateParamIsValid(ctx, data, nbytes);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+
+    if (nbytes == 0) {
+        return CRYPT_SUCCESS;
+    }
+
+    const uint8_t *d = data;
+    uint32_t left = nbytes;
+    uint32_t n = ctx->blocklen;
+    uint8_t *p = (uint8_t *)ctx->block;
+
+    if (left < CRYPT_SHA2_256_BLOCKSIZE - n) {
+        if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, left) != EOK) {
+            BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
+            return CRYPT_SECUREC_FAIL;
+        }
+        ctx->blocklen += (uint32_t)left;
+        return CRYPT_SUCCESS;
+    }
+    if ((n != 0) && (left >= CRYPT_SHA2_256_BLOCKSIZE - n)) {
+        if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, CRYPT_SHA2_256_BLOCKSIZE - n) != EOK) {
+            BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
+            return CRYPT_SECUREC_FAIL;
+        }
+        SHA256CompressMultiBlocks(ctx->h, p, 1);
+        n = CRYPT_SHA2_256_BLOCKSIZE - n;
+        d += n;
+        left -= n;
+        ctx->blocklen = 0;
+        (void)memset_s(p, CRYPT_SHA2_256_BLOCKSIZE, 0, CRYPT_SHA2_256_BLOCKSIZE);
+    }
+
+    n = (uint32_t)(left / CRYPT_SHA2_256_BLOCKSIZE);
+    if (n > 0) {
+        SHA256CompressMultiBlocks(ctx->h, d, n);
+        n *= CRYPT_SHA2_256_BLOCKSIZE;
+        d += n;
+        left -= n;
+    }
+
+    if (left != 0) {
+        ctx->blocklen = (uint32_t)left;
+        if (memcpy_s((uint8_t *)ctx->block, CRYPT_SHA2_256_BLOCKSIZE, d, left) != EOK) {
+            BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
+            return CRYPT_SECUREC_FAIL;
+        }
+    }
+
+    return CRYPT_SUCCESS;
+}
+
+static int32_t FinalParamIsValid(const CRYPT_SHA2_256_Ctx *ctx, const uint8_t *out, const uint32_t *outLen)
+{
+    if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+
+    if (*outLen < ctx->outlen) {
+        BSL_ERR_PUSH_ERROR(CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH);
+        return CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH;
+    }
+
+    if (ctx->errorCode == CRYPT_SHA2_INPUT_OVERFLOW) {
+        BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
+        return CRYPT_SHA2_INPUT_OVERFLOW;
+    }
+
+    return CRYPT_SUCCESS;
+}
+int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *outlen)
+{
+    int32_t ret = FinalParamIsValid(ctx, digest, outlen);
+    if (ret != CRYPT_SUCCESS) {
+        BSL_ERR_PUSH_ERROR(ret);
+        return ret;
+    }
+
+    uint8_t *p = (uint8_t *)ctx->block;
+    uint32_t n = ctx->blocklen;
+
+    p[n++] = 0x80;
+    if (n > (CRYPT_SHA2_256_BLOCKSIZE - 8)) { /* 8 bytes to save bits of input */
+        (void)memset_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, 0, CRYPT_SHA2_256_BLOCKSIZE - n);
+        n = 0;
+        SHA256CompressMultiBlocks(ctx->h, p, 1);
+    }
+    (void)memset_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, 0,
+        CRYPT_SHA2_256_BLOCKSIZE - 8 - n); /* 8 bytes to save bits of input */
+
+    p += CRYPT_SHA2_256_BLOCKSIZE - 8; /* 8 bytes to save bits of input */
+    PUT_UINT32_BE(ctx->hNum, p, 0);
+    p += sizeof(uint32_t);
+    PUT_UINT32_BE(ctx->lNum, p, 0);
+    p += sizeof(uint32_t);
+    p -= CRYPT_SHA2_256_BLOCKSIZE;
+    SHA256CompressMultiBlocks(ctx->h, p, 1);
+    ctx->blocklen = 0;
+    (void)memset_s(p, CRYPT_SHA2_256_BLOCKSIZE, 0, CRYPT_SHA2_256_BLOCKSIZE);
+
+    n = ctx->outlen / sizeof(uint32_t);
+    for (uint32_t nn = 0; nn < n; nn++) {
+        PUT_UINT32_BE(ctx->h[nn], digest, sizeof(uint32_t) * nn);
+    }
+    *outlen = ctx->outlen;
+
+    return CRYPT_SUCCESS;
+}
+
+#ifndef HITLS_CRYPTO_NO_SHA224
+int32_t CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx *ctx)
+{
+    if (ctx == NULL) {
+        BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
+        return CRYPT_NULL_INPUT;
+    }
+    (void)memset_s(ctx, sizeof(CRYPT_SHA2_224_Ctx), 0, sizeof(CRYPT_SHA2_224_Ctx));
+    /**
+     * @RFC 4634 6.1 SHA-224 and SHA-256 Initialization
+     * SHA-224, the initial hash value, H(0):
+     * H(0)0 = c1059ed8
+     * H(0)1 = 367cd507
+     * H(0)2 = 3070dd17
+     * H(0)3 = f70e5939
+     * H(0)4 = ffc00b31
+     * H(0)5 = 68581511
+     * H(0)6 = 64f98fa7
+     * H(0)7 = befa4fa4
+     */
+    ctx->h[0] = 0xc1059ed8UL;
+    ctx->h[1] = 0x367cd507UL;
+    ctx->h[2] = 0x3070dd17UL;   // 第2位按照RFC 4634赋值
+    ctx->h[3] = 0xf70e5939UL;   // 第3位按照RFC 4634赋值
+    ctx->h[4] = 0xffc00b31UL;   // 第4位按照RFC 4634赋值
+    ctx->h[5] = 0x68581511UL;   // 第5位按照RFC 4634赋值
+    ctx->h[6] = 0x64f98fa7UL;   // 第6位按照RFC 4634赋值
+    ctx->h[7] = 0xbefa4fa4UL;   // 第7位按照RFC 4634赋值
+    ctx->outlen = CRYPT_SHA2_224_DIGESTSIZE;
+    return CRYPT_SUCCESS;
+}
+
+void CRYPT_SHA2_224_Deinit(CRYPT_SHA2_224_Ctx *ctx)
+{
+    if (ctx == NULL) {
+        return;
+    }
+    SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_224_Ctx));
+}
+
+int32_t CRYPT_SHA2_224_CopyCtx(CRYPT_SHA2_224_Ctx *dst, CRYPT_SHA2_224_Ctx *src)
+{
+    if (dst == NULL || src == NULL) {
+        return CRYPT_NULL_INPUT;
+    }
+
+    (void)memcpy_s(dst, sizeof(CRYPT_SHA2_224_Ctx), src, sizeof(CRYPT_SHA2_224_Ctx));
+    return CRYPT_SUCCESS;
+}
+
+int32_t CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
+{
+    return CRYPT_SHA2_256_Update((CRYPT_SHA2_256_Ctx *)ctx, data, nbytes);
+}
+
+int32_t CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx *ctx, uint8_t *digest, uint32_t *len)
+{
+    return CRYPT_SHA2_256_Final((CRYPT_SHA2_256_Ctx *)ctx, digest, len);
+}
+#endif
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/crypto/sha2/src/sha2_core.h b/code/sdk/open_source/HiTLS/crypto/sha2/src/sha2_core.h
new file mode 100644 (file)
index 0000000..3ebfadd
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * @file sha2_core.h
+ * Description: sha2 内部函数
+ */
+#ifndef SHA2_CORE_H
+#define SHA2_CORE_H
+#include <stdint.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef U64
+#define U64(v) (uint64_t)(v)
+#endif
+
+void SHA256CompressMultiBlocks(uint32_t hash[8], const uint8_t *in, uint32_t num);
+void SHA512CompressMultiBlocks(uint64_t hash[8], const uint8_t *bl, uint32_t bcnt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/bsl/bsl_err.h b/code/sdk/open_source/HiTLS/include/bsl/bsl_err.h
new file mode 100644 (file)
index 0000000..dba71b3
--- /dev/null
@@ -0,0 +1,160 @@
+/**
+ * @defgroup    bsl_err bsl_err.h
+ * @ingroup     bsl
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       由产品调用,初始化、反初始化错误码模块,获取错误码,使用之前必
+ *              须要注册内存分配、释放相关函数,单线程环境可以不注册线程相关函数
+ */
+
+/** @defgroup    bsl  BSL */
+
+#ifndef BSL_ERR_H
+#define BSL_ERR_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "bsl_errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup bsl_err
+ * @brief 错误码模块初始化
+ *
+ * @par 描述:
+ * 产品如果是单线程的,则该函数可调可不调;
+ * 产品如果是多线程的,则必须在进程初始化时调用,且必须在调用BSL_SAL_RegThreadCallback
+ * 之后调用。
+ *
+ * @attention 无
+ * @retval #BSL_SUCCESS 错误码模块初始化成功
+ * @retval #BSL_SAL_ERR_NO_MEMORY 内存空间不足,无法申请线程锁空间
+ * @retval #BSL_SAL_ERR_UNKNOWN 线程锁初始化失败
+ */
+int32_t BSL_ERR_Init(void);
+
+/**
+ * @ingroup bsl_err
+ * @brief 错误码模块反初始化
+ *
+ * @par 描述:
+ * 产品在进程退出时调用
+ *
+ * @attention 无
+ */
+void BSL_ERR_DeInit(void);
+
+/**
+ * @ingroup bsl_err
+ * @brief 删除错误栈
+ *
+ * @par 描述:
+ * 删除错误栈,在进程和线程退出时调用
+ *
+ * @attention 线程退出时必须要调用,否则会有内存泄漏
+ * @param isRemoveAll [IN] 是否删除全部错误栈,进程退出时用true,线程退出时用false
+ */
+void BSL_ERR_RemoveErrorStack(bool isRemoveAll);
+
+/**
+ * @ingroup bsl_err
+ * @brief 获取错误栈中最后一次push的错误码
+ *
+ * @par 描述:
+ * 产品在HiTLS某个接口发生错误后调用,获取错误码。可以一直调用,每次返回的错误码组成该接口发生错误
+ * 的错误栈,直到返回BSL_SUCCESS为止。
+ *
+ * @attention
+ * @return 错误码,高16位是发生错误的模块子模块id,低16位是原因号
+ */
+int32_t BSL_ERR_GetLastError(void);
+
+/**
+ * @ingroup bsl_err
+ * @brief 获取错误栈中最后一次push的错误码、文件名和行号
+ *
+ * @par 描述:
+ * 产品在HiTLS某个接口发生错误后调用,获取一个错误码,并且可以获取文件名和行号,这些已获取的信息会从错误栈中删除。
+ * 可以一直调用,每次返回的错误码组成该接口发生错误的错误栈,直到返回BSL_SUCCESS为止。
+ *
+ * @attention 两个参数其中任一为NULL则无法获取文件名和行号
+ * @param file [OUT] 用于获取发生错误的文件名,不含目录路径
+ * @param lineNo [OUT] 用于获取发生错误的文件行号
+ * @return 错误码,高16位是发生错误的模块子模块id,低16位是原因号
+ */
+int32_t BSL_ERR_GetLastErrorFileLine(const char **file, uint32_t *lineNo);
+
+/**
+ * @ingroup bsl_err
+ * @brief 获取错误栈中最后一次push的错误码、文件名和行号
+ *
+ * @par 描述:
+ * 产品在HiTLS某个接口发生错误后调用,获取一个错误码,并且可以获取文件名和行号,这些已获取的信息不会从错误栈中删除。
+ *
+ * @attention 两个参数其中任一为NULL则无法获取文件名和行号
+ * @param file [OUT] 用于获取发生错误的文件名,不含目录路径
+ * @param lineNo [OUT] 用于获取发生错误的文件行号
+ * @return 错误码,高16位是发生错误的模块子模块id,低16位是原因号
+ */
+int32_t BSL_ERR_PeekLastErrorFileLine(const char **file, uint32_t *lineNo);
+
+/**
+ * @ingroup bsl_err
+ * @brief 获取错误栈中最早一次push的错误码
+ *
+ * @par 描述:
+ * 产品在HiTLS某个接口发生错误后调用,获取错误码。可以一直调用,每次返回的错误码组成该接口发生错误
+ * 的错误栈,直到返回BSL_SUCCESS为止。
+ *
+ * @attention
+ * @return 错误码,高16位是发生错误的模块子模块id,低16位是原因号
+ */
+int32_t BSL_ERR_GetError(void);
+
+/**
+ * @ingroup bsl_err
+ * @brief 获取错误栈中最早一次push的错误码、文件名和行号
+ *
+ * @par 描述:
+ * 产品在HiTLS某个接口发生错误后调用,获取一个错误码,并且可以获取文件名和行号,这些已获取的信息会从错误栈中删除。
+ * 可以一直调用,每次返回的错误码组成该接口发生错误的错误栈,直到返回BSL_SUCCESS为止。
+ *
+ * @attention 两个参数其中任一为NULL则无法获取文件名和行号
+ * @param file [OUT] 用于获取发生错误的文件名,不含目录路径
+ * @param lineNo [OUT] 用于获取发生错误的文件行号
+ * @return 错误码,高16位是发生错误的模块子模块id,低16位是原因号
+ */
+int32_t BSL_ERR_GetErrorFileLine(const char **file, uint32_t *lineNo);
+
+/**
+ * @ingroup bsl_err
+ * @brief 获取错误栈中最早一次push的错误码、文件名和行号
+ *
+ * @par 描述:
+ * 产品在HiTLS某个接口发生错误后调用,获取一个错误码,并且可以获取文件名和行号,这些已获取的信息不会从错误栈中删除。
+ *
+ * @attention 两个参数其中任一为NULL则无法获取文件名和行号
+ * @param file [OUT] 用于获取发生错误的文件名,不含目录路径
+ * @param lineNo [OUT] 用于获取发生错误的文件行号
+ * @return 错误码,高16位是发生错误的模块子模块id,低16位是原因号
+ */
+int32_t BSL_ERR_PeekErrorFileLine(const char **file, uint32_t *lineNo);
+
+/**
+ * @ingroup bsl_err
+ * @brief 清除错误栈
+ *
+ * @par 描述:
+ * 在调用HiTLS接口后检测到错误,如果无需理会错误信息,那么在再次调用HiTLS接口之前应该调用本接口清理错误信息
+ *
+ * @attention 无
+ */
+void BSL_ERR_ClearError(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/bsl/bsl_errno.h b/code/sdk/open_source/HiTLS/include/bsl/bsl_errno.h
new file mode 100644 (file)
index 0000000..2049535
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * @defgroup    bsl_errno   bsl_errno.h
+ * @ingroup     bsl
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       BSL模块的函数返回值
+ */
+
+#ifndef BSL_ERRNO_H
+#define BSL_ERRNO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup bsl_errno
+ * @brief   返回成功
+ */
+#define BSL_SUCCESS 0
+
+/**
+ * @ingroup bsl_errno
+ *
+ * BSL模块的返回值从 0x03000000 ~ 0x03ffffff
+ */
+enum BSL_ERROR {
+    /* 通用返回值从0x03000000开始 */
+    BSL_NULL_INPUT = 0x03000000,
+    BSL_INTERNAL_EXCEPTION,
+    BSL_MEMCPY_FAIL,
+    BSL_MEMMOVE_FAIL,
+    BSL_ERROR_INPUT,
+
+    /* SAL子模块的返回值从0x03010001开始 */
+    BSL_SAL_ERR_UNKNOWN = 0x03010001, /**< 未知错误 */
+    BSL_SAL_ERR_NO_MEMORY, /**< 申请内存失败 */
+    BSL_SAL_ERR_BAD_PARAM, /**< 参数错误 */
+
+    /* LOG子模块的返回值从0x03020001开始 */
+    BSL_LOG_ERR_REG_FUNC_FAIL = 0x03020001, /**< 注册日志输出函数失败 */
+    BSL_LOG_ERR_BAD_PARAM,                  /**< 参数错误 */
+    BSL_LOG_ERR_MEMCPY_FAIL,                /**< 内存拷贝失败 */
+
+    /* TLV子模块的返回值从0x03030001开始 */
+    BSL_TLV_ERR_BAD_PARAM = 0x03030001,     /**< 参数错误 */
+    BSL_TLV_ERR_MEMCPY_FAIL,                /**< 内存拷贝失败 */
+    BSL_TLV_ERR_NO_WANT_TYPE,               /**< 没有找到TLV */
+
+    /* ERR子模块的返回值从0x03040001开始 */
+    BSL_ERR_ERR_ACQUIRE_READ_LOCK_FAIL = 0x03040001, /**< 获取读锁失败 */
+    BSL_ERR_ERR_ACQUIRE_WRITE_LOCK_FAIL,
+    BSL_ERR_ERR_NO_STACK,
+    BSL_ERR_ERR_NO_ERROR,
+    BSL_ERR_ERR_NO_MARK,
+    
+    // 0x03050001 预留给time
+
+    /* UIO子模块的返回值从0x03060001开始 */
+    BSL_UIO_FAIL = 0x03060001,
+    BSL_UIO_IO_EXCEPTION,
+    BSL_UIO_IO_BUSY,
+    BSL_UIO_CTRL_INVALID_PARAM,
+    BSL_UIO_FILE_OPEN_FAIL,
+    BSL_UIO_MEM_GROW_FAIL,
+    BSL_UIO_REF_MAX,
+    BSL_UIO_MEM_ALLOC_FAIL,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/bsl/bsl_log.h b/code/sdk/open_source/HiTLS/include/bsl/bsl_log.h
new file mode 100644 (file)
index 0000000..12c42f0
--- /dev/null
@@ -0,0 +1,142 @@
+/**
+ * @defgroup    bsl_log bsl_log.h
+ * @ingroup     bsl
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       由产品注册日志相关的函数
+ */
+
+#ifndef BSL_LOG_H
+#define BSL_LOG_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup bsl_log
+ *
+ * 审计日志级别
+ */
+#define BSL_LOG_LEVEL_SEC         0U
+
+/**
+ * @ingroup bsl_log
+ *
+ * 紧急日志级别
+ */
+#define BSL_LOG_LEVEL_FATAL       1U
+
+/**
+ * @ingroup bsl_log
+ *
+ * 错误日志级别
+ */
+#define BSL_LOG_LEVEL_ERR         2U
+
+/**
+ * @ingroup bsl_log
+ *
+ * 警告日志级别
+ */
+#define BSL_LOG_LEVEL_WARN        3U
+
+/**
+ * @ingroup bsl_log
+ *
+ * 信息日志级别
+ */
+#define BSL_LOG_LEVEL_INFO        4U
+
+/**
+ * @ingroup bsl_log
+ *
+ * 调试日志级别
+ */
+#define BSL_LOG_LEVEL_DEBUG       5U
+
+/**
+ * @ingroup bsl_log
+ *
+ * HiTLS版本字符串
+ */
+#ifndef HITLS_VERSION
+#define HITLS_VERSION ""
+#endif
+
+#define HITLS_VERSION_LEN 150
+
+/**
+ * @ingroup bsl_log
+ * @brief   获取HiTLS版本号
+ * @attention 接收版本字符串的空间长度versionLen必须大于等于HITLS_VERSION_LEN
+ * @param   version [OUT] HiTLS当前版本号字符串
+ * @param   versionLen [IN/OUT] HiTLS当前版本号字符串长度
+ * @retval  BSL_SUCCESS 成功
+ * @retval  BSL_LOG_ERR_MEMCPY 内存拷贝失败
+ */
+int32_t BSL_LOG_GetVersion(char *version, uint32_t *versionLen);
+
+/**
+ * @ingroup bsl_log
+ * @brief   打点日志类型,可扩展其它类型
+ */
+#define BSL_LOG_BINLOG_TYPE_RUN 0x01
+
+/**
+ * @ingroup bsl_log
+ * @brief   打点日志定长回调类型
+ */
+typedef void (*BSL_LOG_BinLogFixLenFunc)(uint32_t logId, uint32_t logLevel, uint32_t logType,
+    void *format, void *para1, void *para2, void *para3, void *para4);
+
+/**
+ * @ingroup bsl_log
+ * @brief   打点日志变长回调类型
+ */
+typedef void (*BSL_LOG_BinLogVarLenFunc)(uint32_t logId, uint32_t logLevel, uint32_t logType,
+    void *format, void *para);
+
+/**
+ * @ingroup bsl_log
+ * @brief   注册打点日志回调函数的参数类型
+ */
+typedef struct {
+    BSL_LOG_BinLogFixLenFunc fixLenFunc; // 4参回调
+    BSL_LOG_BinLogVarLenFunc varLenFunc; // 1参回调
+} BSL_LOG_BinLogFuncs;
+
+/**
+ * @ingroup bsl_log
+ * @brief   设置打点日志的定长和变长回调函数
+ * @attention 入参可为NULL
+ * @param   funcs [IN] 打点日志回调函数指针集合体,不可为NULL,其成员可为NULL
+ * @retval  BSL_SUCCESS 成功
+ */
+int32_t BSL_LOG_RegBinLogFunc(const BSL_LOG_BinLogFuncs *funcs);
+
+/**
+ * @ingroup bsl_log
+ * @brief   设置打点日志的日志级别
+ * @attention 级别必须要合法
+ * @param   level [IN] 打点日志的级别,合法值为BSL_LOG_LEVEL_SEC、BSL_LOG_LEVEL_FATAL、BSL_LOG_LEVEL_ERR、
+ *          BSL_LOG_LEVEL_WARN、BSL_LOG_LEVEL_INFO、BSL_LOG_LEVEL_DEBUG
+ * @retval  BSL_SUCCESS 成功
+ * @retval  BSL_LOG_ERR_BAD_PARAM 入参非法
+ */
+int32_t BSL_LOG_SetBinLogLevel(uint32_t level);
+
+/**
+ * @ingroup bsl_log
+ * @brief   获取打点日志的日志级别
+ * @return  打点日志的级别,合法值为BSL_LOG_LEVEL_SEC、BSL_LOG_LEVEL_FATAL、BSL_LOG_LEVEL_ERR、
+ *          BSL_LOG_LEVEL_WARN、BSL_LOG_LEVEL_INFO、BSL_LOG_LEVEL_DEBUG
+ */
+uint32_t BSL_LOG_GetBinLogLevel(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/bsl/bsl_sal.h b/code/sdk/open_source/HiTLS/include/bsl/bsl_sal.h
new file mode 100644 (file)
index 0000000..9b3d7d3
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * @defgroup    bsl_sal bsl_sal.h
+ * @ingroup     bsl
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       系统抽象层,由产品注册系统相关的函数
+ */
+
+#ifndef BSL_SAL_H
+#define BSL_SAL_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup bsl_sal
+ *
+ * 产品为内存分配/释放可注册函数结构体
+ */
+typedef struct MemCallback {
+    /**
+     * @ingroup bsl_sal
+     * @brief 分配一块内存
+     *
+     * @par 描述:
+     * 分配一块内存
+     *
+     * @param size [IN] 分配内存的大小
+     * @retval 非NULL 内存分配成功,被分配内存的首地址
+     * @retval NULL 内存分配失败
+     */
+    void *(*pfMalloc)(uint32_t size);
+
+    /**
+     * @ingroup bsl_sal
+     * @brief 回收由pfMalloc分配的一块内存
+     *
+     * @par 描述:
+     * 回收由pfMalloc分配的一块内存
+     *
+     * @param addr [IN] 由pfMalloc分配的内存首地址
+     */
+    void (*pfFree)(void *addr);
+} BSL_SAL_MemCallback;
+
+/**
+ * @ingroup bsl_sal
+ *
+ * 线程锁句柄,在产品注册时由产品提供相应结构体
+ */
+typedef void *BSL_SAL_ThreadLockHandle;
+
+/**
+ * @ingroup bsl_sal
+ *
+ * 产品为线程相关操作可注册函数结构体
+ */
+typedef struct ThreadCallback {
+    /**
+     * @ingroup bsl_sal
+     * @brief 新建一个线程锁
+     *
+     * @par 描述:
+     * 新建一个线程锁
+     *
+     * @param lock [IN/OUT] 锁句柄
+     * @retval #BSL_SUCCESS 新建成功
+     * @retval #BSL_SAL_ERR_NO_MEMORY 内存空间不足,无法申请线程锁空间
+     * @retval #BSL_SAL_ERR_UNKNOWN 线程锁初始化失败
+     * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+     */
+    int32_t (*pfThreadLockNew)(BSL_SAL_ThreadLockHandle *lock);
+
+    /**
+    * @ingroup bsl_sal
+    * @brief 释放线程锁
+    *
+    * @par 描述:
+    * 释放线程锁,要保证在有其它线程获得锁的情况下,释放锁是没有问题的
+    *
+    * @param lock [IN] 锁句柄
+    */
+    void (*pfThreadLockFree)(BSL_SAL_ThreadLockHandle lock);
+
+    /**
+     * @ingroup bsl_sal
+     * @brief 锁住读操作
+     *
+     * @par 描述:
+     * 锁住读操作
+     *
+     * @param lock [IN] 锁句柄
+     * @retval #BSL_SUCCESS 成功
+     * @retval #BSL_SAL_ERR_UNKNOWN 操作失败
+     * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+     */
+    int32_t (*pfThreadReadLock)(BSL_SAL_ThreadLockHandle lock);
+
+    /**
+     * @ingroup bsl_sal
+     * @brief 锁住写操作
+     *
+     * @par 描述:
+     * 锁住写操作
+     *
+     * @param lock [IN] 锁句柄
+     * @retval #BSL_SUCCESS 成功
+     * @retval #BSL_SAL_ERR_UNKNOWN 操作失败
+     * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+     */
+    int32_t (*pfThreadWriteLock)(BSL_SAL_ThreadLockHandle lock);
+
+    /**
+     * @ingroup bsl_sal
+     * @brief 解锁
+     *
+     * @par 描述:
+     * 解锁
+     *
+     * @param lock [IN] 锁句柄
+     * @retval #BSL_SUCCESS 成功
+     * @retval #BSL_SAL_ERR_UNKNOWN 操作失败
+     * @retval #BSL_SAL_ERR_BAD_PARAM 参数错误,lock为NULL
+     */
+    int32_t (*pfThreadUnlock)(BSL_SAL_ThreadLockHandle lock);
+
+    /**
+     * @ingroup bsl_sal
+     * @brief 获取线程id
+     *
+     * @par 描述:
+     * 获取线程id
+     *
+     * @return 线程id
+     */
+    uint64_t (*pfThreadGetId)(void);
+} BSL_SAL_ThreadCallback;
+
+/**
+ * @ingroup bsl_sal
+ * @brief   内存相关回调函数注册接口
+ *
+ * @par 描述:
+ * 注册内存申请、释放函数
+ *
+ * @attention 无
+ * @param cb [IN] 内存相关回调函数指针
+ * @retval #BSL_SUCCESS 内存申请、释放函数注册成功
+ * @retval #BSL_SAL_ERR_BAD_PARAM 0x02010003,cb为NULL或者cb的成员有NULL,请仔细填写cb指针
+ */
+int32_t BSL_SAL_RegMemCallback(BSL_SAL_MemCallback *cb);
+
+/**
+ * @ingroup bsl_sal
+ * @brief   线程相关回调函数注册接口
+ *
+ * @par 描述:
+ * 注册线程锁创建、释放、加锁、解锁、获取线程id相关函数。
+ * 如果产品是单线程的,则不能调用;
+ * 如果产品是多线程的,则必须调用。
+ *
+ * @attention 无
+ * @param cb [IN] 线程相关回调函数指针
+ * @retval #BSL_SUCCESS 线程相关函数注册成功
+ * @retval #BSL_SAL_ERR_BAD_PARAM 0x02010003,cb为NULL或者cb的成员有NULL,请仔细填写cb指针
+ */
+int32_t BSL_SAL_RegThreadCallback(BSL_SAL_ThreadCallback *cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/include/bsl/bsl_uio.h b/code/sdk/open_source/HiTLS/include/bsl/bsl_uio.h
new file mode 100644 (file)
index 0000000..7115363
--- /dev/null
@@ -0,0 +1,288 @@
+/**
+ * @defgroup    bsl_uio bsl_uio.h
+ * @ingroup     bsl
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       统一IO抽象
+ */
+
+#ifndef BSL_UIO_H
+#define BSL_UIO_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   UIO模块控制结构
+ */
+typedef struct UIO_ControlBlock BSL_UIO;
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   传输协议枚举
+ */
+typedef enum {
+    BSL_UIO_TCP,    /**< TCP协议 */
+    BSL_UIO_UDP,    /**< UDP协议 */
+    BSL_UIO_SCTP,   /**< SCTP协议 */
+    BSL_UIO_UNKNOWN, /**< 未知协议,不应出现 */
+} BSL_UIO_TransportType;
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   Sctp auth key, hitls通过BSL_UIO_Method.ctrl方法传入 BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY 指令
+ *          以通知用户需要设置auth key
+ */
+typedef struct {
+    uint16_t shareKeyId;    /**< share key id */
+    uint16_t authKeySize;   /**< auth key size */
+    const uint8_t *authKey;       /**< auth key */
+} BSL_UIO_SctpAuthKey;
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   BSL_UIO_CtrlParameter 控制IO的回调,hitls通知用户需要实现的功能
+ *          可用作ctrl回调的cmd参数
+ */
+typedef enum {
+    /* 公共的使用0x0xx */
+    BSL_UIO_SET_PEER_IP_ADDR = 0x000,
+    BSL_UIO_GET_PEER_IP_ADDR,
+    BSL_UIO_SET_FD,
+    BSL_UIO_GET_FD,
+
+    /* SCTP 使用0x3XX */
+    BSL_UIO_SCTP_CHECK_PEER_AUTH = 0x300,     /**< SCTP检查对端是否支持认证 */
+    BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY,         /**< 添加新的sctp auth key,sctp可以用新的key接收数据 */
+    BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY,      /**< 激活新的sctp auth key,sctp需要用新的key发送数据 */
+    BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY,     /**< SCTP删除上个shared key */
+    BSL_UIO_SCTP_SND_BUFF_IS_EMPTY,           /**< SCTP发送队列是否已为空, ctrl.param为(uint8_t *)的指针
+                                                    当用户返回ctrl.param大于0,表明队列是为空. 反之等于0,表明队列不为空 */
+    BSL_UIO_SCTP_RECV_BUFF_IS_EMPTY,          /**< SCTP接收队列是否已为空, ctrl.param为(uint8_t *)的指针
+                                                    当用户返回ctrl.param大于0,表明队列是为空. 反之等于0,表明队列不为空 */
+    BSL_UIO_SCTP_GET_SEND_STREAM_ID,
+    BSL_UIO_SCTP_SET_APP_STREAM_ID,
+} BSL_UIO_CtrlParameter;
+
+typedef struct {
+    uint8_t *addr;
+    uint32_t size;
+} BSL_UIO_CtrlGetPeerIpAddrParam;
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   BSL_UIO_Method是控制IO的回调,需要产品注册给HITLS以供HITLS底层调用
+ */
+typedef struct BSL_UIO_MethodStruct {
+    BSL_UIO_TransportType type;
+    int32_t (*write)(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen);    /**< UIO写函数 */
+    int32_t (*read)(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen);            /**< UIO读函数 */
+    int32_t (*ctrl)(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg);              /**< UIO控制函数 */
+} BSL_UIO_Method;
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   创建一个新的UIO对象。
+ * @param   method  [IN] UIO方法结构体
+ * @retval  UIO对象 创建成功
+ * @retval  NULL UIO创建失败
+ */
+BSL_UIO *BSL_UIO_New(const BSL_UIO_Method *method);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   释放UIO对象。
+ * @param   uio  [IN] UIO对象。
+ */
+void BSL_UIO_Free(BSL_UIO *uio);
+
+/**
+ * @brief 按cmd处理特定的UIO实现
+ * @details 如果HiTLS无某个cmd的默认实现,则会调uio的ctrl回调
+ *
+ * @param uio [IN] UIO 对象
+ * @param cmd [IN] 不同的cmd对UIO对象执行不同的操作,必须有HiTLS实现或自定义实现
+ * @param larg [IN] parg的大小,数组为元素个数,指针为指向类型的大小,由cmd决定,详见下
+ * @param parg [IN/OUT] 由cmd决定,详见下
+ * @retval BSL_SUCCESS 成功
+ * @retval 非BSL_SUCCESS 具体参见bsl_errno.h
+ *
+ * @brief 在UIO对象中设置对端ip地址。
+ * @details 设置的地址格式为网络字节序二进制地址,长度为4或者16。
+ *           将为dtls的HelloVerifyRequest所用而提供生成cookie。
+ * @param uio [IN] UIO 对象
+ * @param cmd [IN] BSL_UIO_SET_PEER_IP_ADDR
+ * @param larg [IN] 对端地址的大小:长度应为4或者16。
+ * @param parg [IN] 对端地址。
+ *
+ * @brief 在UIO对象中获取对端ip地址。
+ * @details 获取的地址格式为网络字节序二进制地址,输入长度应大于设置的大小。
+ *          目的将为dtls的HelloVerifyRequest所用而提供生成cookie
+ * @param uio [IN] UIO 对象
+ * @param cmd [IN] BSL_UIO_GET_PEER_IP_ADDR
+ * @param larg [IN] sizeof(BSL_UIO_CtrlGetPeerIpAddrParam)
+ * @param parg [IN] BSL_UIO_CtrlGetPeerIpAddrParam *,其中:
+ *             addr [IN/OUT] 对端地址,
+ *             size [IN/OUT] IN: 输入缓存的大小 OUT: 输出对端地址的大小。
+ *
+ * @brief 在UIO对象中获取sctp发送的stream id
+ * @details 在需要用户在 BSL_UIO_Method.write中调用,并根据获取的stream id去发送sctp消息
+ * @param uio [IN] UIO 对象
+ * @param cmd [IN] BSL_UIO_SCTP_GET_SEND_STREAM_ID
+ * @param larg [IN] sizeof(uint16_t)
+ * @param parg [IN/OUT] 发送的流id,uint16_t *类型
+ *
+ * @brief 在UIO对象中设置sctp发送的app消息stream id
+ * @details 若用户需要对业务消息走特定的stream id, 则可以调用此接口
+ * @param uio [IN] UIO 对象
+ * @param cmd [IN] BSL_UIO_SCTP_SET_APP_STREAM_ID
+ * @param larg [IN] sizeof(uint16_t)
+ * @param parg [IN] uint16_t指针,指向app流id
+ *
+ * @brief 获取fd
+ * @details 如果UIO对象的底层有fd,则可以获取fd
+ * @param uio [IN] UIO 对象
+ * @param cmd [IN] BSL_UIO_GET_FD
+ * @param larg [IN] sizeof(int32_t)
+ * @param parg [IN/OUT] int32_t类型的指针,用于存放获取的fd
+ *
+ * @brief 设置fd
+ * @details 如果UIO对象的底层有fd,则可以设置fd
+ * @param uio [IN] UIO 对象
+ * @param cmd [IN] BSL_UIO_SET_FD
+ * @param larg [IN] sizeof(int32_t)
+ * @param parg [IN] int32_t类型的指针,用于指向被设置的fd
+ */
+int32_t BSL_UIO_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   获取UIO传输协议类型。
+ * @param   uio  [IN] UIO 对象。
+ * @return  协议类型
+ */
+BSL_UIO_TransportType BSL_UIO_GetTransportType(const BSL_UIO *uio);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   在UIO对象中设置用户数据。
+ * @details UIO will not modify the user data, user can add some information
+ *      for the UIO, and get the information by use BSL_UIO_GetUserData function; After you set user data by calling
+ *      BSL_UIO_SetUserData, you need to call BSL_UIO_SetUserData again before calling BSL_UIO_Free to set
+ *      user data to null to ensure that all memory is released.
+ * @param   uio   [IN] UIO 对象。
+ * @param   data  [IN] 用户数据指针
+ * @retval  BSL_SUCCESS 成功
+ * @retval  BSL_NULL_INPUT 无效空指针
+ */
+int32_t BSL_UIO_SetUserData(BSL_UIO *uio, void *data);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   获取UIO对象中的用户数据。
+ * @details The user data comes from users, and tls will not change any thing
+ *          for user data, user can add some customize information.
+ * @param   uio   [IN] UIO 对象。
+ * @retval  用户存储的数据结构指针 获取成功
+ * @retval  NULL 获取的数据不存在
+ */
+void *BSL_UIO_GetUserData(const BSL_UIO *uio);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   在UIO对象中设置对端ip地址。
+ * @details 设置的地址格式为网络字节序二进制地址,长度为4或者16。 \n
+ *          如果为DTLS 服务器并且使能cookie交换, 则用该对端ip地址用来生成cookie \n
+ *          以让服务器通过发送HelloVerifyRequest给客户端.
+ * @param   uio   [IN] UIO 对象。
+ * @param   addr  [IN] addr 对端IP地址。
+ * @param   size   [IN] size 对端地址的大小:长度应为4或者16。
+ * @retval  BSL_SUCCESS 成功
+ * @retval  BSL_NULL_INPUT 无效空指针
+ * @retval  BSL_UIO_FAIL 设置失败,长度不正确
+ */
+int32_t BSL_UIO_SetPeerIpAddr(BSL_UIO *uio, uint8_t *addr, uint32_t size);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   在UIO对象中获取对端ip地址。
+ * @details 获取的地址格式为网络字节序二进制地址,输入长度应大于设置的大小。 \n
+ *          目的:为dtls服务器的HelloVerifyRequest所用(生成cookie的输入因子)
+ * @param   uio   [IN] UIO 对象。
+ * @param   addr  [IN] addr 对端地址。
+ * @param   size   [IN/OUT] size IN: 输入缓存的大小 OUT: 输出对端地址的大小。
+ * @retval  BSL_SUCCESS 成功
+ * @retval  BSL_NULL_INPUT 无效空指针
+ * @retval  BSL_UIO_FAIL 获取失败,未设置地址或长度不正确
+ */
+int32_t BSL_UIO_GetPeerIpAddr(BSL_UIO *uio, uint8_t *addr, uint32_t *size);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   在UIO对象中获取sctp发送的stream id
+ * @details 如果为DTLS OVER SCTP, 发送数据时SCTP应该从HITLS获取发送的流id,按该流id发送数据。 \n
+ *          非业务数据在DTLS协议规定使用流id为0发送数据。 \n
+ *          至于业务数据(app data)用户可以通过BSL_UIO_SctpSetAppStreamId 设置业务数据发送的流id。
+ * @attention 如果为DTLS OVER SCTP, 用户需要在 BSL_UIO_Method.write中调用,并根据获取的stream id去发送sctp消息。
+ * @param   uio   [IN] UIO 对象。
+ * @param   sendStreamId  [OUT] sendStreamId 发送的流id。
+ * @retval  BSL_SUCCESS 成功
+ * @retval  BSL_NULL_INPUT 无效空指针
+ */
+int32_t BSL_UIO_SctpGetSendStreamId(BSL_UIO *uio, uint16_t *sendStreamId);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   在UIO对象中设置sctp发送的app消息stream id
+ * @details 若用户需要对业务消息走特定的stream id, 则可以调用此接口
+ *
+ * @param   uio   [IN] UIO 对象。
+ * @param   sendAppStreamId  [OUT] sendAppStreamId 发送的app流id。
+ * @retval  BSL_SUCCESS 成功
+ * @retval  BSL_NULL_INPUT 无效空指针
+ */
+int32_t BSL_UIO_SctpSetAppStreamId(BSL_UIO *uio, uint16_t sendAppStreamId);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   为UIO对象设置文件描述符fd。
+ * @param   uio [IN] UIO 对象。
+ * @param   fd  [IN] 文件描述符, 对于TCP/UDP是socket fd, 对于SCTP是偶联id。
+ * @retval  BSL_SUCCESS 设置成功
+ * @retval  BSL_NULL_INPUT 入参空指针
+ */
+int32_t BSL_UIO_SetFd(BSL_UIO *uio, int32_t fd);
+
+/**
+ * @ingroup bsl_uio
+ *
+ * @brief   获取UIO对象中的文件描述符fd。
+ * @param   uio  [IN] UIO 对象
+ * @retval  -1 获取失败
+ * @retval  其他值 文件描述符fd
+ */
+int32_t BSL_UIO_GetFd(BSL_UIO *uio);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_algid.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_algid.h
new file mode 100644 (file)
index 0000000..0a03cee
--- /dev/null
@@ -0,0 +1,210 @@
+/**\r
+ * @defgroup    crypt_algid crypt_algid.h\r
+ * @ingroup     crypto\r
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.\r
+ * @brief       通用类型对外接口\r
+ */\r
+\r
+#ifndef CRYPT_ALGID_H\r
+#define CRYPT_ALGID_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+/**\r
+ * @ingroup  crypt_algid\r
+ * RAND 算法ID\r
+ */\r
+typedef enum {\r
+    CRYPT_RAND_SHA1 = 0,\r
+    CRYPT_RAND_SHA224,\r
+    CRYPT_RAND_SHA256,\r
+    CRYPT_RAND_SHA384,\r
+    CRYPT_RAND_SHA512,\r
+    CRYPT_RAND_HMAC_SHA1,\r
+    CRYPT_RAND_HMAC_SHA224,\r
+    CRYPT_RAND_HMAC_SHA256,\r
+    CRYPT_RAND_HMAC_SHA384,\r
+    CRYPT_RAND_HMAC_SHA512,\r
+    CRYPT_RAND_AES128_CTR,\r
+    CRYPT_RAND_AES192_CTR,\r
+    CRYPT_RAND_AES256_CTR,\r
+    CRYPT_RAND_AES128_CTR_DF,\r
+    CRYPT_RAND_AES192_CTR_DF,\r
+    CRYPT_RAND_AES256_CTR_DF,\r
+    CRYPT_RAND_ALGID_MAX\r
+} CRYPT_RAND_AlgId;\r
+\r
+/**\r
+ * @ingroup  crypt_algid\r
+ * 哈希算法ID\r
+ */\r
+typedef enum {\r
+    CRYPT_MD_MD4 = 0,\r
+    CRYPT_MD_MD5,\r
+    CRYPT_MD_SHA1,\r
+    CRYPT_MD_SHA224,\r
+    CRYPT_MD_SHA256,\r
+    CRYPT_MD_SHA384,\r
+    CRYPT_MD_SHA512,\r
+    CRYPT_MD_SHA3_224,\r
+    CRYPT_MD_SHA3_256,\r
+    CRYPT_MD_SHA3_384,\r
+    CRYPT_MD_SHA3_512,\r
+    CRYPT_MD_SHAKE128,\r
+    CRYPT_MD_SHAKE256,\r
+    CRYPT_MD_SM3,\r
+    CRYPT_MD_MAX\r
+} CRYPT_MD_AlgId;\r
+\r
+/**\r
+ * @ingroup  crypt_algid\r
+ * MAC算法ID\r
+ */\r
+typedef enum {\r
+    CRYPT_MAC_HMAC_MD5 = 0,\r
+    CRYPT_MAC_HMAC_SHA1,\r
+    CRYPT_MAC_HMAC_SHA224,\r
+    CRYPT_MAC_HMAC_SHA256,\r
+    CRYPT_MAC_HMAC_SHA384,\r
+    CRYPT_MAC_HMAC_SHA512,\r
+    CRYPT_MAC_HMAC_SM3,\r
+    CRYPT_MAC_CMAC_AES128,\r
+    CRYPT_MAC_CMAC_AES192,\r
+    CRYPT_MAC_CMAC_AES256,\r
+    CRYPT_MAC_GMAC_AES128,\r
+    CRYPT_MAC_GMAC_AES192,\r
+    CRYPT_MAC_GMAC_AES256,\r
+    CRYPT_MAC_SIPHASH64,\r
+    CRYPT_MAC_SIPHASH128,\r
+    CRYPT_MAC_MAX\r
+} CRYPT_MAC_AlgId;\r
+\r
+/**\r
+ * @ingroup  crypt_algid\r
+ * 非对称算法ID\r
+ */\r
+typedef enum {\r
+    CRYPT_PKEY_DSA = 0,\r
+    CRYPT_PKEY_ED25519,\r
+    CRYPT_PKEY_X25519,\r
+    CRYPT_PKEY_RSA,\r
+    CRYPT_PKEY_DH,\r
+    CRYPT_PKEY_ECDSA,\r
+    CRYPT_PKEY_ECDH,\r
+    CRYPT_PKEY_SM2,\r
+    CRYPT_PKEY_ED448,\r
+    CRYPT_PKEY_X448,\r
+    CRYPT_PKEY_SM9,\r
+    CRYPT_PKEY_MAX\r
+} CRYPT_PKEY_AlgId;\r
+\r
+/**\r
+ * @ingroup  cipher_algid\r
+ * 对称加解密模式组合算法ID\r
+ */\r
+typedef enum {\r
+    CRYPT_CIPHER_AES128_CBC = 0,\r
+    CRYPT_CIPHER_AES192_CBC,\r
+    CRYPT_CIPHER_AES256_CBC,\r
+\r
+    CRYPT_CIPHER_AES128_CTR,\r
+    CRYPT_CIPHER_AES192_CTR,\r
+    CRYPT_CIPHER_AES256_CTR,\r
+\r
+    CRYPT_CIPHER_AES128_ECB,\r
+    CRYPT_CIPHER_AES192_ECB,\r
+    CRYPT_CIPHER_AES256_ECB,\r
+\r
+    CRYPT_CIPHER_AES128_XTS,\r
+    CRYPT_CIPHER_AES256_XTS,\r
+\r
+    CRYPT_CIPHER_AES128_CCM,\r
+    CRYPT_CIPHER_AES192_CCM,\r
+    CRYPT_CIPHER_AES256_CCM,\r
+\r
+    CRYPT_CIPHER_AES128_GCM,\r
+    CRYPT_CIPHER_AES192_GCM,\r
+    CRYPT_CIPHER_AES256_GCM,\r
+\r
+    CRYPT_CIPHER_CHACHA20_POLY1305,\r
+\r
+    CRYPT_CIPHER_SM4_CBC,\r
+    CRYPT_CIPHER_SM4_ECB,\r
+\r
+    CRYPT_CIPHER_AES128_CFB,\r
+    CRYPT_CIPHER_AES192_CFB,\r
+    CRYPT_CIPHER_AES256_CFB,\r
+\r
+    CRYPT_CIPHER_AES128_OFB,\r
+    CRYPT_CIPHER_AES192_OFB,\r
+    CRYPT_CIPHER_AES256_OFB,\r
+    \r
+    CRYPT_CIPHER_TDES_ECB,\r
+    CRYPT_CIPHER_TDES_CBC,\r
+    CRYPT_CIPHER_TDES_OFB,\r
+    CRYPT_CIPHER_TDES_CFB,\r
+\r
+    CRYPT_CIPHER_SM4_CTR,\r
+    CRYPT_CIPHER_SM4_GCM,\r
+\r
+    CRYPT_CIPHER_MAX,\r
+} CRYPT_CIPHER_AlgId;\r
+\r
+/**\r
+ * @ingroup  crypt_algid\r
+ * 非对称算法参数ID,高16位为算法标识,低16位映射对应算法LowLevel的ID定义\r
+ */\r
+typedef enum {\r
+    CRYPT_DH_RFC2409_768,\r
+    CRYPT_DH_RFC2409_1024,\r
+    CRYPT_DH_RFC3526_1536,\r
+    CRYPT_DH_RFC3526_2048,\r
+    CRYPT_DH_RFC3526_3072,\r
+    CRYPT_DH_RFC3526_4096,\r
+    CRYPT_DH_RFC3526_6144,\r
+    CRYPT_DH_RFC3526_8192,\r
+    CRYPT_DH_RFC7919_2048,\r
+    CRYPT_DH_RFC7919_3072,\r
+    CRYPT_DH_RFC7919_4096,\r
+    CRYPT_DH_RFC7919_6144,\r
+    CRYPT_DH_RFC7919_8192,\r
+    CRYPT_ECC_NISTP224,\r
+    CRYPT_ECC_NISTP256,\r
+    CRYPT_ECC_NISTP384,\r
+    CRYPT_ECC_NISTP521,\r
+    CRYPT_ECC_SM2,\r
+    CRYPT_ECC_SM9,\r
+    CRYPT_ECC_PARAID_MAX,\r
+    CRYPT_PKEY_PARAID_MAX\r
+} CRYPT_PKEY_ParaId;\r
+\r
+/**\r
+ * @ingroup  crypt_algid\r
+ * 椭圆曲线点编码格式\r
+ */\r
+typedef enum {\r
+    CRYPT_POINT_COMPRESSED,\r
+    CRYPT_POINT_UNCOMPRESSED, // 默认格式\r
+    CRYPT_POINT_HYBRID,\r
+    CRYPT_POINT_MAX\r
+} CRYPT_PKEY_PointFormat;\r
+\r
+/**\r
+ * @ingroup  crypt_algid\r
+ * KDF算法ID\r
+ */\r
+typedef enum {\r
+    CRYPT_KDF_SCRYPT = 0,\r
+    CRYPT_KDF_PBKDF2,\r
+    CRYPT_KDF_KDFTLS12,\r
+    CRYPT_KDF_HKDF,\r
+    CRYPT_KDF_MAX\r
+} CRYPT_KDF_AlgId;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+#endif // CRYPT_ALGID_H\r
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_check_macro.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_check_macro.h
new file mode 100644 (file)
index 0000000..40cd95a
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * @defgroup    crypt_check_macro crypt_check_macro.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       检查宏之间的依赖关系
+ */
+
+#ifndef CRYPT_CHECK_MACRO_H
+#define CRYPT_CHECK_MACRO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#if !defined(HITLS_CRYPTO_NO_PKEY) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "HITLS_CRYPTO_NO_PKEY not defined, but HITLS_CRYPTO_NO_MD defined."
+#endif
+
+#if defined(HITLS_CRYPTO_HMAC) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "HITLS_CRYPTO_HMAC defined, but HITLS_CRYPTO_NO_MD also defined."
+#endif
+
+#if !defined(HITLS_CRYPTO_NO_RAND) && !defined(HITLS_CRYPTO_NO_DRBG_HASH) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "Hash Func in eal-rand should be controlled by HITLS_CRYPTO_NO_DRBG_HASH, not by HITLS_CRYPTO_NO_MD."
+#endif
+
+#if defined(HITLS_CRYPTO_SHA1) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "HITLS_CRYPTO_SHA1 defined, but HITLS_CRYPTO_NO_MD also defined."
+#endif
+
+#if defined(HITLS_CRYPTO_SHA2) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "HITLS_CRYPTO_SHA2 defined, but HITLS_CRYPTO_NO_MD also defined."
+#endif
+
+#if defined(HITLS_CRYPTO_SHA3) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "HITLS_CRYPTO_SHA3 defined, but HITLS_CRYPTO_NO_MD also defined."
+#endif
+
+#if defined(HITLS_CRYPTO_MD5) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "HITLS_CRYPTO_MD5 defined, but HITLS_CRYPTO_NO_MD also defined."
+#endif
+
+#if defined(HITLS_CRYPTO_SM3) && \
+    defined(HITLS_CRYPTO_NO_MD)
+#error "HITLS_CRYPTO_SM3 defined, but HITLS_CRYPTO_NO_MD also defined."
+#endif
+
+#if !defined(HITLS_CRYPTO_NO_SHA224) && \
+    defined(HITLS_CRYPTO_NO_SHA256)
+#error "HITLS_CRYPTO_NO_SHA224 not defined, but HITLS_CRYPTO_NO_SHA256 also defined."
+#endif
+
+#if !defined(HITLS_CRYPTO_NO_SHA384) && \
+    defined(HITLS_CRYPTO_NO_SHA512)
+#error "HITLS_CRYPTO_NO_SHA384 not defined, but HITLS_CRYPTO_NO_SHA512 also defined."
+#endif
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // CRYPT_CHECK_MACRO_H
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_bn.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_bn.h
new file mode 100644 (file)
index 0000000..59195ae
--- /dev/null
@@ -0,0 +1,238 @@
+/**
+ * @defgroup    crypt_eal_bn crypt_eal_bn.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ * @brief       大数运算对外接口
+ */
+
+#ifndef CRYPT_EAL_BN_H
+#define CRYPT_EAL_BN_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "crypt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct BigNum CRYPT_BN_BigNum;
+
+typedef struct BnMont CRYPT_BN_Mont;
+
+typedef struct BnOptimizer CRYPT_BN_Optimizer;
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数创建
+ *
+ * @param   bits [IN] 位数
+ *
+ * @retval 非NULL 成功
+ * @retval NULL 失败
+ */
+CRYPT_BN_BigNum *CRYPT_EAL_BN_Create(uint32_t bits);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数销毁
+ *
+ * @param   a [IN] 大数
+ *
+ * @retval 无
+ */
+void CRYPT_EAL_BN_Destroy(CRYPT_BN_BigNum *a);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数优化器创建
+ *
+ * @retval 非NULL 成功
+ * @retval NULL 失败
+ */
+CRYPT_BN_Optimizer *CRYPT_EAL_BN_OptimizerCreate(void);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数优化器销毁
+ *
+ * @param   opt [IN] 大数优化器
+ *
+ * @retval 无
+ */
+void CRYPT_EAL_BN_OptimizerDestroy(CRYPT_BN_Optimizer *opt);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   设置符号
+ *
+ * @param   a [IN] 大数
+ * @param   sign [IN] 符号,true为负数 false为正数
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_NO_NEGATIVE_ZERO 0不能设置为负数符号
+ */
+int32_t CRYPT_EAL_BN_SetSign(CRYPT_BN_BigNum *a, bool sign);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   判断大数的值是否为1
+ *
+ * @attention 大数入参不能为空指针
+ * @param   a [IN] 大数
+ *
+ * @retval  true,大数的值为1
+ * @retval  false,大数的值不为1
+ *
+ */
+bool CRYPT_EAL_BN_IsOne(const CRYPT_BN_BigNum *a);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   判断大数是否为负数
+ *
+ * @attention 大数入参不能为空指针
+ * @param   a [IN] 大数
+ *
+ * @retval  true,大数的值为负数
+ * @retval  false,大数的值不为负数
+ *
+ */
+bool CRYPT_EAL_BN_IsNegative(const CRYPT_BN_BigNum *a);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数加法
+ *
+ * @param   r [OUT] 和
+ * @param   a [IN] 加数
+ * @param   b [IN] 加数
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ */
+int32_t CRYPT_EAL_BN_Add(CRYPT_BN_BigNum *r, const CRYPT_BN_BigNum *a, const CRYPT_BN_BigNum *b);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数减法
+ *
+ * @param   r [OUT] 差
+ * @param   a [IN] 被减数
+ * @param   b [IN] 减数
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ */
+int32_t CRYPT_EAL_BN_Sub(CRYPT_BN_BigNum *r, const CRYPT_BN_BigNum *a, const CRYPT_BN_BigNum *b);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数乘法
+ *
+ * @param   r [OUT] 乘积
+ * @param   a [IN] 乘数
+ * @param   b [IN] 乘数
+ * @param   opt [IN] 优化器
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ * @retval  CRYPT_CRYPT_BN_Optimizer_GET_FAIL 从优化器申请空间失败
+ */
+int32_t CRYPT_EAL_BN_Mul(
+    CRYPT_BN_BigNum *r, const CRYPT_BN_BigNum *a, const CRYPT_BN_BigNum *b, CRYPT_BN_Optimizer *opt);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数除法
+ *
+ * @param   q [OUT] 商
+ * @param   r [OUT] 余数
+ * @param   x [IN] 被除数
+ * @param   y [IN] 除数
+ * @param   opt [IN] 优化器
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ * @retval  CRYPT_CRYPT_BN_Optimizer_GET_FAIL 从优化器申请空间失败
+ * @retval  CRYPT_BN_ERR_DIVISOR_ZERO 除数不能为0
+ */
+int32_t CRYPT_EAL_BN_Div(CRYPT_BN_BigNum *q, CRYPT_BN_BigNum *r, const CRYPT_BN_BigNum *x, const CRYPT_BN_BigNum *y,
+    CRYPT_BN_Optimizer *opt);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数求最大公约数
+ * @par 描述: gcd(a,b) (a、b!=0)
+ *
+ * @param   r [OUT] 最大公约数
+ * @param   a [IN] 大数
+ * @param   b [IN] 大数
+ * @param   opt [IN] 优化器
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ * @retval  CRYPT_CRYPT_BN_Optimizer_GET_FAIL 从优化器申请空间失败
+ * @retval  CRYPT_BN_ERR_GCD_NO_ZERO 求最大公约数不能有0
+ */
+int32_t CRYPT_EAL_BN_Gcd(
+    CRYPT_BN_BigNum *r, const CRYPT_BN_BigNum *a, const CRYPT_BN_BigNum *b, CRYPT_BN_Optimizer *opt);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数模逆
+ *
+ * @param   r [OUT] 结果
+ * @param   x [IN] 大数
+ * @param   m [IN] 模
+ * @param   opt [IN] 优化器
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ * @retval  CRYPT_CRYPT_BN_Optimizer_GET_FAIL 从优化器申请空间失败
+ * @retval  CRYPT_BN_ERR_NO_INVERSE 无法求出模逆
+ */
+int32_t CRYPT_EAL_BN_ModInv(
+    CRYPT_BN_BigNum *r, const CRYPT_BN_BigNum *x, const CRYPT_BN_BigNum *m, CRYPT_BN_Optimizer *opt);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   二进制转大数
+ *
+ * @param   r [OUT] 大数
+ * @param   bin [IN] 待转换数据流
+ * @param   binLen [IN] 数据流长度
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ */
+int32_t CRYPT_EAL_BN_Bin2Bn(CRYPT_BN_BigNum *r, const uint8_t *bin, uint32_t binLen);
+
+/**
+ * @ingroup crypt_eal_bn
+ * @brief   大数转二进制
+ *
+ * @param   a [IN] 大数
+ * @param   bin [IN/OUT] 待转换数据流 --传入指针不能为空
+ * @param   binLen [IN/OUT] 数据流长度 --传入时也是bin缓存区的长度
+ *
+ * @retval  CRYPT_SUCCESS
+ * @retval  CRYPT_NULL_INPUT 无效空指针
+ * @retval  CRYPT_BN_SPACE_NOT_ENOUGH 空间不够
+ * @retval  CRYPT_SECUREC_FAIL 拷贝出错
+ */
+int32_t CRYPT_EAL_BN_Bn2Bin(const CRYPT_BN_BigNum *a, uint8_t *bin, uint32_t *binLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_cipher.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_cipher.h
new file mode 100644 (file)
index 0000000..24c0f5c
--- /dev/null
@@ -0,0 +1,240 @@
+/**
+ * @defgroup    crypt_eal_cipher crypt_eal_cipher.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       对称加解密算法对外接口
+ */
+
+#ifndef CRYPT_EAL_CIPHER_H
+#define CRYPT_EAL_CIPHER_H
+
+#ifndef HITLS_CRYPTO_NO_CIPHER
+#include <stdint.h>
+#include <stdbool.h>
+#include "crypt_algid.h"
+#include "crypt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+typedef struct CRYPT_EAL_CipherCtxLocal CRYPT_EAL_CipherCtx;
+
+/**
+  * @ingroup crypt_eal_cipher
+  * @brief 对称合规判断
+  *
+  * @param id [IN] 对称算法id
+  *
+  * @return  true 成功
+  *          false 失败
+  */
+typedef bool (*CRYPT_EAL_CipherC2)(CRYPT_CIPHER_AlgId id);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief   对称合规判断回调注册接口,用于判断算法参数是否合规和模块状态是否可用,EAL的哈希接口在执行操作前会调用该回调
+ *            回调失败会导致CRYPT_EAL_CipherNewCtx/CRYPT_EAL_CipherInit/CRYPT_EAL_CipherReinit/
+ *            CRYPT_EAL_CipherUpdate/CRYPT_EAL_CipherFinal/CRYPT_EAL_CipherCtrl/CRYPT_EAL_CipherSetPadding接口失败
+ *          非核准模式下可以使用任意算法
+ *          ISO19790模式下只允许CRYPT_CIPHER_AES128_CBC/CRYPT_CIPHER_AES192_CBC/CRYPT_CIPHER_AES256_CBC/
+ *            CRYPT_CIPHER_AES128_CTR/CRYPT_CIPHER_AES192_CTR/CRYPT_CIPHER_AES256_CTR/
+ *            CRYPT_CIPHER_AES128_ECB/CRYPT_CIPHER_AES192_ECB/CRYPT_CIPHER_AES256_ECB/
+ *            CRYPT_CIPHER_AES128_XTS/CRYPT_CIPHER_AES256_XTS
+ *
+ * @param   func     [IN] 对称合规判断回调
+ *
+ * @return  无
+ */
+void CRYPT_EAL_RegCipherC2(CRYPT_EAL_CipherC2 func);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 生成对称加解密句柄
+ *
+ * @param id [IN] 对称加解密算法id
+ * @return 成功返回:cipher ctx
+ *         失败返回:NULL
+ */
+CRYPT_EAL_CipherCtx* CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AlgId id);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 释放对称加解密句柄,先清除敏感信息再释放
+ *
+ * @param ctx [IN] 对称加解密句柄, ctx由调用方置空
+ * @return 无
+ */
+void CRYPT_EAL_CipherFreeCtx(CRYPT_EAL_CipherCtx *ctx);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 初始化对称加解密句柄, key不能为NULL;除了ECB模式,其他模式iv不能为NULL
+ * iv的长度必须与块长度一致(ECB模式不做此要求),
+ * 块长度可以通过CRYPT_EAL_CipherCtrl的CRYPT_CTRL_GET_BLOCKSIZE获取。
+ * CRYPT_EAL_CipherInit 在任意阶段可以重复调用,会重置key和iv, 并清除缓存数据。
+ * <table border="1">
+ * <tr><th>         算法ID            </th><th>  keyLen  </th><th>  ivLen  </th></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_CBC  </td><td>   16     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES192_CBC  </td><td>   24     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_CBC  </td><td>   32     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_CTR  </td><td>   16     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES192_CTR  </td><td>   24     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_CTR  </td><td>   32     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_ECB  </td><td>   16     </td><td>  0      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES192_ECB  </td><td>   24     </td><td>  0      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_ECB  </td><td>   32     </td><td>  0      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_XTS  </td><td>   32     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_XTS  </td><td>   64     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_CCM  </td><td>   16     </td><td>  7 <= ivLen <= 13     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES192_CCM  </td><td>   24     </td><td>  7 <= ivLen <= 13     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_CCM  </td><td>   32     </td><td>  7 <= ivLen <= 13     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_GCM  </td><td>   16     </td><td>  1 ≤ ivLen ≤ 2^32 - 1 (byte)     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES192_GCM  </td><td>   24     </td><td>  1 ≤ ivLen ≤ 2^32 - 1 (byte)     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_GCM  </td><td>   32     </td><td>  1 ≤ ivLen ≤ 2^32 - 1 (byte)     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_CHACHA20_POLY1305  </td><td>   32     </td><td>  8或12     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_SM4_CBC     </td><td>   16     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_SM4_ECB     </td><td>   16     </td><td>  0      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_CFB  </td><td>   16     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES192_CFB  </td><td>   24     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_CFB  </td><td>   32     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES128_OFB  </td><td>   16     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES192_OFB  </td><td>   24     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_AES256_OFB  </td><td>   32     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_TDES_ECB    </td><td>   24     </td><td>  0      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_TDES_CBC    </td><td>   24     </td><td>  8或24      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_TDES_OFB    </td><td>   24     </td><td>  8或24      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_TDES_CFB    </td><td>   24     </td><td>  8或24      </td></tr>
+ * <tr><td>  CRYPT_CIPHER_SM4_CTR     </td><td>   16     </td><td>  16     </td></tr>
+ * <tr><td>  CRYPT_CIPHER_SM4_GCM     </td><td>   16     </td><td>  1 ≤ ivLen ≤ 2^32 - 1 (byte)     </td></tr>
+ * </table>
+ *
+ * @param ctx [IN] 对称加解密句柄
+ * @param key [IN] 密钥
+ * @param keyLen [IN] 密钥长度
+ * @param iv [IN] 初始化向量
+ * @param ivLen [IN] 初始化向量长度
+ * @param enc [IN] true 为加密, false 为解密
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_CipherInit(CRYPT_EAL_CipherCtx *ctx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
+    uint32_t ivLen, bool enc);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 反初始化句柄,还原句柄到刚调用完CRYPT_EAL_CipherNewCtx的状态
+ *
+ * @param ctx [IN] 对称加解密句柄
+ * @return 无
+ */
+void CRYPT_EAL_CipherDeinit(CRYPT_EAL_CipherCtx *ctx);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 重新初始化句柄,保留 key, 重新设置iv, 清除缓存、敏感数据; 除了ECB模式,其他模式iv不能为NULL
+ * iv的设置需要结合对应的算法ID, 参见CRYPT_EAL_CipherInit中的对应关系。
+ *
+ * @param ctx [IN] 对称加解密句柄
+ * @param iv [IN] 向量
+ * @param ivlen [IN] 向量的长度
+ * @return 无
+ */
+int32_t CRYPT_EAL_CipherReinit(CRYPT_EAL_CipherCtx *ctx, uint8_t *iv, uint32_t ivLen);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 持续输入加密、解密数据
+ * CRYPT_EAL_CipherUpdate 应与CRYPT_EAL_CipherFinal配合使用,在一次或多次调用完CRYPT_EAL_CipherUpdate后,
+ * 调用CRYPT_EAL_CipherFinal 获取最终的加密数据。
+ *
+ * @param ctx [IN] 对称加解密句柄
+ * @param in [IN] 持续输入的数据
+ * @param inLen [IN] 持续输入数据的长度
+ * @param out [OUT] 输出的数据
+ * @param outLen [IN/OUT] 输入: CBC、ECB块加密 建议输入outLen > inLen + blockSize, CTR、XTS流加密 建议 outLen >= inLen
+ * blockSize 可使用CRYPT_EAL_CipherCtrl 的CRYPT_CTRL_GET_BLOCKSIZE获取
+ * 输出 : 输出加密数据的长度, 如果是块加密算法且最后待处理数据不足块长度时,outLen输出为0;
+ * eg: CBC、ECB块加密
+ *     1. 首次输入加密数据,且inLen < blockSize                          此时outLen输出为0
+ *     2. 首次输入的加密数据长度inLen为blockSize的整数倍                      此时outLen 等于 inLen
+ *     3. 首次输入的加密数据长度inLen > blockSize 且不是blockSize的整数倍     此时outLen < inLen
+ *     4. 多次输入加密数据,(inLen % blockSize) + cache(ctx缓存数据) >= blockSize
+ *     此时outLen = (inlen / blockSize) * blockSize + blockSize
+ *     CTR outLen 等于 inLen
+ *     XTS 模式update会预留最后2 个block到final进行处理, 如果输入数据加上缓存的总长度不足2 * blocksize, 则输出为0
+ *     1. 首次输入数据          此时outLen = (inLen / blocksize - 2) * blocksize
+ *     2. 多次输入加密数据      此时outLen = ((inLen + cache) / blocksize - 2) * blocksize
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_CipherUpdate(CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out,
+    uint32_t *outLen);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 对不足块大小的数据进行充填,输出加密数据;AEAD的tag通过CRYPT_EAL_CipherCtrl获取
+ * 对于CBC、ECB等块加密算法,必须设置padding, XTS模式需要调用final得到最后2个block数据
+ *
+ * @param ctx [IN] 对称加解密句柄
+ * @param out [OUT] 输出加密数据
+ * @param outLen [IN/OUT] 输入:outLen >= blockSize
+ * 输出:流加密输出为0。
+ *      CBC、ECB块加密设置了padding则outLen输出为blockSize
+ *      CBC、ECB块加密没设置padding, 且ctx中有缓存数据,则报错
+ *      CBC、ECB块加密没设置padding,且ctx中无缓存数据, outLen输出为0
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_CipherFinal(CRYPT_EAL_CipherCtx *ctx, uint8_t *out, uint32_t *outLen);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 设置ctx里面的mode ctx的参数
+ * <table border="1">
+ * <tr><th>         参数               </th><th>  数据类型       </th><th>  len的长度(data的字节数)  </th></tr>
+ * <tr><td>  CRYPT_CTRL_GET_IV         </td><td>  uint8_t数组   </td><td>  IV的长度跟对应算法有关,参见 CRYPT_EAL_CipherInit 中的对应关系  </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_IV         </td><td>  uint8_t数组   </td><td>  IV的长度跟对应算法有关,参见 CRYPT_EAL_CipherInit 中的对应关系  </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_AAD        </td><td>  uint8_t数组   </td><td>  仅限AEAD计算使用,长度和对应AEAD算法有关  </td></tr>
+ * <tr><td>  CRYPT_CTRL_GET_TAG        </td><td>  uint8_t数组   </td><td>  仅限AEAD计算使用,长度为用户设置的tagLen  </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_COUNT     </td><td>  uint8_t[4]      </td><td>  len长度为 4  </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_TAGLEN     </td><td>  uint32_t      </td><td>  len长度为 4  </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_MSGLEN     </td><td>  uint64_t      </td><td>  len长度为 8  </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_FEEDBACKSIZE     </td><td>  uint32_t      </td><td>  len长度为 4  </td></tr>
+ * <tr><td>  CRYPT_CTRL_GET_FEEDBACKSIZE     </td><td>  uint32_t指针      </td><td>  sizeof(*uint32_t)  </td></tr>
+ * <tr><td>  CRYPT_CTRL_GET_BLOCKSIZE  </td><td>  uint32_t      </td><td>  len长度为 4 </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_SM4_CONSTTIME     </td><td>  NULL      </td><td>  0  </td></tr>
+ * </table>
+ * @param ctx [IN] 对称加解密句柄
+ * @param type [IN] 参数类型
+ * @param data [IN/OUT] 输入、输出数据
+ * @param len [OUT] 数据长度
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_CipherCtrl(CRYPT_EAL_CipherCtx *ctx, CRYPT_CipherCtrl type, void *data, uint32_t len);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 设置padding模式
+ *
+ * @param ctx 对称加解密句柄
+ * @param type padding类型
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_CipherSetPadding(CRYPT_EAL_CipherCtx *ctx, CRYPT_PaddingType type);
+
+/**
+ * @ingroup crypt_eal_cipher
+ * @brief 获取padding类型
+ *
+ * @param ctx 对称加解密句柄
+ * @return 返回模式
+ */
+int32_t CRYPT_EAL_CipherGetPadding(CRYPT_EAL_CipherCtx *ctx);
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_kdf.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_kdf.h
new file mode 100644 (file)
index 0000000..71f2b0a
--- /dev/null
@@ -0,0 +1,215 @@
+/**\r
+ * @defgroup    crypt_eal_kdf    crypt_eal_kdf.h\r
+ * @ingroup     crypto\r
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.\r
+ * @brief       密钥派生(KDF)算法头文件\r
+ */\r
+\r
+#ifndef CRYPT_EAL_KDF_H\r
+#define CRYPT_EAL_KDF_H\r
+\r
+#ifndef HITLS_CRYPTO_NO_KDF\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include "crypt_algid.h"\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   scrypt 基于密码的密钥派生函数\r
+ *\r
+ * @param   key [IN] 密码,用户输入的字符串\r
+ * @param   keyLen [IN] 密码长度,任意长度,包括0长度\r
+ * @param   salt [IN] 盐值,用户输入的字符串\r
+ * @param   saltLen [IN] 盐值长度,任意长度,包括0长度\r
+ * @param   n [IN] CPU和内存消耗参数,必须为2的幂次,大于1,小于2 ^ (128 * r / 8)\r
+ * @param   r [IN] 块大小参数,不为0的任意正整数,其中 r * p < 2 ^ 30\r
+ * @param   p [IN] 并行化参数,不为0的任意正整数,p <= (2 ^ 32 - 1) * 32 / (128 * r)\r
+ * @param   out [OUT] 派生密钥,不能为空\r
+ * @param   len [IN] 派生密钥长度,取值范围为 (0, 0xFFFFFFFF]\r
+ *\r
+ * @return 成功返回:CRYPT_SUCCESS\r
+ *         其他错误码,请查询crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_Scrypt(const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen, uint32_t n,\r
+    uint32_t r, uint32_t p, uint8_t *out, uint32_t len);\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   PBKDF 基于密码的密钥派生函数\r
+ *\r
+ * @param   id [IN] HMAC算法ID(仅支持CRYPT_MAC_HMAC_SHA1、CRYPT_MAC_HMAC_SHA224、\r
+ *                  CRYPT_MAC_HMAC_SHA256、CRYPT_MAC_HMAC_SHA384、CRYPT_MAC_HMAC_SHA512)\r
+ * @param   key [IN] 密码,用户输入的字符串\r
+ * @param   keyLen [IN] 密码长度,任意长度,包括0长度。\r
+ * @param   salt [IN] 盐值,用户输入的字符串\r
+ * @param   saltLen [IN] 盐值长度,任意长度,包括0长度。\r
+ * @param   it [IN] 迭代次数,可以为任意不为0的正整数,其中性能特殊场景可为1000,默认场景推荐10000,\r
+ *                  性能不敏感或者高安全性要求场景推荐使用10000000。\r
+ * @param   out [OUT] 派生密钥\r
+ * @param   len [IN] 派生密钥长度,长度取值范围为 [1, 0xFFFFFFFF]\r
+ *\r
+ * @return 成功返回:CRYPT_SUCCESS\r
+ *         其他错误码,请查询crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_Pbkdf2(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *salt,\r
+    uint32_t saltLen, uint32_t it, uint8_t *out, uint32_t len);\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   PKCS5 PBKDF 本接口为接口CRYPT_EAL_Pbkdf2的封装,默认使用算法CRYPT_MAC_HMAC_SHA256进行计算。\r
+ *\r
+ * @param   key [IN] 密码,用户输入的字符串\r
+ * @param   keyLen [IN] 密码长度,不为0的任意正整数。\r
+ * @param   salt [IN] 盐值,用户输入的字符串\r
+ * @param   saltLen [IN] 盐值长度,不为0的任意正整数。\r
+ * @param   it [IN] 迭代次数,可以为任意不为0的正整数,其中性能特殊场景可为1000,默认场景推荐10000,\r
+ *                  性能不敏感或者高安全性要求场景推荐使用10000000。\r
+ * @param   out [OUT] 派生密钥\r
+ * @param   len [IN] 派生密钥长度,长度取值范围为 [1, 0xFFFFFFFF]\r
+ *\r
+ * @return 成功返回:CRYPT_SUCCESS\r
+ *         其他错误码,请查询crypt_errno.h\r
+ */\r
+#define CRYPT_EAL_PKCS5_PBKDF2(key, keyLen, salt, saltLen, it, out, len)  \\r
+        CRYPT_EAL_Pbkdf2(CRYPT_MAC_HMAC_SHA256, key, keyLen, salt, saltLen, it, out, len)\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   HKDF\r
+ *\r
+ * @param   id [IN] MAC算法ID(仅支持CRYPT_MAC_HMAC_SHA1、CRYPT_MAC_HMAC_SHA224、\r
+ *                  CRYPT_MAC_HMAC_SHA256、CRYPT_MAC_HMAC_SHA384、CRYPT_MAC_HMAC_SHA512)\r
+ * @param   key [IN] 密码,用户输入的字符串\r
+ * @param   keyLen [IN] 密钥长度,任意长度\r
+ * @param   salt [IN] 盐值,用户输入的字符串\r
+ * @param   saltLen [IN] 盐值长度,任意长度\r
+ * @param   info [IN] 用户可选的附加信息,可选信息。\r
+ * @param   infoLen [IN] 附加信息长度,可以为0长度。[0,0xFFFFFFFF]\r
+ * @param   out [OUT] 派生密钥\r
+ * @param   len [IN] 派生密钥长度,不为0的任意整数,其中最大值:\r
+ *                      CRYPT_MAC_HMAC_SHA1对应最大值为5100、\r
+ *                      CRYPT_MAC_HMAC_SHA224对应最大值为7140、\r
+ *                      CRYPT_MAC_HMAC_SHA256对应最大值为8160、\r
+ *                      CRYPT_MAC_HMAC_SHA384对应最大值为12240、\r
+ *                      CRYPT_MAC_HMAC_SHA512对应最大值为16320、\r
+ *\r
+ * @return 成功返回:CRYPT_SUCCESS\r
+ *         其他错误码,请查询crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_Hkdf(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *salt, uint32_t saltLen,\r
+    const uint8_t *info, uint32_t infoLen, uint8_t *out, uint32_t len);\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   KDF-TLS1.2\r
+ *\r
+ * @param   id [IN] MAC算法ID(仅支持部分HMAC算法ID,\r
+ *                  其中包括 CRYPT_MAC_HMAC_SHA256、CRYPT_MAC_HMAC_SHA384、CRYPT_MAC_HMAC_SHA512)\r
+ * @param   key [IN] 密钥,用户输入的字符串\r
+ * @param   keyLen [IN] 密钥长度,任意长度\r
+ * @param   label [IN] 标签,用户输入的字符串。和seed拼接作为PRF的输入数据\r
+ * @param   labelLen [IN] 标签长度,任意长度\r
+ * @param   seed [IN] 种子,用户输入的字符串,用于作为PRF的输入数据。\r
+ * @param   seedLen [IN] 种子长度,任意长度\r
+ * @param   out [OUT] 派生密钥\r
+ * @param   len [IN] 派生密钥长度,取值范围为 [1, 0xFFFFFFFF]\r
+ *\r
+ * @return 成功返回:CRYPT_SUCCESS\r
+ *         其他错误码,请查询crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_KdfTls12(CRYPT_MAC_AlgId id, const uint8_t *key, uint32_t keyLen, const uint8_t *label,\r
+    uint32_t labelLen, const uint8_t *seed, uint32_t seedLen,  uint8_t *out, uint32_t len);\r
+\r
+/**\r
+  * @ingroup crypt_eal_kdf\r
+  * @brief scrypt合规判断\r
+  *\r
+  * @return  true 测试成功\r
+  *          false 测试失败\r
+  */\r
+typedef bool (*CRYPT_EAL_ScryptC2)(void);\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   scrypt合规判断回调注册接口,用于判断模块状态是否可用\r
+ *          CRYPT_EAL_Scrypt接口在执行操作前会调用该回调,回调失败会导致CRYPT_EAL_Scrypt失败\r
+ *\r
+ * @param   func     [IN] scrypt合规判断回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegScryptC2(CRYPT_EAL_ScryptC2 func);\r
+\r
+/**\r
+  * @ingroup crypt_eal_kdf\r
+  * @brief pbkdf2合规判断\r
+  *\r
+  * @return  true 测试成功\r
+  *          false 测试失败\r
+  */\r
+typedef bool (*CRYPT_EAL_Pbkdf2C2)(uint32_t saltLen, uint32_t it, uint32_t len);\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   pbkdf2合规判断回调注册接口,用于判断模块状态是否可用\r
+ *          CRYPT_EAL_Pbkdf2接口在执行操作前会调用该回调,回调失败会导致CRYPT_EAL_Pbkdf2失败\r
+ *\r
+ * @param   func     [IN] pbkdf2合规判断回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegPbkdf2C2(CRYPT_EAL_Pbkdf2C2 func);\r
+\r
+/**\r
+  * @ingroup crypt_eal_kdf\r
+  * @brief hkdf合规判断\r
+  *\r
+  * @return  true 测试成功\r
+  *          false 测试失败\r
+  */\r
+typedef bool (*CRYPT_EAL_HkdfC2)(void);\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   hkdf合规判断回调注册接口,用于判断模块状态是否可用\r
+ *          CRYPT_EAL_Hkdf接口在执行操作前会调用该回调,回调失败会导致CRYPT_EAL_Hkdf失败\r
+ *\r
+ * @param   func     [IN] hkdf合规判断回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegHkdfC2(CRYPT_EAL_HkdfC2 func);\r
+\r
+/**\r
+  * @ingroup crypt_eal_kdf\r
+  * @brief KDF-TLS1.2合规判断\r
+  *\r
+  * @param   id [IN] MAC算法ID\r
+  *                 非核准模式下可以使用任意算法\r
+  *                 ISO19790模式下只允许CRYPT_MAC_HMAC_SHA256/CRYPT_MAC_HMAC_SHA384/CRYPT_MAC_HMAC_SHA512\r
+  *\r
+  * @return  true 测试成功\r
+  *          false 测试失败\r
+  */\r
+typedef bool (*CRYPT_EAL_KdfTls12C2)(CRYPT_MAC_AlgId id);\r
+\r
+/**\r
+ * @ingroup crypt_eal_kdf\r
+ * @brief   KDF-TLS1.2合规判断回调注册接口,用于判断算法参数是否合规和模块状态是否可用\r
+ *          CRYPT_EAL_KdfTls12接口在执行操作前会调用该回调,回调失败会导致CRYPT_EAL_KdfTls12失败\r
+ *\r
+ * @param   func     [IN] KDF-TLS1.2合规判断回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegKdfTls12C2(CRYPT_EAL_KdfTls12C2 func);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+#endif\r
+#endif\r
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_mac.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_mac.h
new file mode 100644 (file)
index 0000000..97984a2
--- /dev/null
@@ -0,0 +1,176 @@
+/**
+ * @defgroup    crypt_eal_mac    crypt_eal_mac.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief    MAC算法接口,包含HMAC、CMAC
+ */
+#ifndef CRYPT_EAL_MAC_H
+#define CRYPT_EAL_MAC_H
+
+#ifndef HITLS_CRYPTO_NO_MAC
+#include <stdbool.h>
+#include <stdint.h>
+#include "crypt_algid.h"
+#include "crypt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EAL_MacCtx CRYPT_EAL_MacCtx;
+
+/**
+  * @ingroup crypt_eal_mac
+  * @brief MAC合规判断
+  *
+  * @param   id [IN] MAC算法id
+  *                 非核准模式下可以使用任意算法
+  *
+  * @return  true 测试成功
+  *          false 测试失败
+  */
+typedef bool (*CRYPT_EAL_MacC2)(CRYPT_MAC_AlgId id);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   MAC合规判断回调注册接口,用于判断算法参数是否合规和模块状态是否可用
+ *            EAL的哈希接口在执行操作前会调用该回调,回调失败会导致CRYPT_EAL_MacNewCtx/CRYPT_EAL_MacInit/
+ *            CRYPT_EAL_MacUpdate/CRYPT_EAL_MacFinal/CRYPT_EAL_MacReinit接口失败
+ *          非核准模式下,该验证不生效
+ *          ISO19790模式下只允许CRYPT_MAC_HMAC_SHA1/CRYPT_MAC_HMAC_SHA224/CRYPT_MAC_HMAC_SHA256/
+ *            CRYPT_MAC_HMAC_SHA384/CRYPT_MAC_HMAC_SHA512/CRYPT_MAC_CMAC_AES128/
+ *            CRYPT_MAC_CMAC_AES192/CRYPT_MAC_CMAC_AES256
+ *
+ * @param   func     [IN] MAC合规判断回调
+ *
+ * @return  无
+ */
+void CRYPT_EAL_RegMacC2(CRYPT_EAL_MacC2 func);
+
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   申请MAC上下文
+ *
+ * @param   id [IN] MAC算法ID
+ *
+ * @return  CRYPT_EAL_MacCtx指针
+ *          若失败返回NULL
+ */
+CRYPT_EAL_MacCtx *CRYPT_EAL_MacNewCtx(CRYPT_MAC_AlgId id);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   释放MAC上下文内存
+ *
+ * @param   ctx [IN] MAC上下文, ctx由调用方置空
+ */
+void CRYPT_EAL_MacFreeCtx(CRYPT_EAL_MacCtx *ctx);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief  MAC算法初始化上下文,在调用CRYPT_EAL_MacNewCtx接口之后使用。
+ *         在计算过程中任何时候都可以使用初始化接口,但注意,调用了初始化接口上一次的计算数据全部清零。
+ *
+ * @param   ctx [IN] MAC上下文
+ * @param   key [IN] 密钥,长度规格如下:
+ *                   HMAC:长度为大于等于0的任意整数, 其中HMAC-SHA1、HMAC-SHA224、HMAC-SHA256长度为小于2^64bits,
+ *                        HMAC-SHA384、HMAC-SHA512长度为小于2^128bits
+ *                   CMAC:CMAC-AES128 长度需要等于128bits、CMAC-AES192 长度需要等于192bits、
+ *                        CMAC-AES256 长度需要等于256bits
+ * @param   len [IN] 密钥长度
+ *
+ * @retval #CRYPT_SUCCESS 初始化成功
+ * @retval #CRYPT_NULL_INPUT 指针ctx参数或者key参数为NULL
+ * @retval #CRYPT_AES_ERR_KEYLEN  AES CMAC算法密钥长度错误
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_MacInit(CRYPT_EAL_MacCtx *ctx, const uint8_t *key, uint32_t len);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   持续输入待mac的数据。需要在接口CRYPT_EAL_MacInit接口执行成功之后使用。
+ *
+ * @param   ctx [IN] MAC上下文
+ * @param   in  [IN] 输入数据,当该变量为NULL时,len参数必须为0,否则报错
+ * @param   len [IN] 输入数据长度,可以为0长度。
+ *
+ * @retval #CRYPT_SUCCESS  更新摘要内部状态成功
+ * @retval #CRYPT_NULL_INPUT  输入参数为NULL
+ * @retval #CRYPT_EAL_ERR_STATE 状态错误
+ * @retval #CRYPT_SHA1_INPUT_OVERFLOW  HMAC-SHA1输入数据的长度超出最大值
+ * @retval #CRYPT_SHA2_INPUT_OVERFLOW  HMAC-SHA224、HMAC-SHA256、HMAC-SHA384、HMAC-SHA512输入数据的长度超出最大值
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_MacUpdate(CRYPT_EAL_MacCtx *ctx, const uint8_t *in, uint32_t len);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   输出MAC结果。需要在接口CRYPT_EAL_MacInit接口执行成功之后使用,过程中可以不调用CRYPT_EAL_MacUpdate接口。
+ *          MAC输出长度,HMAC-SHA1对应20bytes、HMAC-SHA224对应28bytes、HMAC-SHA256对应32bytes、
+ *          HMAC-SHA384对应48bytes、HMAC-SHA512对应64bytes、CMAC-AES对应的16bytes
+ *
+ * @param   ctx [IN] MAC上下文
+ * @param   out [OUT] 输出数据,必须分配足够大的内存用于存储MAC结果,不能为NULL。
+ * @param   len [IN/OUT] 输出数据长度,入参该值需要指定out长度,该长度需要大于等于MAC生成的长度,出参为MAC 输出的长度.
+ *
+ * @retval #CRYPT_SUCCESS  计算成功
+ * @retval #CRYPT_NULL_INPUT  输入参数为NULL
+ * @retval #CRYPT_EAL_ERR_STATE 状态错误
+ * @retval #CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH  HMAC算法输出buffer长度不足
+ * @retval #CRYPT_CMAC_OUT_BUFF_LEN_NOT_ENOUGH  CMAC算法输出buffer长度不足
+ * @retval #CRYPT_SHA1_INPUT_OVERFLOW  HMAC-SHA1输入数据的长度超出最大值
+ * @retval #CRYPT_SHA2_INPUT_OVERFLOW  HMAC-SHA224、HMAC-SHA256、HMAC-SHA384、HMAC-SHA512输入数据的长度超出最大值
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_MacFinal(CRYPT_EAL_MacCtx *ctx, uint8_t *out, uint32_t *len);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   去初始化函数,调用后如果要计算则需要重新初始化。
+ * @param   ctx [IN] MAC上下文
+ */
+void CRYPT_EAL_MacDeinit(CRYPT_EAL_MacCtx *ctx);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief  使用ctx中保留的信息重新初始化。不需要重新调用init接口初始化。相当与deinit和init两个接口的结合。
+ * @param   ctx [IN] MAC上下文
+ * @retval #CRYPT_SUCCESS  reinit成功
+ * @retval #CRYPT_NULL_INPUT  输入参数为NULL
+ */
+int32_t CRYPT_EAL_MacReinit(CRYPT_EAL_MacCtx *ctx);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   通过上下文获取对应算法的输出MAC长度
+ * @param   ctx [IN] MAC上下文
+ * @return  上下文对应的MAC长度
+ */
+uint32_t CRYPT_EAL_GetMacLen(const CRYPT_EAL_MacCtx *ctx);
+
+/**
+ * @ingroup crypt_eal_mac
+ * @brief   设置算法参数,该接口需要在CRYPT_EAL_MacInit接口调用之后使用,且该接口仅支持GMAC算法
+ * <table border="1">
+ * <tr><th>         参数              </th><th>  数据类型      </th><th>  len为长度,in的字节数      </th></tr>
+ * <tr><td>  CRYPT_CTRL_SET_IV        </td><td>  uint8_t数组   </td><td>  IV的长度                  </td></tr>
+ * <tr><td>  CRYPT_CTRL_SET_TAGLEN    </td><td>  uint32_t      </td><td>  4字节,sizeof(uint32_t)   </td></tr>
+ * </table>
+ * @param   ctx [IN] MAC上下文
+ * @param   type [IN] 设置参数类型,当前仅支持两种操作码,CRYPT_CTRL_SET_IV 和 CRYPT_CTRL_SET_TAGLEN
+ * @param   in [IN] 输入数据
+ * @param   len [IN] 输入数据长度
+ * @retval #CRYPT_SUCCESS  参数设置成功
+ * @retval #CRYPT_EAL_ERR_STATE 状态错误
+ * @retval #CRYPT_EAL_MAC_CTRL_TYPE_ERROR 设置参数类型错误
+ * @retval #CRYPT_EAL_ERR_ALGID  算法ID为非GMAC
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_MacCtrl(CRYPT_EAL_MacCtx *ctx, uint32_t type, void *in, uint32_t len);
+#ifdef __cplusplus
+}   // end extern "C"
+#endif
+
+#endif
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_md.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_md.h
new file mode 100644 (file)
index 0000000..4c4a3c0
--- /dev/null
@@ -0,0 +1,120 @@
+/**\r
+ * @defgroup    crypt_eal_md    crypt_eal_md.h\r
+ * @ingroup     crypto\r
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.\r
+ * @brief       消息摘要(MD)算法对外接口文件\r
+ */\r
+\r
+#ifndef CRYPT_EAL_MD_H\r
+#define CRYPT_EAL_MD_H\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include "crypt_algid.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+typedef struct EAL_MdCtx CRYPT_EAL_MdCTX;\r
+\r
+/**\r
+  * @ingroup crypt_eal_md\r
+  * @brief 哈希合规判断\r
+  *\r
+  * @param   id [IN] 哈希算法ID\r
+  *\r
+  * @return  true 测试成功\r
+  *          false 测试失败\r
+  */\r
+typedef bool (*CRYPT_EAL_MdC2)(CRYPT_MD_AlgId id);\r
+\r
+/**\r
+ * @ingroup crypt_eal_md\r
+ * @brief   哈希合规判断回调注册接口,用于判断算法参数是否合规和模块状态是否可用,EAL的哈希接口在执行操作前会调用该回调\r
+ *            回调失败会导致CRYPT_EAL_MdNewCtx/CRYPT_EAL_MdInit/CRYPT_EAL_MdUpdate/CRYPT_EAL_MdFinal接口失败\r
+ *          非核准模式下可以使用任意算法\r
+ *          ISO19790模式下只允许CRYPT_MD_SHA224/CRYPT_MD_SHA256/CRYPT_MD_SHA384/CRYPT_MD_SHA512\r
+ *\r
+ * @param   func     [IN] 哈希合规判断回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegMdC2(CRYPT_EAL_MdC2 func);\r
+\r
+/**\r
+ * @ingroup crypt_eal_md\r
+ * @brief   创建MD上下文,计算结束后需要调用CRYPT_EAL_MdFreeCtx接口释放内存。\r
+ *\r
+ * @param   id [IN] 算法ID\r
+ *\r
+ * @return  CRYPT_EAL_MdCTX MD上下文指针\r
+ *          若失败返回空\r
+ */\r
+CRYPT_EAL_MdCTX *CRYPT_EAL_MdNewCtx(CRYPT_MD_AlgId id);\r
+\r
+/**\r
+ * @ingroup crypt_eal_md\r
+ * @brief   MD上下文释放\r
+ *\r
+ * @param   ctx [IN] MD上下文,使用CRYPT_EAL_MdNewCtx接口创建, ctx由调用方置空\r
+ *\r
+ * @return  void 无返回值\r
+ */\r
+void CRYPT_EAL_MdFreeCtx(CRYPT_EAL_MdCTX *ctx);\r
+\r
+/**\r
+ * @ingroup crypt_eal_md\r
+ * @brief   MD上下文初始化\r
+ *\r
+ * @param   ctx [IN/OUT] MD上下文,使用CRYPT_EAL_MdNewCtx接口创建。\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_MdInit(CRYPT_EAL_MdCTX *ctx);\r
+\r
+/**\r
+ * @ingroup crypt_eal_md\r
+ * @brief   持续输入待摘要的数据\r
+ *\r
+ * @param   ctx [IN/OUT] MD上下文,使用CRYPT_EAL_MdNewCtx接口创建。\r
+ * @param   data [IN] 待摘要数据\r
+ * @param   len [IN] 数据长度,sha384、sha512最大总长度限制为[0,2^128bits),\r
+ *                   sha1、sha224、sha256、sm3、md5最大总长度限制[0,2^64bits)。单次最大长度限制都[0,0xffffffff]。\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_MdUpdate(CRYPT_EAL_MdCTX *ctx, const uint8_t *data, uint32_t len);\r
+\r
+/**\r
+ * @ingroup crypt_eal_md\r
+ * @brief   完成摘要,输出最终摘要结果\r
+ *\r
+ * @param   ctx [IN/OUT] MD上下文,使用CRYPT_EAL_MdNewCtx接口创建。\r
+ * @param   out [OUT] 摘要结果缓存,需要用户创建管理。\r
+ * @param   len [IN/OUT] 入参标识out的buffer长度,出参标识获取的out有效长度。长度大小必须大于等于对应算法哈希长度。\r
+ *                       哈希长度大小可以通过CRYPT_EAL_MdGetDigestSize接口获取。需要用户创建管理。\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_MdFinal(CRYPT_EAL_MdCTX *ctx, uint8_t *out, uint32_t *len);\r
+\r
+/**\r
+ * @ingroup crypt_eal_md\r
+ * @brief   获取算法输出的摘要长度\r
+ *\r
+ * @param   id [IN] 算法ID\r
+ *\r
+ * @return  成功返回摘要长度\r
+ *          失败返回0,且仅有id不合法的情况下返回为0\r
+ */\r
+uint32_t CRYPT_EAL_MdGetDigestSize(CRYPT_MD_AlgId id);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+#endif // CRYPT_EAL_MD_H\r
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_pkey.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_pkey.h
new file mode 100644 (file)
index 0000000..fa5bdbb
--- /dev/null
@@ -0,0 +1,445 @@
+/**\r
+ * @defgroup    crypt_eal_pkey  crypt_eal_pkey.h\r
+ * @ingroup     crypto\r
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.\r
+ * @brief       消息非对称算法对外接口文件\r
+ */\r
+\r
+#ifndef CRYPT_EAL_PKEY_H\r
+#define CRYPT_EAL_PKEY_H\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include "crypt_algid.h"\r
+#include "crypt_types.h"\r
+#include "crypt_eal_pkey.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ *\r
+ * EAL公钥结构体\r
+ */\r
+typedef struct {\r
+    CRYPT_PKEY_AlgId id; /**< 公钥算法ID */\r
+    union {\r
+        CRYPT_RsaPub rsaPub; /**< RSA 公钥结构体 */\r
+        CRYPT_DsaPub dsaPub; /**< DSA 公钥结构体 */\r
+        CRYPT_DhPub dhPub;   /**< DH 公钥结构体 */\r
+        CRYPT_EccPub eccPub; /**< ECC 公钥结构体 */\r
+        CRYPT_Curve25519Pub curve25519Pub; /**< ed25519/x25519 公钥结构体 */\r
+        CRYPT_Curve448Pub curve448Pub; /**< ed448/x448 公钥结构体 */\r
+        CRYPT_Sm9Pub sm9Pub; /**< sm9 公钥结构体 */\r
+    } key;                           /**< 全部算法的公钥联合体 */\r
+} CRYPT_EAL_PkeyPub;\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ *\r
+ * EAL私钥结构体\r
+ */\r
+typedef struct {\r
+    CRYPT_PKEY_AlgId id; /**< 私钥算法ID */\r
+    union {\r
+        CRYPT_RsaPrv rsaPrv; /**< RSA 私钥结构体 */\r
+        CRYPT_DsaPrv dsaPrv; /**< DSA 私钥结构体 */\r
+        CRYPT_DhPrv  dhPrv;  /**< DH 私钥结构体 */\r
+        CRYPT_EccPrv eccPrv; /**< ECC 私钥结构体 */\r
+        CRYPT_Curve25519Prv curve25519Prv; /**< ed25519/x25519 私钥结构体 */\r
+        CRYPT_Curve448Prv curve448Prv; /**< ed448/x448 私钥结构体 */\r
+        CRYPT_Sm9Prv sm9Prv; /**< sm9 私钥结构体 */\r
+    } key;                           /**< 全部算法的私钥联合体 */\r
+} CRYPT_EAL_PkeyPrv;\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ *\r
+ * 用于非对称算法Para使用的结构体,包括算法id和对应算法的Para联合体\r
+ */\r
+typedef struct {\r
+    CRYPT_PKEY_AlgId id; /**< 非对称算法ID */\r
+    union {\r
+        CRYPT_RsaPara rsaPara; /**< RSA Para结构体 */\r
+        CRYPT_DsaPara dsaPara; /**< DSA Para结构体 */\r
+        CRYPT_DhPara  dhPara;  /**< DH Para结构体 */\r
+    } para;                            /**< 全部算法的Para联合体 */\r
+} CRYPT_EAL_PkeyPara;\r
+\r
+/**\r
+* @ingroup  crypt_eal_pkey\r
+*\r
+* pkey的会话结构体\r
+*/\r
+typedef struct EAL_PkeyCtx CRYPT_EAL_PkeyCtx;\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   密钥配对一致性测试\r
+ *\r
+ * @param   pkey     [IN] 秘钥对结构体\r
+ *\r
+ * @return  true 测试成功\r
+ *  false 测试失败\r
+ */\r
+typedef bool (*CRYPT_EAL_Pct)(CRYPT_EAL_PkeyCtx *pkey);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   密钥配对一致性测试回调注册接口,EAL生成非对称密钥对后会调用该回调,回调失败会导致EAL接口失败\r
+ *\r
+ * @param   func     [IN] 密钥配对一致性测试回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegPct(CRYPT_EAL_Pct func);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ *\r
+ * 非对称合规判断数据\r
+ */\r
+typedef struct {\r
+    const CRYPT_EAL_PkeyPara *para; /**< CRYPT_EAL_PkeyPara结构体 */\r
+    const CRYPT_EAL_PkeyPub *pub; /**< CRYPT_EAL_PkeyPub结构体 */\r
+    const CRYPT_EAL_PkeyPrv *prv; /**< CRYPT_EAL_PkeyPrv结构体 */\r
+    CRYPT_MD_AlgId mdId; /**< 哈希算法ID */\r
+    CRYPT_PKEY_ParaId paraId; /**< 非对称算法参数ID */\r
+    CRYPT_EVENT_TYPE oper; /**< 当前执行的操作 */\r
+    const CRYPT_RSA_PkcsV15Para *pkcsv15; /**< CRYPT_RSA_PkcsV15Para结构体 */\r
+    const CRYPT_RSA_PssPara *pss; /**< CRYPT_RSA_PssPara结构体 */\r
+    const CRYPT_RSA_OaepPara *oaep; /**< CRYPT_RSA_OaepPara结构体 */\r
+} EAL_PkeyC2Data;\r
+\r
+/**\r
+  * @ingroup crypt_eal_pkey\r
+  * @brief 非对称合规判断\r
+  *\r
+  * @param id [IN] 非对称算法id\r
+  * @param data [IN] 数据\r
+  *\r
+  * @return  true 测试成功\r
+  *          false 测试失败\r
+  */\r
+typedef bool (*CRYPT_EAL_PkeyC2)(CRYPT_PKEY_AlgId id, const EAL_PkeyC2Data *data);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   非对称合规判断回调注册接口,用于判断算法参数是否合规和模块状态是否可用\r
+ *            EAL的非对称接口在执行操作前会调用该回调,回调失败会导致EAL接口失败\r
+ *          非核准模式下可以使用任意算法\r
+ *          ISO19790模式下只允许CRYPT_PKEY_DSA/CRYPT_PKEY_X25519/CRYPT_PKEY_RSA/CRYPT_PKEY_DH/\r
+ *            CRYPT_PKEY_ECDSA/CRYPT_PKEY_ECDH算法\r
+ *          RSA密钥长度至少为2048bits\r
+ *          DSA算法p至少为2048bits,q至少为224bits\r
+ *          ECDSA算法p至少为224bits,曲线只允许P-224/P-256/P-384/P-521\r
+ *          DH算法p至少为2048bits,q至少为256bits\r
+ *          ECDH算法曲线只允许P-224/P-256/P-384/P-521\r
+ *          签名支持CRYPT_MD_SHA224/CRYPT_MD_SHA256/CRYPT_MD_SHA384/CRYPT_MD_SHA512\r
+ *          验签支持CRYPT_MD_SHA1/CRYPT_MD_SHA224/CRYPT_MD_SHA256/CRYPT_MD_SHA384/CRYPT_MD_SHA512\r
+ *\r
+ * @param   func     [IN] 非对称合规判断回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegPkeyC2(CRYPT_EAL_PkeyC2 func);\r
+\r
+\r
+/* Pkey对外接口 */\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   创建一个非对称秘钥对结构体\r
+ *\r
+ * @param   id [IN] 算法ID\r
+ *\r
+ * @return  CRYPT_EAL_PkeyCtx 指针\r
+ *          若失败返回空\r
+ */\r
+CRYPT_EAL_PkeyCtx *CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_AlgId id);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   释放非对称秘钥对结构体\r
+ *\r
+ * @param   pkey [IN] pkey上下文, pkey由调用方置空\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_PkeyFreeCtx(CRYPT_EAL_PkeyCtx *pkey);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   设置秘钥参数,其中para由调用者申请和释放内存\r
+ *\r
+ * @param   pkey [IN/OUT] 待设置秘钥对结构体\r
+ * @param   para [IN] 参数\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeySetPara(CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyPara *para);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   设置秘钥参数\r
+ *\r
+ * @param   pkey [IN/OUT] 待设置秘钥对结构体\r
+ * @param   id [IN] 参数id\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeySetParaById(CRYPT_EAL_PkeyCtx *pkey, CRYPT_PKEY_ParaId id);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   获取秘钥参数,其中para由调用者申请和释放内存\r
+ *\r
+ * @param   pkey [IN] 待设置秘钥对结构体\r
+ * @param   para [OUT] 参数\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyGetPara(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_EAL_PkeyPara *para);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   生成秘钥数据\r
+ *\r
+ * @param   pkey [IN/OUT] 接收秘钥数据的秘钥对结构体\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyGen(CRYPT_EAL_PkeyCtx *pkey);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   公钥设置,其中key由调用者申请和释放内存。\r
+ *\r
+ * @param   pkey [OUT] 接收秘钥数据的秘钥对结构体\r
+ * @param   key  [IN] 公钥数据\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeySetPub(CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyPub *key);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   私钥设置,其中key由调用者申请和释放内存。\r
+ *\r
+ * @param   pkey [OUT] 接收秘钥数据的秘钥对结构体\r
+ * @param   key  [IN] 私钥数据\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeySetPrv(CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyPrv *key);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   公钥获取,其中key由调用者申请和释放内存。\r
+ *\r
+ * @param   pkey [IN] 秘钥会话\r
+ * @param   key  [OUT] 公钥数据\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyGetPub(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_EAL_PkeyPub *key);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   私钥获取,其中key由调用者申请和释放内存。\r
+ *\r
+ * @param   pkey [IN] 秘钥会话\r
+ * @param   key  [OUT] 私钥数据\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyGetPrv(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_EAL_PkeyPrv *key);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   签名接口\r
+ *\r
+ * @param   pkey     [IN] 秘钥会话\r
+ * @param   id       [IN] 哈希算法ID\r
+ * @param   data     [IN] 明文数据\r
+ * @param   dataLen  [IN] 明文长度,最大长度限制为[0,0xffffffff]\r
+ * @param   sign     [OUT] 签名数据\r
+ * @param   signLen  [OUT/IN] 签名数据长度。可通过接口 CRYPT_EAL_PkeyGetSignLen 获取该值。\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeySign(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_MD_AlgId id, const uint8_t *data,\r
+    uint32_t dataLen, uint8_t *sign, uint32_t *signLen);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   验签接口\r
+ *\r
+ * @param   pkey      [IN] 秘钥会话\r
+ * @param   id        [IN] 哈希算法ID\r
+ * @param   data      [IN] 明文数据\r
+ * @param   dataLen   [IN] 明文长度,最大长度限制为[0,0xffffffff]\r
+ * @param   sign      [IN] 签名数据\r
+ * @param   signLen   [IN] 签名数据长度\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyVerify(const CRYPT_EAL_PkeyCtx *pkey, CRYPT_MD_AlgId id, const uint8_t *data,\r
+    uint32_t dataLen, const uint8_t *sign, uint32_t signLen);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   对哈希数据进行签名的接口\r
+ *\r
+ * @param   pkey      [IN] 秘钥会话\r
+ * @param   hash      [IN] 哈希数据\r
+ * @param   hashLen   [IN] 哈希长度。\r
+ *                         当使用RSA用于签名时,哈希长度应该与填充方法所依赖的哈希算法的摘要长度对应\r
+ * @param   sign      [OUT] 签名数据\r
+ * @param   signLen   [OUT/IN] 签名数据长度。可通过接口 CRYPT_EAL_PkeyGetSignLen 获取该值。\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeySignData(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *hash, uint32_t hashLen,\r
+    uint8_t *sign, uint32_t *signLen);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   对哈希数据进行验签的接口\r
+ *\r
+ * @param   pkey     [IN] 秘钥会话\r
+ * @param   hash     [IN] 哈希数据\r
+ * @param   hashLen   [IN] 哈希长度。\r
+ *                         当使用RSA用于签名时,哈希长度应该与填充方法所依赖的哈希算法的摘要长度对应\r
+ * @param   sign     [IN] 签名数据\r
+ * @param   signLen  [IN] 签名数据长度\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyVerifyData(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *hash, uint32_t hashLen,\r
+    const uint8_t *sign, uint32_t signLen);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   对数据进行加密\r
+ *\r
+ * @param   pkey      [IN] 秘钥会话\r
+ * @param   data      [IN] 输入明文数据\r
+ * @param   dataLen   [IN] 数据长度。\r
+ *\r
+ * @param   out      [OUT] 加密后的数据,RSA加密时用于保存加密数据的内存buff长度必须大于等于秘钥模长\r
+ * @param   outLen   [OUT/IN] 加密数据长度。\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyEncrypt(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *data, uint32_t dataLen,\r
+    uint8_t *out, uint32_t *outLen);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   对数据进行解密\r
+ *\r
+ * @param   pkey      [IN] 秘钥会话\r
+ * @param   data      [IN] 输入密文数据\r
+ * @param   dataLen   [IN] 数据长度。\r
+ *\r
+ * @param   out      [OUT] 解密后的数据\r
+ * @param   outLen   [OUT/IN] 解密数据长度。\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyDecrypt(const CRYPT_EAL_PkeyCtx *pkey, const uint8_t *data, uint32_t dataLen,\r
+    uint8_t *out, uint32_t *outLen);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   计算共享秘钥\r
+ *\r
+ * @param   pkey         [IN] 秘钥会话\r
+ * @param   pubKey       [IN] 公钥会话\r
+ * @param   share        [OUT] 共享秘钥\r
+ * @param   shareLen     [IN/OUT] 入参为share空间长度,出参为share有效长度,所需空间可通过接口CRYPT_EAL_PkeyGetKeyLen获取\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyComputeShareKey(const CRYPT_EAL_PkeyCtx *pkey, const CRYPT_EAL_PkeyCtx *pubKey,\r
+    uint8_t *share, uint32_t *shareLen);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   获取秘钥长度的字节数\r
+ *\r
+ * @param   pkey [IN] 秘钥会话\r
+ *\r
+ * @return  成功返回秘钥长度\r
+ *          失败返回0\r
+ */\r
+uint32_t CRYPT_EAL_PkeyGetKeyLen(const CRYPT_EAL_PkeyCtx *pkey);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   获取秘钥进行签名的签名长度,只支持可用于签名的算法\r
+ *\r
+ * @param   pkey [IN] 秘钥会话\r
+ *\r
+ * @return  成功返回签名长度\r
+ *          失败返回0\r
+ */\r
+uint32_t CRYPT_EAL_PkeyGetSignLen(const CRYPT_EAL_PkeyCtx *pkey);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   对秘钥进行特定的设置/获取动作,支持动作可参考CRYPT_PkeyCtrl枚举\r
+ *\r
+ * @param   pkey [IN] 秘钥会话\r
+ * @param   opt [IN] 选项信息\r
+ * @param   val [IN/OUT] 进行设置/获取的数据\r
+ * @param   len [IN] val数据的长度\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyCtrl(CRYPT_EAL_PkeyCtx *pkey, CRYPT_PkeyCtrl opt, void *val, uint32_t len);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   获取密钥算法类型\r
+ *\r
+ * @param   pkey [IN] 秘钥会话\r
+ *\r
+ * @return  密钥算法类型\r
+ */\r
+CRYPT_PKEY_AlgId CRYPT_EAL_PkeyGetId(const CRYPT_EAL_PkeyCtx *pkey);\r
+\r
+/**\r
+ * @ingroup crypt_eal_pkey\r
+ * @brief   检查密钥对一致性\r
+ *\r
+ * @param   pkey [IN] 秘钥会话\r
+ *\r
+ * @return  CRYPT_SUCCESS 成功\r
+ *          其他错误码参考 crypt_errno.h\r
+ */\r
+int32_t CRYPT_EAL_PkeyCheck(const CRYPT_EAL_PkeyCtx *pkey);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+#endif // CRYPT_EAL_PKEY_H\r
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_rand.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_eal_rand.h
new file mode 100644 (file)
index 0000000..3c6633c
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ * @defgroup    crypt_eal_rand  crypt_eal_rand.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       RAND 算法对外接口文件
+ */
+
+#ifndef CRYPT_EAL_RAND_H
+#define CRYPT_EAL_RAND_H
+
+#ifndef HITLS_CRYPTO_NO_RAND
+#include <stdbool.h>
+#include <stdint.h>
+#include "crypt_algid.h"
+#include "crypt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+  * @ingroup crypt_eal_rand
+  * @brief 随机数合规判断
+  *
+  * id:随机数算法id
+  *
+  * @return  true 测试成功
+  *          false 测试失败
+  */
+typedef bool (*CRYPT_EAL_RandC2)(CRYPT_RAND_AlgId id);
+
+/**
+ * @ingroup crypt_eal_rand
+ * @brief   随机数算法合规判断注册接口,用于判断模块状态是否可用
+ *            EAL的随机数接口在执行操作前会调用该回调,回调失败会导致CRYPT_EAL_RandInit/CRYPT_EAL_RandbytesWithAdin/
+ *            CRYPT_EAL_Randbytes/CRYPT_EAL_RandSeedWithAdin/CRYPT_EAL_RandSeed接口失败
+ *          非核准模式下可以使用任意算法
+ *          ISO19790模式下允许CRYPT_MD_SHA224/CRYPT_MD_SHA256/CRYPT_MD_SHA384/CRYPT_MD_SHA512
+ *          修改上面注释
+ *
+ * @param   func     [IN] 随机数合规判断
+ *
+ * @return  无
+ */
+void CRYPT_EAL_RegRandC2(CRYPT_EAL_RandC2 func);
+
+/**
+ * @ingroup crypt_eal_rand
+ * @brief 随机数初始化接口,此接口不支持多线程
+ * @par
+ *      将全局随机数初始为HITLS实现的RAND,种子材料中的熵源和额外随机数,必须由用户提供
+ *      使用场景如下:
+ *      1. seedMeth == NULL ====> 报错
+ *      2. seedMeth != NULL ====> 正常使用, seedCtx不做限制,但要保证seedMeth能够处理各种情况
+ *
+ * @attention 支持多线程获取/生成随机数,但是不支持多线程初始化和去初始化
+ * @param id [IN] RAND id
+ * @param seedMeth [IN] 种子方法,不可以为空
+ * @param seedCtx [IN] 种子上下文信息,可以为空,但用户提供的seedMeth需要能够处理seedCtx为空的情况
+ *                     seedCtx一般需要包含熵源entropy,额外随机数nonce等数据
+ * @param pers [IN] 个人数据,可以为空
+ * @param persLen [IN] 个人数据长度,长度限制为[0,0x7FFFFFF0]
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_RandInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx,
+    const uint8_t *pers, uint32_t persLen);
+
+/**
+ * @ingroup crypt_eal_rand
+ * @brief   CRYPT_EAL_RandDeinit 所对应的反初始化全局RAND接口, 此接口不支持多线程
+ * @return void 无返回值
+ */
+void CRYPT_EAL_RandDeinit(void);
+
+/**
+ * @ingroup crypt_eal_rand
+ * @brief 随机数生成,额外数据允许为空,由用户指定额外的混淆数据,此接口支持多线程访问
+ *
+ * @param byte  [OUT] 用于输出随机数,内存由用户提供
+ * @param len   [IN] 所需随机数长度,限制长度为(0,65536]
+ * @param addin [IN] 额外数据,可以为空
+ * @param addinLen [IN] 额外数据长度,长度限制为[0,0x7FFFFFF0]
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_RandbytesWithAdin(uint8_t *byte, uint32_t len, uint8_t *addin, uint32_t addinLen);
+
+/**
+ * @ingroup crypt_eal_rand
+ * @brief 随机数生成,等同于CRYPT_EAL_RandbytesWithAdin(bytes, len, NULL, 0),此接口支持多线程访问
+ *
+ * @param byte [OUT] 用于存储输出的随机数,内存由用户提供
+ * @param len  [IN] 所需随机数长度, 限制长度为(0,65536]
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_Randbytes(uint8_t *byte, uint32_t len);
+
+/**
+ * @ingroup crypt_eal_rand
+ * @brief 重新生成种子,额外数据允许为空,此接口支持多线程访问
+ *
+ * @param addin [IN] 额外数据,可以为空
+ * @param addinLen [IN] 额外数据长度, 长度限制为[0,0x7FFFFFF0]
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_RandSeedWithAdin(uint8_t *addin, uint32_t addinLen);
+
+/**
+ * @ingroup crypt_eal_rand
+ * @brief 重新生成种子,等同于CRYPT_EAL_RandSeedWithAdin(NULL, 0),此接口支持多线程访问
+ *
+ * @return 成功返回:CRYPT_SUCCESS
+ *         其他错误码,请查询crypt_errno.h
+ */
+int32_t CRYPT_EAL_RandSeed(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_errno.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_errno.h
new file mode 100644 (file)
index 0000000..41eb556
--- /dev/null
@@ -0,0 +1,323 @@
+/**
+ * @defgroup    crypt_errno    crypt_errno.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       crypto模块返回码
+ */
+
+/** @defgroup   crypto  crypto */
+
+#ifndef CRYPT_ERRNO_H
+#define CRYPT_ERRNO_H
+
+#include "crypt_check_macro.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup crypt_errno
+ * @brief   返回成功
+ */
+#define CRYPT_SUCCESS 0
+
+/**
+ * @ingroup crypt_errno
+ *
+ * CRYPTO模块的返回值
+ */
+enum CRYPT_ERROR {
+    CRYPT_NULL_INPUT = 0x01010001,      /**< 错误的空指针输入, bufferLen为0 */
+    CRYPT_SECUREC_FAIL,                 /**< 安全函数返回错误 */
+    CRYPT_MEM_ALLOC_FAIL,               /**< 内存资源申请失败 */
+    CRYPT_NO_REGIST_RAND,               /**< 未注册全局随机数 */
+    CRYPT_ERR_ALGID,                    /**< 错误的算法ID */
+    CRYPT_INVALID_ARG,                  /**< 非法入参 */
+
+    CRYPT_BN_BUFF_LEN_NOT_ENOUGH = 0x01020001, /**< 缓冲区长度不足 */
+    CRYPT_BN_SPACE_NOT_ENOUGH,          /**< 大数空间不足 */
+    CRYPT_BN_BITS_TOO_MAX,              /**< 超出大数最大bits限制 */
+    CRYPT_BN_RAND_GEN_FAIL,             /**< 随机数生成失败 */
+    CRYPT_BN_OPTIMIZER_STACK_FULL,      /**< 优化器栈满了失败 */
+    CRYPT_BN_NO_NEGATIVE_ZERO,          /**< 大数0只设置为正数符号 */
+    CRYPT_BN_ERR_RAND_ZERO,             /**< 生成比0小的随机数 */
+    CRYPT_BN_ERR_RAND_NEGATIVE,         /**< 生成负数随机数 */
+    CRYPT_BN_ERR_RAND_TOP_BOTTOM,       /**< 随机数生成时top或bottom无效 */
+    CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH,  /**< 随机数生成时bit过小 */
+    CRYPT_BN_OPTIMIZER_GET_FAIL,        /**< 从优化器获取空间失败 */
+    CRYPT_BN_ERR_DIVISOR_ZERO,          /**< 除数不能为0 */
+    CRYPT_BN_ERR_EXP_NO_NEGATIVE,       /**< 幂的值不能为负数 */
+    CRYPT_BN_MONT_BASE_TOO_MAX,         /**< 蒙哥马利模幂底数过大 */
+    CRYPT_BN_NOR_GEN_PRIME,             /**< 素数生成失败 */
+    CRYPT_BN_NOR_CHECK_PRIME,           /**< 素数检查失败 */
+    CRYPT_BN_ERR_GCD_NO_ZERO,           /**< 求最大公约数不能有0 */
+    CRYPT_BN_ERR_NO_INVERSE,            /**< 无法求出模逆 */
+    CRYPT_BN_ERR_SQRT_PARA,             /**< 模开根号参数错误 */
+    CRYPT_BN_ERR_LEGENDE_DATA,          /**< 计算平方根时寻找z对p的勒让德符号(z|p)等于-1特定的数失败 */
+    CRYPT_BN_ERR_NO_SQUARE_ROOT,        /**< 找不到平方根 */
+    CRYPT_BN_ERR_MASKCOPY_LEN,          /**< 带掩码进行拷贝时,数据长度不一致 */
+    CRYPT_BN_ERR_QUICK_MODDATA,         /**< 使用BN_ModNistEccMul和BN_ModNistEccSqr接口时,其模数据不支持 */
+
+    CRYPT_RSA_BUFF_LEN_NOT_ENOUGH = 0x01030001, /**< 缓冲区长度不足 */
+    CRYPT_RSA_NO_KEY_INFO,               /**< 缺乏有效秘钥信息 */
+    CRYPT_RSA_ERR_KEY_BITS,              /**< 秘钥长度错误 */
+    CRYPT_RSA_ERR_E_VALUE,               /**< 参数e数值错误 */
+    CRYPT_RSA_NOR_KEYGEN_FAIL,           /**< 秘钥生成失败,正常错误 */
+    CRYPT_RSA_NOR_VERIFY_FAIL,           /**< 验签失败,正常错误 */
+    CRYPT_RSA_ERR_ENC_BITS,              /**< 公钥加密明文长度错误 */
+    CRYPT_RSA_ERR_DEC_BITS,              /**< 私钥解密密文长度错误 */
+    CRYPT_RSA_ERR_PSS_SALT_LEN,          /**< PSS操作盐长度错误 */
+    CRYPT_RSA_ERR_PSS_SALT_DATA,         /**< PSS操作盐数据错误,验签时提取的盐与用户输入比较失败 */
+    CRYPT_RSA_ERR_PKCSV15_SALT_LEN,      /**< PKCSV15操作盐长度错误 */
+    CRYPT_RSA_ERR_PKCSV15_SALT_DATA,     /**< PKCSV15操作盐数据错误 */
+    CRYPT_RSA_ERR_INPUT_VALUE,           /**< 一些比较特殊的值,作为输入所产生的错误 */
+    CRYPT_RSA_ERR_MD_ALGID,              /**< 设置pkcs1.5填充方式时入参的哈希id错误  */
+    CRYPT_RSA_PAD_NO_SET_ERROR,          /**< 使用RSA秘钥进行签名验签时尚未设置填充信息  */
+    CRYPT_RSA_CTRL_NOT_SUPPORT_ERROR,    /**< 使用RSA进行Ctrl时,使用的Ctrl类型不支持 */
+    CRYPT_RSA_SET_SALT_NOT_PSS_ERROR,    /**< 当秘钥的填充类型非pss时,进行盐信息设置,返回失败 */
+    CRYPT_RSA_SET_EMS_PKCSV15_LEN_ERROR, /**< 进行PKCSV15填充信息设置时,输入的数据长度错误,返回失败 */
+    CRYPT_RSA_SET_EMS_PSS_LEN_ERROR,     /**< 进行PSS填充信息设置时,输入的数据长度错误,返回失败 */
+    CRYPT_RSA_SET_RSAES_OAEP_LEN_ERROR,    /**< 进行Oaep填充信息设置时,输入的数据长度错误,返回失败 */
+    CRYPT_RSA_SET_FLAG_LEN_ERROR,         /**< 设置flag时,输入数据长度错误,返回失败 */
+    CRYPT_RSA_FLAG_NOT_SUPPORT_ERROR,     /**< 不支持的flag */
+    CRYPT_RSA_ERR_SALT_LEN,              /**< 盐长度错误 */
+    CRYPT_RSA_ERR_ALGID,                 /**< 进行签名、验签以及填充参数设置时,入参的哈希ID错误或者有冲突时返回错误 */
+    CRYPT_RSA_ERR_GEN_SALT,              /**< 进行PSS签名时生成盐信息时失败返回错误 */
+    CRYPT_RSA_ERR_ENC_INPUT_NOT_ENOUGH,  /**< RSA NO PAD加密,明文长度过短*/
+
+    CRYPT_EAL_BUFF_LEN_NOT_ENOUGH = 0x01040001, /**< 缓冲区长度不足 */
+    CRYPT_EAL_ERR_ALGID,                /**< 算法ID错误 */
+    CRYPT_EAL_ALG_NOT_SUPPORT,          /**< 算法不支持、算法行为不支持 */
+    CRYPT_EAL_RAND_GEN_FAIL,            /**< 随机数生成失败 */
+    CRYPT_EAL_ERR_SALT_MEM,             /**< 盐内存错误 */
+    CRYPT_EAL_NOR_VERIFY_FAIL,          /**< 验签失败,正常错误 */
+    CRYPT_EAL_ERR_NEW_PARA_FAIL,        /**< 生成参数失败 */
+    CRYPT_EAL_ERR_RAND_WORKING,         /**< DRBG 处于工作状态 */
+    CRYPT_EAL_ERR_RAND_NO_WORKING,      /**< DRBG 处于非工作状态 */
+    CRYPT_EAL_ERR_METH_NULL_NUMBER,     /**< method变量成员为NULL */
+    CRYPT_EAL_ERR_LOCK_NULL,            /**< 锁为NULL */
+    CRYPT_EAL_ERR_GLOBAL_DRBG_NULL,     /**< 全局DRBG为NULL */
+    CRYPT_EAL_ERR_DRBG_REPEAT_INIT,     /**< DRBG重复初始化 */
+    CRYPT_EAL_ERR_DRBG_INIT_FAIL,       /**< DRBG初始化失败 */
+    CRYPT_EAL_ERR_STATE,                /**< 使用流程不正确,例如未执行init,直接执行update,具体用法参见相关算法 */
+    CRYPT_EAL_PKEY_PAD_REDUNDANCY,      /**< pkey签名验签接口中,RSA以外的算法不需要填充信息;
+                                             如果入参包含填充信息返回该错误码 */
+    CRYPT_EAL_CIPHER_DATA_ERROR,        /**< 对于解密后的数据进行去充填是数据出错,
+                                             对于X923 最后一位是原始数据的长度,其余充填数据是0,如果不满足此要求,则报错
+                                             对于pkcs 所有充填的数据是 充填后的长度 - 原始数据长度,如不满足此要求,则报错
+                                             对于ISO7816 充填的第一位数据是0x80, 其余充填0, 如不满足此要求,则报错 */
+    CRYPT_EAL_PADDING_NOT_SUPPORT,      /**< 不支持的padding */
+    CRYPT_EAL_CIPHER_CTRL_ERROR,        /**< CRYPT_EAL_CipherCtrl接口不支持的CTRL */
+    CRYPT_EAL_CIPHER_FIANL_WITH_AEAD_ERROR,     /**< 对AEAD算法进行final操作导致错误 */
+    CRYPT_EAL_PKEY_CTRL_ERROR,          /**< CRYPT_EAL_PkeyCtrl接口进行CTRL时功能不支持或者输入的长度不正确 */
+    CRYPT_EAL_MAC_CTRL_TYPE_ERROR,          /**< CRYPT_EAL_PkeyCtrl接口进行CTRL时功能不支持或者输入的长度不正确 */
+
+    CRYPT_SHA2_INPUT_OVERFLOW    = 0x01050001, /**< 输入数据的长度超出SHA2的最大处理范围 */
+    CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH,        /**< 承载输出结果的缓冲区长度不足 */
+
+    CRYPT_DRBG_ERR_STATE         = 0x01060001, /**< DRBG 状态错误 */
+    CRYPT_DRBG_FAIL_GET_ENTROPY,        /**< 获取熵失败 */
+    CRYPT_DRBG_FAIL_GET_NONCE,          /**< 获取 nonce 失败 */
+    CRYPT_DRBG_ALG_NOT_SUPPORT,         /**< 不支持给定的算法 */
+    CRYPT_DRBG_INVALID_LEN,             /**< 错误的数据长度 */
+
+    CRYPT_MPA_POOL_SIZE_EXCEED   = 0x01070001, /**< 创建pool时单元个数超限 */
+    CRYPT_MPA_ERR_ALG_MODE,                    /**< 错误算法模式 */
+    CRYPT_MPA_OUT_BUFF_LEN_NOT_ENOUGH,         /**< 承载输出结果的缓冲区长度不足 */
+
+    CRYPT_CURVE25519_NO_PUBKEY         = 0x01080001, /**< 没有公钥 */
+    CRYPT_CURVE25519_NO_PRVKEY,                      /**< 没有私钥 */
+    CRYPT_CURVE25519_KEYLEN_ERROR,                   /**< 秘钥长度错误 */
+    CRYPT_CURVE25519_SIGNLEN_ERROR,                  /**< 签名长度错误 */
+    CRYPT_CURVE25519_HASH_METH_ERROR,                /**< 哈希方法不是SHA512 */
+    CRYPT_CURVE25519_VERIFY_FAIL,                    /**< 签名不正确,验签失败 */
+    CRYPT_CURVE25519_NO_HASH_METHOD,                 /**< 未设置哈希方法 */
+    CRYPT_CURVE25519_UNSUPPORTED_CTRL_OPTION,        /**< 不支持的操作模式 */
+    CRYPT_CURVE25519_KEY_COMPUTE_FAILED,             /**< 生成共享密钥失败 */
+    CRYPT_CURVE25519_INVALID_PUBKEY,                 /**< 公钥非法 */
+
+    CRYPT_SHA1_INPUT_OVERFLOW = 0x01090001,    /**< 输入数据的长度超出SHA1的最大处理范围 */
+    CRYPT_SHA1_OUT_BUFF_LEN_NOT_ENOUGH,        /**< 承载输出结果的缓冲区长度不足 */
+
+    CRYPT_ENTROPY_RCT_FAILURE = 0x010A0001,    /**< RCT检测失败,失败时可以重启熵源 */
+    CRYPT_ENTROPY_APT_FAILURE,                 /**< APT检测失败,失败时可以重启熵源 */
+    CRYPT_ENTROPY_CONDITION_FAILURE,           /**< 调用后处理方法出错 */
+    CRYPT_ENTROPY_RANGE_ERROR,                 /**< 熵源生成范围错误 */
+
+    CRYPT_DSA_BUFF_LEN_NOT_ENOUGH = 0x010B0001, /**< 缓冲区长度不足 */
+    CRYPT_DSA_ERR_KEY_PARA,                     /**< 秘钥参数数据错误 */
+    CRYPT_DSA_ERR_KEY_INFO,                     /**< 秘钥信息错误 */
+    CRYPT_DSA_VERIFY_FAIL,                      /**< 验签失败 */
+    CRYPT_DSA_ERR_TRY_CNT,                      /**< 秘钥生成、签名在规定的尝试次数内无法生成结果 */
+    CRYPT_DSA_DECODE_FAIL,                      /**< 数据解码失败,数据不符合解码要求 */
+
+    CRYPT_HMAC_OUT_BUFF_LEN_NOT_ENOUGH = 0x010C0001, /**< 承载输出结果的缓冲区长度不足 */
+
+    CRYPT_DH_BUFF_LEN_NOT_ENOUGH = 0x010D0001, /**< 缓冲区长度不足 */
+    CRYPT_DH_PARA_ERROR,                       /**< 秘钥参数的数值不符合要求、使用ctx时不包含必要的参数信息 */
+    CRYPT_DH_KEYINFO_ERROR,                    /**< 公私钥的数值不符合要求、使用ctx时不包含必要的公私钥信息 */
+    CRYPT_DH_RAND_GENERATE_ERROR,              /**< 秘钥生成在规定的尝试次数内无法生成结果 */
+    CRYPT_DH_PAIRWISE_CHECK_FAIL,              /**< 公私钥不一致*/
+    CRYPT_DH_PRVKEY_CHECK_FAIL,                /**< 私钥进行FIPS检查失败*/
+
+    CRYPT_CHACHA20_BUFF_LEN_NOT_ENOUGH = 0x010E0001, /**< 缓冲区长度不足 */
+    CRYPT_CHACHA20_KEYLEN_ERROR,                     /**< 进行秘钥设置时 输入的秘钥长度错误 */
+    CRYPT_CHACHA20_NONCELEN_ERROR,                   /**< 进行nounce设置时,输入的nounce长度错误 */
+    CRYPT_CHACHA20_COUNTLEN_ERROR,                   /**< 进行count设置时,输入的count长度错误 */
+    CRYPT_CHACHA20_NO_KEYINFO,                       /**< 进行加解密时缺乏有效的秘钥信息 */
+    CRYPT_CHACHA20_NO_NONCEINFO,                     /**< 进行加解密时缺乏有效的nounce信息 */
+    CRYPT_CHACHA20_CTRLTYPE_ERROR,                   /**< 使用ctrl接口时输入的type不支持 */
+
+    CRYPT_AES_ERR_KEYLEN = 0x010F0001,          /**< 秘钥长度错误 */
+
+    CRYPT_MODES_TAGLEN_ERROR = 0x01100001,  /**< 在AEAD模式下,获取TAG和校验TAG时输入的TAG长度错误 */
+    CRYPT_MODES_IVLEN_ERROR,                /**< 在设置IV时,输入的IV长度错误 */
+    CRYPT_MODES_KEYUSE_TOOMANY_TIME,        /**< GCM模式下,限制了秘钥用于加解密的次数,当一个秘钥使用次数超出该限制时报错 */
+    CRYPT_MODES_CRYPTLEN_OVERFLOW,          /**< AEAD模式下,单次加密输入的明文/密文长度超出规格限制 */
+    CRYPT_MODES_CTRL_TAGLEN_ERROR,          /**< GCM和CCM模式下,使用ctrl接口设置tag长度时入参长度错误或入参数据表示的长度错误 */
+    CRYPT_MODES_AAD_REPEAT_SET_ERROR,       /**< 在AEAD模式下,重复设置AAD信息错误 */
+    CRYPT_MODE_BUFF_LEN_NOT_ENOUGH,         /**< 缓冲区长度不足 */
+    CRYPT_MODE_ERR_INPUT_LEN,               /**< 函数输入长度不是期望的长度 */
+    CRYPT_MODES_CTRL_TYPE_ERROR,            /**< 使用ctrl接口时输入的type不支持 */
+    CRYPT_MODES_CTRL_TAGLEN_AFTER_USED_ERROR, /**< GCM模式下tagLen信息影响秘钥限制的最大使用次数和加密长度。在使用秘钥进行加解密之后,不允许重新设置tagLen,返回该错误码 */
+    CRYPT_MODES_AAD_IS_SET_ERROR,           /**< ccm模式下在设置aad之后进行tagLen、msgLen的设置时返回错误 */
+    CRYPT_MODES_MSGLEN_OVERFLOW,            /**< ccm模式下加解密时输入的消息长度超出设置的msgLen */
+    CRYPT_MODES_CTRL_MSGLEN_ERROR,          /**< ccm模式下,使用ctrl接口设置msg长度时入参长度错误或入参数据表示的长度错误(该规格受ivLen影响) */
+    CRYPT_MODES_MSGLEN_LEFT_ERROR,          /**< ccm模式下,使用ctrl接口获取tag时,已加解密的消息长度尚未达到设置的数量,还有剩余,导致错误 */
+    CRYPT_MODES_ERR_KEYLEN,                 /**< 设置了错误的密钥长度 */
+    CRYPT_MODES_ERR_KEY,                    /**< 设置了错误的密钥 */
+    CRYPT_MODES_ERR_FEEDBACKSIZE,           /**< cfb模式设置了错误的密文反馈长度 */
+    CRYPT_MODES_MODE_NOT_SUPPORT,           /**< 当前模式不支持 */
+
+    CRYPT_HKDF_DKLEN_OVERFLOW = 0x01110001,         /**< 派生密钥长度超过最大限制 */
+    CRYPT_HKDF_NOT_SUPPORTED,                       /**< 不支持HKDF算法 */
+
+    CRYPT_CMAC_OUT_BUFF_LEN_NOT_ENOUGH = 0x01120001, /**< 承载输出结果的缓冲区长度不足 */
+    CRYPT_CMAC_INPUT_OVERFLOW,                       /**< 输入数据的长度超出CMAC的最大处理范围 */
+
+    CRYPT_SCRYPT_PARAM_ERROR = 0x01130001,           /**< 入参错误 */
+    CRYPT_SCRYPT_NOT_SUPPORTED,                      /**< 不支持SCRYPT算法 */
+    CRYPT_SCRYPT_DATA_TOO_MAX,                      /**< SCRYPT算法计算数据太大 */
+
+    CRYPT_CMVP_ERR_CSP_EXIST = 0x1140001, /**< 内存中存在CSP导致切换模式失败 */
+    CRYPT_CMVP_INVALID_INPUT,             /**< 要切换的模式错误 */
+    CRYPT_CMVP_ERR_STATUS,                /**< 当前状态不可用 */
+    CRYPT_CMVP_ERR_LOCK,                  /**< CMVP锁失败 */
+    CRYPT_CMVP_ERR_ALGO_SELFTEST,         /**< 算法自检失败 */
+    CRYPT_CMVP_ALREADY_IN_MODE,           /**< 已经处在该模式 */
+    CRYPT_CMVP_ERR_PAIRWISETEST,          /**< 密钥配对测试失败 */
+    CRYPT_CMVP_NOT_APPROVED,              /**< 不满足标准要求 */
+    CRYPT_CMVP_ERR_INTEGRITY,             /**< 完整性验证失败 */
+
+    CRYPT_PBKDF2_PARAM_ERROR = 0x01150001,       /**< 入参错误 */
+    CRYPT_PBKDF2_NOT_SUPPORTED,                  /**< 不支持PBKDF2算法 */
+
+    CRYPT_ECC_POINT_AT_INFINITY = 0x1160001,     /**< 点在无穷远 */
+    CRYPT_ECC_POINT_NOT_ON_CURVE,                /**< 点不在曲线上 */
+    CRYPT_ECC_POINT_ERR_CURVE_ID,                /**< 曲线ID不一致或者错误 */
+    CRYPT_ECC_POINT_WINDOW_TOO_MAX,              /**< 窗口过大 */
+    CRYPT_ECC_POINT_NOT_EQUAL,                   /**< 两个点不相等 */
+    CRYPT_ECC_POINT_BLIND_WITH_ZERO,             /**< 点加盐时随机数生成值为0 */
+    CRYPT_ECC_POINT_NOT_AFFINE,                  /**< 点不为仿射坐标 */
+    CRYPT_ECC_NOT_SUPPORT,                       /**< 不支持该功能 */
+    CRYPT_ECC_POINT_MUL_ADD_WITH_ZERO_K,          /**< 使用点乘加功能时,标量值为0返回错误 */
+    CRYPT_ECC_POINT_MUL_ERR_K_LEN,               /**< 使用点乘功能时,标量长度超过曲线规格 */
+    CRYPT_ECC_BUFF_LEN_NOT_ENOUGH,               /**< 缓冲区长度不足 */
+    CRYPT_ECC_ERR_POINT_FORMAT,                  /**< 进行点编码时输入的编码格式不对 */
+    CRYPT_ECC_ERR_POINT_CODE,                    /**< 错误的点编码信息 */
+    CRYPT_ECC_PKEY_ERR_UNSUPPORTED_CTRL_OPTION,  /**< 不支持的控制类型 */
+    CRYPT_ECC_PKEY_ERR_EMPTY_KEY,                /**< 秘钥为空 */
+    CRYPT_ECC_PKEY_ERR_INVALID_POINT_FORMAT,     /**< 无效的点格式 */
+    CRYPT_ECC_PKEY_ERR_CTRL_LEN,                 /**< 控制入参的长度不正确 */
+    CRYPT_ECC_PKEY_ERR_INVALID_PRIVATE_KEY,      /**< 无效的私钥 */
+    CRYPT_ECC_PKEY_ERR_INVALID_PUBLIC_KEY,       /**< 无效的公钥 */
+    CRYPT_ECC_PKEY_ERR_TRY_CNT,                  /**< 秘钥生成、签名在规定的尝试次数内无法生成结果 */
+
+    CRYPT_SHA3_OUT_BUFF_LEN_NOT_ENOUGH = 0x01170001, /**< 承载输出结果的缓冲区长度不足 */
+
+    CRYPT_ECDH_ERR_UNSUPPORT_CURVE_TYPE = 0x01180001,       /**< 不支持的曲线类型 */
+    CRYPT_ECDH_ERR_EMPTY_KEY,                               /**< 秘钥为空 */
+    CRYPT_ECDH_ERR_EMPTY_PARA,                              /**< 曲线参数为空 */
+    CRYPT_ECDH_ERR_UNSUPPORTED_CTRL_OPTION,                 /**< 不支持的控制选项 */
+    CRYPT_ECDH_ERR_INVALID_COFACTOR,                        /**< 无效的cofactor值 */
+    CRYPT_ECDH_ERR_INIFINITY_SHARE_KEY,                     /**< 计算出的share key为0 */
+
+    CRYPT_ECDSA_ERR_EMPTY_KEY = 0x01190001,       /**< 秘钥为空 */
+    CRYPT_ECDSA_ERR_TRY_CNT,                     /**< 秘钥生成、签名在规定的尝试次数内无法生成结果 */
+    CRYPT_ECDSA_VERIFY_FAIL,                     /**< 验签失败 */
+    CRYPT_ECDSA_ERR_UNSUPPORTED_CTRL_OPTION,     /**< 不支持的控制类型 */
+
+    CRYPT_SM3_INPUT_OVERFLOW    = 0x11A0001,  /**< 输入数据的长度超出SM3的最大处理范围 */
+    CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH,        /**< 承载输出结果的缓冲区长度不足 */
+
+    CRYPT_SM4_ERR_IV_LEN = 0x011B0001,           /**< SM4 iv长度不对,不是16 */
+    CRYPT_SM4_ERR_MSG_LEN,                       /**< SM4消息长度不对,不是16的倍数 */
+    CRYPT_SM4_ERR_KEY_LEN,                       /**< SM4秘钥长度不对,不是16 */
+
+    CRYPT_SM9_BUFF_LEN_NOT_ENOUGH = 0x011C0001,     /**< BUFF长度不足 */
+    CRYPT_SM9_ERR_KEYTYPE,                          /**< 秘钥类型错误 */
+    CRYPT_SM9_ERR_TRY_CNT,                          /**< 签名过程随机数生成次数在尝试次数内无法生成结果 */
+    CRYPT_SM9_ERR_MD_METHOD,                        /**< 没有哈希方法信息 */
+    CRYPT_SM9_VERIFY_FAIL,                          /**< 验签失败 */
+    CRYPT_SM9_ERR_CTRL_TYPE,                        /**< 调用ctrl接口设置信息时ctrlType不对 */
+    CRYPT_SM9_ERR_HASH_METHOD,                      /**< 调用ctrl接口设置的哈希方法不对 */
+    CRYPT_SM9_POINT_AT_INFINITY,                    /**< 点在无穷远 */
+    CRYPT_SM9_POINT_NOT_ON_CURVE,                   /**< 点不在曲线上 */
+    CRYPT_SM9_ERR_POINT_FORMAT,                     /**< 点格式不正确 */
+    CRYPT_SM9_ERR_POINT_BUFF,                       /**< 点数据不正确 */
+    CRYPT_SM9_ERR_POINT_NOT_AFFINE,                 /**< 点不是仿射坐标 */
+    CRYPT_SM9_ERR_POINTS2AFFINE_CNT,                /**< 多个点转到仿射坐标时点的数量错误 */
+    CRYPT_SM9_FQ2_NOT_EQUAL,                        /**< fq2点信息比较不一致 */
+
+    CRYPT_MD5_INPUT_OVERFLOW    = 0x11D0001,  /**< 输入数据的长度超出MD5的最大处理范围 */
+    CRYPT_MD5_OUT_BUFF_LEN_NOT_ENOUGH,        /**< 承载输出结果的缓冲区长度不足 */
+    
+    CRYPT_TDES_ERR_KEYLEN = 0x11E0001,          /**< tdes秘钥长度错误 */
+    CRYPT_TDES_ERR_KEY,                          /**< des秘钥错误 */
+    CRYPT_TDES_ERR_LEN,                          /**< des加解密长度错误 */
+
+    CRYPT_CURVE448_NO_PUBKEY         = 0x011F0001, /**< 没有公钥 */
+    CRYPT_CURVE448_NO_PRVKEY,                      /**< 没有私钥 */
+    CRYPT_CURVE448_KEYLEN_ERROR,                   /**< 秘钥长度错误 */
+    CRYPT_CURVE448_SIGNLEN_ERROR,                  /**< 签名长度错误 */
+    CRYPT_CURVE448_VERIFY_FAIL,                    /**< 签名不正确,验签失败 */
+    CRYPT_CURVE448_NO_HASH_METHOD,                 /**< 未设置哈希方法 */
+    CRYPT_CURVE448_UNSUPPORTED_CTRL_OPTION,        /**< 不支持的操作模式 */
+    CRYPT_CURVE448_KEY_COMPUTE_FAILED,             /**< 生成共享密钥失败 */
+    CRYPT_CURVE448_INVALID_PUBKEY,                 /**< 公钥非法 */
+    CRYPT_CURVE448_CONTEXT_TOO_LONG,               /**< context超255 */
+    CRYPT_CURVE448_NO_CONTEXT,                     /**< 未设置ctx */
+    CRYPT_CURVE448_HASH_METH_ERROR,                /**< 哈希方法不是SHAKE256 */
+
+    CRYPT_SM2_BUFF_LEN_NOT_ENOUGH = 0x01200001, /**< 缓冲区长度不足 */
+    CRYPT_SM2_NO_PUBKEY,                        /**< SM2未设置公钥 */
+    CRYPT_SM2_NO_PRVKEY,                        /**< SM2未设置私钥 */
+    CRYPT_SM2_ERR_EMPTY_KEY,                    /**< SM2秘钥为空 */
+    CRYPT_SM2_ERR_TRY_CNT,                      /**< 秘钥生成、签名在规定的尝试次数内无法生成结果 */
+    CRYPT_SM2_VERIFY_FAIL,                      /**< 验签失败 */
+    CRYPT_SM2_ERR_UNSUPPORTED_CTRL_OPTION,      /**< 不支持的控制类型 */
+    CRYPT_SM2_ERR_CTRL_LEN,                    /**< 错误的ctrl长度 */
+    CRYPT_SM2_ERR_NO_HASH_METHOD,               /**< 没有哈希方法信息 */
+    CRYPT_SM2_HASH_METH_ERROR,                /**< 哈希方法不是SM3 */
+    CRYPT_SM2_USERID_NOT_SET,                   /**< userID未设置*/
+    CRYPT_SM2_R_NOT_SET,                       /**< 对端R值未设置*/
+    CRYPT_SM2_INVALID_SERVER_TYPE,             /**< 用户既不是发起方也不是接收方 */
+    CRYPT_SM2_INVALID_CHECK_TYPE,              /**< 错误的校验类型 */
+    CRYPT_SM2_DECRYPT_FAIL,                    /**< 解密失败 */
+    CRYPT_SM2_ERR_DATA_LEN,                    /**< 数据长度错误 */
+    CRYPT_SM2_ERR_GET_S,                       /**< 获取校验和失败 */
+    CRYPT_SM2_ERR_S_NOT_SET,                   /**< 未设置校验和 */
+    CRYPT_SM2_EXCH_VERIFY_FAIL,                /**< 密钥协商失败 */
+
+    CRYPT_KDFTLS12_NOT_SUPPORTED = 0x01210001,          /**< 不支持KDFTLS12算法 */
+
+    CRYPT_SIPHASH_OUT_BUFF_LEN_NOT_ENOUGH = 0x01220001,           /**< 承载输出结果的缓冲区长度不足 */
+    CRYPT_SIPHASH_INPUT_OVERFLOW,                                 /**< 输入数据的长度超出SIPHASH的最大处理范围 */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_mpa_aead.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_mpa_aead.h
new file mode 100644 (file)
index 0000000..579ecbf
--- /dev/null
@@ -0,0 +1,203 @@
+/**
+ * @defgroup    crypt_mpa_aead    crypt_mpa_aead.h
+ * @ingroup     crypto
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ * @brief       MPA多路并行计算对外接口文件
+ */
+#ifndef CRYPT_MPA_AEAD_H
+#define CRYPT_MPA_AEAD_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup crypt_mpa_aead
+ *
+ * 加密认证计算顺序
+ */
+typedef enum {
+    MPA_MTE, /**< hmac->aes */
+    MPA_ETM, /**< aes->hmac */
+} CRYPT_MPA_AeadOrder;
+
+/**
+ * @ingroup crypt_mpa_aead
+ *
+ * aes加密解密模式
+ */
+typedef enum {
+    MPA_ENC, /**< 加密 */
+    MPA_DEC, /**< 解密 */
+} CRYPT_MPA_EncMode;
+
+/**
+ * @ingroup crypt_mpa_aead
+ *
+ * hmac 算法类型
+ */
+typedef enum {
+    MPA_HASH_NONE, /**< 不使用hash 算法 */
+    MPA_MD5,       /**< md5 算法(预留) */
+    MPA_SHA1,      /**< sha1 算法(预留) */
+    MPA_SHA224,    /**< sha224 算法(预留) */
+    MPA_SHA256,    /**< sha256 算法 */
+    MPA_SHA384,    /**< sha384 算法(预留) */
+    MPA_SHA512     /**< sha512 算法 */
+} CRYPT_MPA_HashAlg;
+
+/**
+ * @ingroup crypt_mpa_aead
+ *
+ * aes 算法类型
+ */
+typedef enum {
+    MPA_AES_NONE,   /**< 不使用 aes 算法 */
+    MPA_AES128_CBC, /**< aes128cbc 算法 */
+    MPA_AES192_CBC, /**< aes192cbc 算法 */
+    MPA_AES256_CBC  /**< aes256cbc 算法 */
+} CRYPT_MPA_AesMode;
+
+/**
+ * @ingroup crypt_mpa_aead
+ *
+ * 基于流的、对外数据结构。设置单条流的具体信息。
+ */
+typedef struct {
+    /* common */
+    uint32_t jobId;             /**< job标记 */
+    uint32_t aeadOrder;         /**< 认证加密模式:MPA_MTE、MPA_ETM */
+
+    /* aes alg resource */
+    const uint8_t *msgInput;    /**< aes进行计算的数据输入, 明文或密文 */
+    uint8_t *msgOutput;         /**< aes计算结果, 密文或明文 */
+    uint32_t aesMsgLen;         /**< aes计算的数据长度,长度为16字节的整数倍,不支持aes padding功能 */
+    uint8_t aesMode;            /**< aes模式:MPA_AES_NONE, MPA_AES128_CBC, MPA_AES192_CBC, MPA_AES256_CBC */
+    uint8_t encryptDecrypt;     /**< aes加密或解密: MPA_ENC, MPA_DEC */
+    uint8_t res1[2];            /**< 预留 */
+    const uint8_t *iv;          /**< aes初始向量输入 */
+    const uint8_t *aesKey;      /**< aes密钥输入 */
+    uint32_t keyLen;            /**< aes密钥长度,aes128:16字节;aes192:24字节;aes256:32字节 */
+    uint32_t ivLen;             /**< aes初始向量长度,16字节 */
+    uint8_t *expandKeyEnc;      /**< aes加密扩展密钥输入,aes128:11 * 16字节;aes192:13 * 16字节;aes256:15 * 16字节 */
+    uint8_t *expandKeyDec;      /**< aes解密扩展密钥输入,aes128:11 * 16字节;aes192:13 * 16字节;aes256:15 * 16字节 */
+
+    /* hmac-sha resource */
+    const uint8_t *hmacKey;     /**< hmac密钥输入 */
+    const uint8_t *msg;         /**< hmac计算,数据输入 */
+    uint32_t hmacKeyLen;        /**< hmac密钥长度 */
+    uint32_t msgLen;            /**< hmac计算的数据长度 */
+    uint8_t *hashResult;        /**< hmac计算结果mac输出 */
+    uint8_t hashAlg;            /**< 哈希算法选择:MPA_HASH_NONE, MPA_SHA256,MPA_SHA512 */
+    uint8_t res2[3];            /**< 预留 */
+    uint32_t hashResultLen;     /**< 输入参数,决定返回的mac数据长度;sha256:长度不大于32字节;sha512:长度不大于64字节 */
+    const uint8_t *ipadKeyHash; /**< hmac ipadKey数据哈希值,没有提前计算ipadkey哈希值,赋值NULL */
+    const uint8_t *opadKeyHash; /**< hmac opadKey数据哈希值,没有提前计算opadkey哈希值,赋值NULL */
+    
+    void *userData;             /**< 用户自定义使用 */
+} CRYPT_MPA_Job;
+
+typedef struct MGR_ CRYPT_MPA_Mgr;
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief 从mgr池子里面获取一个job
+ * @attention 调用者需要保证入参mgr不为空
+ * @param mgr [IN] 多流并行计算管理结构体,包含job池子
+ * @return 成功返回job;失败返回NULL
+ */
+void *CRYPT_MPA_MallocJob(CRYPT_MPA_Mgr *mgr);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief 提交job到调度层
+ * @attention 调用者需要保证入参mgr和job不为空
+ * @param mgr [IN] 多流并行计算管理结构体,包含job池子
+ * @param job [IN] 多流并行调度单元(当前支持算法:hmac,aes,aes-hmac组合)
+ * @return 有job计算完成,返回计算完成的job,用户需要自行释放job;无job计算完成则返回NULL
+ */
+void *CRYPT_MPA_CommitJob(CRYPT_MPA_Mgr *mgr, CRYPT_MPA_Job *job);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief 初始化多流并行计算模块
+ * @return 初始化成功返回0;初始化失败返回其它值
+ */
+uint32_t CRYPT_MPA_Init(void);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief init mgr resource
+ * @param mgr [IN] 多流并行计算管理结构体,包含job池子
+ * @param order [IN] 指定加解密和认证的顺序
+ * @return 初始化成功返回0;初始化失败返回其它值
+ */
+uint32_t CRYPT_MPA_InitMgr(CRYPT_MPA_Mgr *mgr, CRYPT_MPA_AeadOrder order);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief 申请mgr资源
+ * @return 成功返回mgr;失败返回NULL
+ */
+CRYPT_MPA_Mgr *CRYPT_MPA_MallocMgr(void);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief 释放mgr资源,与CRYPT_MPA_MallocMgr接口配对使用
+ * @param mgr [IN] 多流并行计算管理结构体,包含job池子
+ * @return NONE
+ */
+void CRYPT_MPA_FreeMgr(CRYPT_MPA_Mgr *mgr);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief 释放job资源. 如果CRYPT_MPA_CommitJob 和 CRYPT_MPA_FetchJob接口返回job资源,用户需要调用本接口释放job资源
+ * @attention 调用者需要保证入参mgr和job不为空
+ * @param mgr [IN] 多流并行计算管理结构体,包含job池子
+ * @param job [IN] 多流并行调度单元(当前支持算法:hmac,aes,aes-hmac组合)
+ * @return NONE
+ */
+void CRYPT_MPA_FreeJob(CRYPT_MPA_Mgr *mgr, CRYPT_MPA_Job *job);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief 强制处理job,并且返回处理完的job,每次返回一个job,直到所有的job处理完毕
+ * @attention 调用者需要保证入参mgr不为空
+ * @param mgr [IN] 多流并行计算管理结构体,包含job池子
+ * @return 用户提交的job如果还有没处理完的,返回处理完的job;所有job都处理完了,则返回NULL。用户需要负责释放返回的job
+ */
+void *CRYPT_MPA_FetchJob(CRYPT_MPA_Mgr *mgr);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief AES扩展密钥算法
+ * @param aesMode [IN] 指定AES模式
+ * @param key [IN] AES原始密钥. aes128: 16 bytes; aes192: 24 bytes; aes256: 32 bytes.
+ * @param encExpKey [OUT] 加密扩展密钥起始地址. 用户必须保证16字节对齐
+ * @param decExpKey [OUT] 解密扩展密钥起始地址. 用户必须保证16字节对齐
+ * @return 成功返回0;失败返回其它值
+ */
+uint32_t CRYPT_MPA_AesExpsionKey(CRYPT_MPA_AesMode aesMode, const uint8_t *key, uint8_t *encExpKey, uint8_t *decExpKey);
+
+/**
+ * @ingroup crypt_mpa_aead
+ * @brief hmac-sha2 算法 opadkey ipadkey hash计算,本接口不做填充. 在使用该接口前,需要调用CRYPT_MPA_Init初始化
+ * @param hashAlg [IN] 指定hash模式
+ * @param key [IN] hmac 密钥
+ * @param keyLen [IN] hmac 密钥长度
+ * @param opadKeyHash [OUT] opay key hash计算结果. SHA256要求32字节空间;SHA512算法要求64字节空间
+ * @param opadKeyHashLen [IN] 指定opadKeyHash长度
+ * @param ipadKeyHash [OUT] ipay key hash计算结果. SHA256要求32字节空间;SHA512算法要求64字节空间
+ * @param ipadKeyHashLen [IN] 指定ipadKeyHash长度
+ * @return 成功返回0;失败返回其它值
+ */
+uint32_t CRYPT_MPA_PadKeyHashNoPadding(CRYPT_MPA_HashAlg hashAlg, const uint8_t *key, uint32_t keyLen,
+    uint8_t *opadKeyHash, uint32_t opadKeyHashLen, uint8_t *ipadKeyHash, uint32_t ipadKeyHashLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/HiTLS/include/crypto/crypt_types.h b/code/sdk/open_source/HiTLS/include/crypto/crypt_types.h
new file mode 100644 (file)
index 0000000..0208bb9
--- /dev/null
@@ -0,0 +1,462 @@
+/**\r
+ * @defgroup    crypt_types crypt_types.h\r
+ * @ingroup     crypto\r
+ * @copyright   Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.\r
+ * @brief       算法ID对外接口\r
+ */\r
+\r
+#ifndef CRYPT_TYPES_H\r
+#define CRYPT_TYPES_H\r
+\r
+#include <stdint.h>\r
+#include "crypt_algid.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * 数据结构体\r
+ */\r
+typedef struct {\r
+    uint8_t *data; /**< 数据内容 */\r
+    uint32_t len;    /**< 数据长度 */\r
+} CRYPT_Data;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * 数据范围\r
+ */\r
+typedef struct {\r
+    uint32_t min; /**< 最小值 */\r
+    uint32_t max; /**< 最大值 */\r
+} CRYPT_Range;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * RSA用于签名时,Pkcsv15填充方式的结构体\r
+ */\r
+typedef struct {\r
+    CRYPT_MD_AlgId mdId; /**< pkcsv15 填充时时候的哈希算法ID*/\r
+} CRYPT_RSA_PkcsV15Para;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * RSA用于签名时,PSS填充方式的结构体\r
+ */\r
+typedef struct {\r
+    int32_t saltLen;      /**< pss 盐值长度,-1表示hashLen,-2表示MaxLen */\r
+    CRYPT_MD_AlgId mdId;  /**< pss 填充时的mdid */\r
+    CRYPT_MD_AlgId mgfId; /**< pss 填充时的mgfid */\r
+} CRYPT_RSA_PssPara;\r
+\r
+typedef struct {\r
+    CRYPT_MD_AlgId mdId;  /**< pss 填充时的mdid */\r
+    CRYPT_MD_AlgId mgfId; /**< pss 填充时的mgfid */\r
+} CRYPT_RSA_OaepPara;\r
+\r
+typedef enum {\r
+    CRYPT_RSA_BLINDING = 0x00000001,            /**< 开启RSA blinding功能进行签名\r
+                                                    此时需要设置公钥信息,或者在设置私钥的时候设置p q参数 */\r
+    CRYPT_RSA_MAXFLAG\r
+} CRYPT_RSA_Flag;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * RSA私钥参数结构体\r
+ */\r
+typedef struct {\r
+    uint8_t *d;  /**< RSA 私钥参数d */\r
+    uint8_t *n;  /**< RSA 私钥参数n */\r
+    uint8_t *p;  /**< RSA 私钥参数p */\r
+    uint8_t *q;  /**< RSA 私钥参数q */\r
+    uint32_t dLen; /**< RSA 私钥参数d的长度 */\r
+    uint32_t nLen; /**< RSA 私钥参数n的长度 */\r
+    uint32_t pLen; /**< RSA 私钥参数p的长度 */\r
+    uint32_t qLen; /**< RSA 私钥参数q的长度 */\r
+} CRYPT_RsaPrv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * DSA私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_DsaPrv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ECC私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_EccPrv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ECDSA私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_EcdsaPrv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * SM2私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_Sm2Prv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * DH私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_DhPrv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ECDH私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_EcdhPrv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ed25519/x25519私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_Curve25519Prv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ed448/x448私钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_Curve448Prv;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * RSA公钥参数结构体\r
+ */\r
+typedef struct {\r
+    uint8_t *e;  /**< RSA 公钥参数e */\r
+    uint8_t *n;  /**< RSA 公钥参数n */\r
+    uint32_t eLen; /**< RSA 公钥参数e的长度 */\r
+    uint32_t nLen; /**< RSA 公钥参数e的长度 */\r
+} CRYPT_RsaPub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * DSA公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_DsaPub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ECC公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_EccPub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ECDSA公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_EcdsaPub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * SM2公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_Sm2Pub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * DH公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_DhPub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ECDH公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_EcdhPub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ed25519/x25519公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_Curve25519Pub;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * ed448/x448公钥参数结构体\r
+ */\r
+typedef CRYPT_Data CRYPT_Curve448Pub;\r
+\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * RSA算法的Para结构体\r
+ */\r
+typedef struct {   // 该参数全不可为空, 由底层结构判断\r
+    uint8_t *e;    /**< para 参数e */\r
+    uint32_t eLen; /**< para 参数e的长度 */\r
+    uint32_t bits; /**< para 的bits */\r
+} CRYPT_RsaPara;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * DSA算法的Para结构体\r
+ */\r
+typedef struct {   // 该参数全不可为空, 由底层结构判断\r
+    uint8_t *p;  /**< 参数p */\r
+    uint8_t *q;  /**< 参数q */\r
+    uint8_t *g;  /**< 参数g */\r
+    uint32_t pLen; /**< 参数p的长度 */\r
+    uint32_t qLen; /**< 参数q的长度 */\r
+    uint32_t gLen; /**< 参数g的长度 */\r
+} CRYPT_DsaPara;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * DH算法的Para结构体\r
+ */\r
+typedef struct {\r
+    uint8_t *p;  /**< 参数p */\r
+    uint8_t *q;  /**< 参数q 该参数可为空L */\r
+    uint8_t *g;  /**< 参数g */\r
+    uint32_t pLen; /**< 参数p的长度 */\r
+    uint32_t qLen; /**< 参数q的长度 */\r
+    uint32_t gLen; /**< 参数g的长度 */\r
+} CRYPT_DhPara;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ *\r
+ * RAND注册接口的metohd结构体,包括熵源获取和清理接口,随机数获取和清理接口。\r
+ */\r
+typedef struct {\r
+    /**\r
+     * @ingroup crypt_types\r
+     * @brief 获取熵源,该接口必须注册,其输出的数据需要满足长度等要求,HiTLS不会对熵源进行检查,需要由熵源提供者实现\r
+     *\r
+     * ctx      [IN] 调用者所使用的上下文\r
+     * entropy  [OUT] 获取到的熵源数据,熵源数据长度需要满足:lenRange->min <= len <= lenRange->max\r
+     * strength [IN] 熵源强度\r
+     * lenRange [IN] 熵源长度范围\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*getEntropy)(void *ctx, CRYPT_Data *entropy, uint32_t strength, CRYPT_Range *lenRange);\r
+\r
+    /**\r
+     * @ingroup crypt_types\r
+     * @brief 熵源内存清理,非必须注册接口\r
+     * ctx     [IN] 调用者所使用的上下文\r
+     * entropy [OUT] 熵源数据\r
+     * @return  void\r
+     */\r
+    void (*cleanEntropy)(void *ctx, CRYPT_Data *entropy);\r
+\r
+    /**\r
+     * @ingroup crypt_types\r
+     * @brief 获取随机数,该接口不是必须注册的\r
+              如果注册,其输出的数据需要满足长度等要求,HiTLS不会对熵源进行检查,需要由提供则实现\r
+     *\r
+     * ctx      [IN] 调用者所使用的上下文\r
+     * nonce    [OUT] 获取到的随机数,随机数长度需要满足:lenRange->min <= len <= lenRange->max\r
+     * strength [IN] 随机数强度\r
+     * lenRange [IN] 随机数长度范围\r
+     * @return 0表示成功,其他表示失败\r
+     */\r
+    int32_t (*getNonce)(void *ctx, CRYPT_Data *nonce, uint32_t strength, CRYPT_Range *lenRange);\r
+\r
+    /**\r
+     * @ingroup crypt_types\r
+     * @brief 随机数内存清理,非必须注册接口\r
+     * ctx   [IN] 调用者所使用的上下文\r
+     * nonce [OUT] 随机数\r
+     * @return  void\r
+     */\r
+    void (*cleanNonce)(void *ctx, CRYPT_Data *nonce);\r
+} CRYPT_RandSeedMethod;\r
+\r
+/**\r
+ * @ingroup crypt_ctrl_param\r
+ *\r
+ * 设置、获取内部modes的参数\r
+ */\r
+typedef enum {\r
+    CRYPT_CTRL_SET_IV = 0,        /**< 设置iv 数据为uint8_t 类型*/\r
+    CRYPT_CTRL_GET_IV,            /**< 获取iv 数据为uint8_t* 类型 */\r
+    CRYPT_CTRL_GET_BLOCKSIZE,     /**< 获取块大小 数据为uint8_t类型 */\r
+    CRYPT_CTRL_SET_COUNT,         /**< 设置计数器信息,输入为四字节小端排布的字节流,需要的算法为chacha20 */\r
+    CRYPT_CTRL_SET_AAD,           /**< AEAD加解密模式下设置aad信息 */\r
+    CRYPT_CTRL_GET_TAG,           /**< AEAD加密或解密,在结束时获取tag */\r
+    CRYPT_CTRL_SET_TAGLEN,        /**< AEAD加解密,设置tag长度,在加解密开始之前设置,设置类型为uint32_t */\r
+    CRYPT_CTRL_SET_MSGLEN,        /**< CMM模式下需要加密消息长度作为输入用于计算,需要在SET_AAD之前设置,输入数据为一个uint64_t类型 */\r
+    CRYPT_CTRL_SET_FEEDBACKSIZE,  /**< CFB模式下设置密文反馈长度 */\r
+    CRYPT_CTRL_GET_FEEDBACKSIZE,  /**< CFB模式下获取密文反馈长度 */\r
+    CRYPT_CTRL_SET_SM4_CONSTTIME, /**< SM4选择侧信道安全实现,降低性能。仅在启用ARM汇编实现时有效 */\r
+    CRYPT_CTRL_MAX\r
+} CRYPT_CipherCtrl;\r
+\r
+/**\r
+ * @ingroup crypt_ctrl_param\r
+ *\r
+ * pkey设置、获取内部的参数\r
+ */\r
+typedef enum {\r
+    CRYPT_CTRL_SET_ED25519_HASH_METHOD, /**< ED25519设置哈希方法 */\r
+    CRYPT_CTRL_SET_RSA_EMSA_PKCSV15,    /**< RSA设置签名填充方式为EMSA_PKCSV15 */\r
+    CRYPT_CTRL_SET_RSA_EMSA_PSS,        /**< RSA设置签名填充方式为EMSA_PSS */\r
+    CRYPT_CTRL_SET_RSA_SALT,            /**< RSA算法进行PSS签名时指定盐数据,使用时将用户数据地址直接保存到秘钥\r
+                                             并在下一次签名时使用,必须保证设置后的下一次签名在盐数据的生命周期内\r
+                                             调用,该选项不推荐用户使用,仅用于KAT测试、自校验时使用 */\r
+    CRYPT_CTRL_SET_ECC_POINT_FORMAT,    /**< ECC PKEY设置点格式,点格式参照CRYPT_PKEY_PointFormat */\r
+    CRYPT_CTRL_SET_ECC_USE_COFACTOR_MODE, /**< ECC PKEY设置是否使用cofactor模式,使用后可防止中间人篡改\r
+                                               公钥,使用置为1,不使用置为0  */\r
+    CRYPT_CTRL_SET_RSA_RSAES_OAEP,            /**< RSA设置加解密填充方式为RSAES_OAEP */\r
+    CRYPT_CTRL_SET_RSA_OAEP_LABEL,            /**< RSA oaep充填设置label, 用于生成hash值 */\r
+    CRYPT_CTRL_SET_RSA_FLAG,                  /**< RSA 设置flag */\r
+    CRYPT_CTRL_CLR_RSA_FLAG,                  /**< RSA 清除flag */\r
+    CRYPT_CTRL_SET_RSA_RSAES_PKCSV15,         /**< RSA设置加解密填充方式为RSAES_PKCSV15 */\r
+\r
+    CRYPT_CTRL_SET_SM9_HASH_METHOD,     /**< SM9设置哈希方法 */\r
+\r
+    CRYPT_CTRL_SET_ED448_HASH_METHOD,   /**< ed448设置哈希方法 */\r
+    CRYPT_CTRL_SET_ED448_CONTEXT,       /**< ed448设置context */\r
+    CRYPT_CTRL_SET_ED448_PREHASH,       /**< ed448设置prehash模式 */\r
+    CRYPT_CTRL_SET_SM2_USER_ID,         /**< SM2设置用户ID */\r
+    CRYPT_CTRL_SET_SM2_HASH_METHOD,     /**< SM2设置使用SM3计算杂凑值 */\r
+    CRYPT_CTRL_SET_SM2_SERVER,          /**< SM2设置用户状态 */\r
+    CRYPT_CTRL_GENE_SM2_R,              /**< SM2获取R值 */\r
+    CRYPT_CTRL_SET_SM2_R,               /**< SM2设置R值 */\r
+    CRYPT_CTRL_SM2_GET_SEND_CHECK,      /**< SM2获取本端发送给对端的校验值 */\r
+    CRYPT_CTRL_SM2_DO_CHECK,            /**< SM2校验共享密钥 */\r
+    CRYPT_CTRL_SET_NO_PADDING,          /**< RSA设置加解密填充方式为NO_PADDING */\r
+} CRYPT_PkeyCtrl;\r
+\r
+/**\r
+ * @ingroup crypt_padding_type\r
+ *\r
+ * 填充方式枚举类型\r
+ */\r
+typedef enum {\r
+    CRYPT_PADDING_NONE = 0,         /**< Never pad (full blocks only).   */\r
+    CRYPT_PADDING_ZEROS,            /**< Zero padding (not reversible).  */\r
+    CRYPT_PADDING_ISO7816,          /**< ISO/IEC 7816-4 padding.         */\r
+    CRYPT_PADDING_X923,             /**< ANSI X.923 padding.            */\r
+    CRYPT_PADDING_PKCS5,            /**< PKCS5 padding.                  */\r
+    CRYPT_PADDING_PKCS7,            /**< PKCS7 padding.                  */\r
+    CRYPT_PADDING_MAX_COUNT\r
+} CRYPT_PaddingType;\r
+\r
+/**\r
+ * @ingroup  crypt_types\r
+ * 操作类型\r
+ */\r
+typedef enum {\r
+    CRYPT_EVENT_ENC,          /**< 加密*/\r
+    CRYPT_EVENT_DEC,          /**< 解密*/\r
+    CRYPT_EVENT_GEN,          /**< 生成密钥*/\r
+    CRYPT_EVENT_SIGN,         /**< 签名*/\r
+    CRYPT_EVENT_VERIFY,       /**< 验签*/\r
+    CRYPT_EVENT_MD,           /**< 哈希*/\r
+    CRYPT_EVENT_MAC,          /**< MAC*/\r
+    CRYPT_EVENT_KEYAGGREMENT, /**< 密钥协商*/\r
+    CRYPT_EVENT_KEYDERIVE,    /**< 派生密钥*/\r
+    CRYPT_EVENT_RANDGEN,      /**< 生成随机数*/\r
+    CRYPT_EVENT_ZERO,         /**< 敏感信息置零*/\r
+    CRYPT_EVENT_ERR,          /**< 发生错误*/\r
+    CRYPT_EVENT_SETSSP,       /**< 添加、修改密码数据和SSP*/\r
+    CRYPT_EVENT_GETSSP,       /**< 访问密码数据和SSP*/\r
+    CRYPT_EVENT_MAX\r
+} CRYPT_EVENT_TYPE;\r
+\r
+/**\r
+ * @ingroup  crypt_types\r
+ * 算法类型\r
+ */\r
+typedef enum {\r
+    CRYPT_ALGO_CIPHER = 0,\r
+    CRYPT_ALGO_PKEY,\r
+    CRYPT_ALGO_MD,\r
+    CRYPT_ALGO_MAC,\r
+    CRYPT_ALGO_KDF,\r
+    CRYPT_ALGO_RAND\r
+} CRYPT_ALGO_TYPE;\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ * @brief 事件上报\r
+ *\r
+ * @param   oper [IN] 操作类型\r
+ * @param   type [IN] 算法类型\r
+ * @param   id [IN] 算法id\r
+ * @param   err [IN] 错误码,成功为CRYPT_SUCCESS,其他错误码参考crypt_errno.h\r
+ *\r
+ * @return 无\r
+ */\r
+typedef void (*EventReport)(CRYPT_EVENT_TYPE oper, CRYPT_ALGO_TYPE type, int32_t id, int32_t err);\r
+\r
+/**\r
+ * @ingroup crypt_types\r
+ * @brief\r
+ * 事件上报回调注册接口,EAL执行完服务及报错时会上报事件。不支持多线程\r
+ *\r
+ * @param   func     [IN] 事件上报处理回调\r
+ *\r
+ * @return  无\r
+ */\r
+void CRYPT_EAL_RegEventReport(EventReport func);\r
+\r
+/* SM9算法秘钥类型枚举 */\r
+typedef enum {\r
+    SM9_NOKEY = 0x00,               // 不存在秘钥信息\r
+    SM9_SIGN_KEY = 0x01,            // 签名\r
+    SM9_VERIFY_KEY = 0x02,          // 验签\r
+    SM9_COMPUTE_SHARE_KEY = 0x04,   // 共享秘钥计算\r
+    SM9_ENC_KEY = 0x08,             // 加密\r
+    SM9_DEC_KEY = 0x10,             // 解密\r
+    SM9_KEY_GEN = 0x20,             // 秘钥生成\r
+} CRYPT_SM9_KeyType;\r
+\r
+/* SM9算法用户设置/获取秘钥使用的公钥结构体 */\r
+typedef struct {\r
+    CRYPT_Data pub;     // 主公钥 1、用于签名验签 Fp2;2、用于加解密 Fp1\r
+    CRYPT_Data idA;    // 标识ID\r
+    CRYPT_SM9_KeyType keyType;  // 秘钥类型,用于签名验签、共享秘钥计算、加解密\r
+    uint8_t hid;    // 标识符\r
+} CRYPT_Sm9Pub;\r
+\r
+/* SM9算法用户设置/获取秘钥使用的私钥结构体 */\r
+typedef struct {\r
+    CRYPT_Data pub;     // 主公钥 1、用于签名验签 Fp2;2、用于加解密、共享秘钥计算 Fp1\r
+    CRYPT_Data prv;     // 主私钥 1、进行秘钥生成时使用\r
+    CRYPT_Data d;       // 用户私钥 1、用于签名验签 Fp1 2、用于加解密、共享秘钥计算 Fp2\r
+    CRYPT_Data idA;    // 标识ID 签名可设置为NULL\r
+    CRYPT_SM9_KeyType keyType; // 秘钥类型\r
+    uint8_t hid;        // 标识符 签名时不使用该值\r
+} CRYPT_Sm9Prv;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+#endif // CRYPT_TYPES_H\r